ink_macro/lib.rs
1// Copyright (C) Use Ink (UK) Ltd.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15#![doc(
16 html_logo_url = "https://use.ink/img/crate-docs/logo.png",
17 html_favicon_url = "https://use.ink/crate-docs/favicon.png"
18)]
19
20extern crate proc_macro;
21#[macro_use]
22extern crate ink_codegen;
23
24mod blake2b;
25mod contract;
26mod contract_ref;
27mod error;
28mod event;
29mod ink_test;
30mod scale;
31mod selector;
32mod sol;
33mod storage;
34mod storage_item;
35mod trait_def;
36
37#[cfg(test)]
38mod tests;
39
40use proc_macro::TokenStream;
41
42/// Computes and expands into the BLAKE2b 256-bit hash of the string input.
43///
44/// # Note
45///
46/// - The computation takes place at compilation time of the crate.
47/// - The returned value is of type `[u8; 32]`.
48///
49/// # Example
50///
51/// ```
52/// # use ink_macro::blake2x256;
53/// # use ink_ir::blake2b_256;
54/// assert_eq!(blake2x256!("hello"), {
55/// let mut output = [0u8; 32];
56/// blake2b_256(b"hello", &mut output);
57/// output
58/// });
59/// ```
60#[proc_macro]
61pub fn blake2x256(input: TokenStream) -> TokenStream {
62 blake2b::generate_blake2x256_hash(input.into()).into()
63}
64
65/// Computes the selector of the string and expands into its `u32` representation.
66///
67/// # Note
68///
69/// - The computation takes place at compilation time of the crate.
70/// - Requires an ABI parameter as the first argument to specify the selector computation
71/// method.
72///
73/// # Arguments
74///
75/// - `Abi::Ink`: Uses ink! ABI (BLAKE-2 256-bit hash)
76/// - `Abi::Sol`: Uses Solidity ABI (Keccak-256 hash)
77///
78/// # Example
79///
80/// ```
81/// # use ink_macro::selector_id;
82/// # use ink_primitives::abi::Abi;
83/// // ink! ABI (BLAKE-2)
84/// assert_eq!(selector_id!(Abi::Ink, "hello"), 843960066,);
85///
86/// // Solidity ABI (Keccak-256)
87/// assert_eq!(selector_id!(Abi::Sol, "foo()"), 0xc2985578,);
88/// ```
89#[proc_macro]
90pub fn selector_id(input: TokenStream) -> TokenStream {
91 selector::generate_selector_id(input.into()).into()
92}
93
94/// Computes the selector of the string and expands into its byte representation.
95///
96/// # Note
97///
98/// - The computation takes place at compilation time of the crate.
99/// - Requires an ABI parameter as the first argument to specify the selector computation
100/// method.
101///
102/// # Arguments
103///
104/// - `Abi::Ink`: Uses ink! ABI (BLAKE-2 256-bit hash)
105/// - `Abi::Sol`: Uses Solidity ABI (Keccak-256 hash)
106///
107/// # Example
108///
109/// ```
110/// # use ink_macro::selector_bytes;
111/// # use ink_primitives::abi::Abi;
112/// // ink! ABI (BLAKE-2)
113/// assert_eq!(selector_bytes!(Abi::Ink, "hello"), [50, 77, 207, 2],);
114///
115/// // Solidity ABI (Keccak-256)
116/// assert_eq!(selector_bytes!(Abi::Sol, "hello"), [0x1c, 0x8a, 0xff, 0x95],);
117/// ```
118#[proc_macro]
119pub fn selector_bytes(input: TokenStream) -> TokenStream {
120 selector::generate_selector_bytes(input.into()).into()
121}
122
123/// Entry point for writing ink! smart contracts.
124///
125/// If you are a beginner trying to learn ink! we recommend you to check out
126/// our extensive [ink! workshop](https://docs.substrate.io/tutorials/v3/ink-workshop/pt1).
127///
128/// # Description
129///
130/// The macro does analysis on the provided smart contract code and generates
131/// proper code.
132///
133/// ink! smart contracts can compile in several different modes.
134/// There are two main compilation models using either
135/// - on-chain mode: `no_std` and WebAssembly as target
136/// - off-chain mode: `std`
137///
138/// We generally use the on-chain mode for actual smart contract instantiation
139/// whereas we use the off-chain mode for smart contract testing using the
140/// off-chain environment provided by the `ink_env` crate.
141///
142/// # Usage
143///
144/// ## Header Arguments
145///
146/// The `#[ink::contract]` macro can be provided with some additional comma-separated
147/// header arguments:
148///
149/// - `keep_attr: String`
150///
151/// Tells the ink! code generator which attributes should be passed to call builders.
152/// Call builders are used for making cross-contract calls and are automatically
153/// generated for contracts.
154///
155/// **Usage Example:**
156/// ```
157/// #[ink::contract(keep_attr = "foo, bar")]
158/// mod my_contract {
159/// # #[ink(storage)]
160/// # pub struct MyStorage;
161/// # impl MyStorage {
162/// # #[ink(constructor)]
163/// // #[bar]
164/// # pub fn construct() -> Self { MyStorage {} }
165/// # #[ink(message)]
166/// // #[foo]
167/// # pub fn message(&self) {}
168/// # }
169/// // ...
170/// }
171/// ```
172///
173/// **Allowed attributes by default:** `cfg`, `cfg_attr`, `allow`, `warn`, `deny`,
174/// `forbid`, `deprecated`, `must_use`, `doc`, `rustfmt`.
175///
176/// - `env: impl Environment`
177///
178/// Tells the ink! code generator which environment to use for the ink! smart
179/// contract. The environment must implement the `Environment` (defined in `ink_env`)
180/// trait and provides all the necessary fundamental type definitions for `Balance`,
181/// `AccountId` etc.
182///
183/// When using a custom `Environment` implementation for a smart contract all types
184/// that it exposes to the ink! smart contract and the mirrored types used in the
185/// runtime must be aligned with respect to SCALE encoding and semantics.
186///
187/// **Usage Example:**
188///
189/// Given a custom `Environment` implementation:
190/// ```
191/// #[derive(Clone)]
192/// pub struct MyEnvironment;
193///
194/// impl ink_env::Environment for MyEnvironment {
195/// const NATIVE_TO_ETH_RATIO: u32 = 100_000_000;
196/// const TRUST_BACKED_ASSETS_PRECOMPILE_INDEX: u16 = 0x0120;
197/// const POOL_ASSETS_PRECOMPILE_INDEX: u16 = 0x0320;
198/// type AccountId = [u8; 16];
199/// type Balance = u128;
200/// type Hash = [u8; 32];
201/// type Timestamp = u64;
202/// type BlockNumber = u32;
203/// type EventRecord = ();
204/// }
205/// ```
206/// A user might implement their ink! smart contract using the above custom
207/// `Environment` implementation as demonstrated below:
208/// ```
209/// #[ink::contract(env = MyEnvironment)]
210/// mod my_contract {
211/// # #[derive(Clone)]
212/// # pub struct MyEnvironment;
213/// #
214/// # impl ink_env::Environment for MyEnvironment {
215/// # const NATIVE_TO_ETH_RATIO: u32 = 100_000_000;
216/// # const TRUST_BACKED_ASSETS_PRECOMPILE_INDEX: u16 = 0x0120;
217/// # const POOL_ASSETS_PRECOMPILE_INDEX: u16 = 0x0320;
218/// # type AccountId = [u8; 16];
219/// # type Balance = u128;
220/// # type Hash = [u8; 32];
221/// # type Timestamp = u64;
222/// # type BlockNumber = u32;
223/// # type EventRecord = ();
224/// # }
225/// #
226/// # #[ink(storage)]
227/// # pub struct MyStorage;
228/// # impl MyStorage {
229/// # #[ink(constructor)]
230/// # pub fn construct() -> Self { MyStorage {} }
231/// # #[ink(message)]
232/// # pub fn message(&self) {}
233/// # }
234/// // ...
235/// }
236/// ```
237///
238/// **Default value:** `DefaultEnvironment` defined in `ink_env` crate.
239///
240/// ## Analysis
241///
242/// The `#[ink::contract]` macro fully analyses its input smart contract
243/// against invalid arguments and structure.
244///
245/// Some example rules include but are not limited to:
246///
247/// - There must be exactly one `#[ink(storage)]` struct.
248///
249/// This struct defines the layout of the storage that the ink! smart contract
250/// operates on. The user is able to use a variety of built-in facilities, combine
251/// them in various ways or even provide their own implementations of storage data
252/// structures.
253///
254/// For more information visit the `ink::storage` crate documentation.
255///
256/// **Example:**
257///
258/// ```
259/// #[ink::contract]
260/// mod flipper {
261/// #[ink(storage)]
262/// pub struct Flipper {
263/// value: bool,
264/// }
265/// # impl Flipper {
266/// # #[ink(constructor)]
267/// # pub fn construct() -> Self { Flipper { value: false } }
268/// # #[ink(message)]
269/// # pub fn message(&self) {}
270/// # }
271/// }
272/// ```
273///
274/// - There must be at least one `#[ink(constructor)]` defined method.
275///
276/// Methods flagged with `#[ink(constructor)]` are special in that they are
277/// dispatchable upon contract instantiation. A contract may define multiple such
278/// constructors which allow users of the contract to instantiate a contract in
279/// multiple different ways.
280///
281/// **Example:**
282///
283/// Given the `Flipper` contract definition above we add an `#[ink(constructor)]`
284/// as follows:
285///
286/// ```
287/// # #[ink::contract]
288/// # mod flipper {
289/// # #[ink(storage)]
290/// # pub struct Flipper {
291/// # value: bool,
292/// # }
293/// impl Flipper {
294/// #[ink(constructor)]
295/// pub fn new(initial_value: bool) -> Self {
296/// Flipper { value: false }
297/// }
298/// # #[ink(message)]
299/// # pub fn message(&self) {}
300/// }
301/// # }
302/// ```
303///
304/// - There must be at least one `#[ink(message)]` defined method.
305///
306/// Methods flagged with `#[ink(message)]` are special in that they are dispatchable
307/// upon contract invocation. The set of ink! messages defined for an ink! smart
308/// contract define its API surface with which users are allowed to interact.
309///
310/// An ink! smart contract can have multiple such ink! messages defined.
311///
312/// **Note:**
313///
314/// - An ink! message with a `&self` receiver may only read state whereas an ink!
315/// message with a `&mut self` receiver may mutate the contract's storage.
316///
317/// **Example:**
318///
319/// Given the `Flipper` contract definition above we add some `#[ink(message)]`
320/// definitions as follows:
321///
322/// ```
323/// # #[ink::contract]
324/// # mod flipper {
325/// # #[ink(storage)]
326/// # pub struct Flipper {
327/// # value: bool,
328/// # }
329/// impl Flipper {
330/// # #[ink(constructor)]
331/// # pub fn new(initial_value: bool) -> Self {
332/// # Flipper { value: false }
333/// # }
334/// /// Flips the current value.
335/// #[ink(message)]
336/// pub fn flip(&mut self) {
337/// self.value = !self.value;
338/// }
339///
340/// /// Returns the current value.
341/// #[ink(message)]
342/// pub fn get(&self) -> bool {
343/// self.value
344/// }
345/// }
346/// # }
347/// ```
348///
349/// **Payable Messages:**
350///
351/// An ink! message by default will reject calls that additional fund the smart
352/// contract. Authors of ink! smart contracts can make an ink! message payable by
353/// adding the `payable` flag to it. An example below:
354///
355/// Note that ink! constructors are always implicitly payable and thus cannot be
356/// flagged as such.
357///
358/// ```
359/// # #[ink::contract]
360/// # mod flipper {
361/// # #[ink(storage)]
362/// # pub struct Flipper {
363/// # value: bool,
364/// # }
365/// impl Flipper {
366/// # #[ink(constructor)]
367/// # pub fn new(initial_value: bool) -> Self {
368/// # Flipper { value: false }
369/// # }
370/// /// Flips the current value.
371/// #[ink(message)]
372/// #[ink(payable)] // You can either specify payable out-of-line.
373/// pub fn flip(&mut self) {
374/// self.value = !self.value;
375/// }
376///
377/// /// Flips the current value.
378/// #[ink(message, payable)] // ...or specify payable inline.
379/// pub fn flip_2(&mut self) {
380/// self.value = !self.value;
381/// }
382///
383/// /// Returns the current value.
384/// #[ink(message)]
385/// pub fn get(&self) -> bool {
386/// self.value
387/// }
388/// }
389/// # }
390/// ```
391///
392/// **Controlling the messages selector:**
393///
394/// Every ink! message and ink! constructor has a unique selector with which the
395/// message or constructor can be uniquely identified within the ink! smart contract.
396/// These selectors are mainly used to drive the contract's dispatch upon calling it.
397///
398/// An ink! smart contract author can control the selector of an ink! message or ink!
399/// constructor using the `selector` flag. An example is shown below:
400///
401/// ```
402/// # #[ink::contract]
403/// # mod flipper {
404/// # #[ink(storage)]
405/// # pub struct Flipper {
406/// # value: bool,
407/// # }
408/// impl Flipper {
409/// #[ink(constructor)]
410/// #[ink(selector = 0xDEADBEEF)] // Works on constructors as well.
411/// pub fn new(initial_value: bool) -> Self {
412/// Flipper { value: false }
413/// }
414///
415/// /// Flips the current value.
416/// #[ink(message)]
417/// #[ink(selector = 0xCAFEBABE)] // You can either specify selector out-of-line.
418/// pub fn flip(&mut self) {
419/// self.value = !self.value;
420/// }
421///
422/// /// Returns the current value.
423/// #[ink(message, selector = 0xFEEDBEEF)] // ...or specify selector inline.
424/// pub fn get(&self) -> bool {
425/// self.value
426/// }
427/// }
428/// # }
429/// ```
430///
431/// ## Interacting with the Contract Executor
432///
433/// The `ink_env` crate provides facilities to interact with the contract executor that
434/// connects ink! smart contracts with the outer world.
435///
436/// For example it is possible to query the current call's caller via:
437/// ```
438/// # ink_env::test::run_test::<ink_env::DefaultEnvironment, _>(|_| {
439/// let caller = ink_env::caller();
440/// # let _caller = caller;
441/// # Ok(())
442/// # }).unwrap();
443/// ```
444///
445/// However, ink! provides a much simpler way to interact with the contract executor
446/// via its environment accessor. An example below:
447///
448/// ```
449/// #[ink::contract]
450/// mod greeter {
451/// #[ink(storage)]
452/// pub struct Greeter;
453///
454/// impl Greeter {
455/// #[ink(constructor)]
456/// pub fn new() -> Self {
457/// let caller = Self::env().caller();
458/// Greeter {}
459/// }
460///
461/// #[ink(message, payable)]
462/// pub fn fund(&mut self) {
463/// let caller = self.env().caller();
464/// let value = self.env().transferred_value();
465/// }
466/// }
467/// }
468/// ```
469///
470/// ## Events
471///
472/// An ink! smart contract may define events that it can emit during contract execution.
473/// Emitting events can be used by third party tools to query information about a
474/// contract's execution and state.
475///
476/// The following example ink! contract shows how an event `Transferred` is defined and
477/// emitted in the `#[ink(constructor)]`.
478///
479/// ```
480/// #[ink::contract]
481/// mod erc20 {
482/// use ink::U256;
483///
484/// /// Defines an event that is emitted every time value is transferred.
485/// #[ink(event)]
486/// pub struct Transferred {
487/// from: Option<Address>,
488/// to: Option<Address>,
489/// value: U256,
490/// }
491///
492/// #[ink(storage)]
493/// pub struct Erc20 {
494/// total_supply: U256,
495/// // more fields...
496/// }
497///
498/// impl Erc20 {
499/// #[ink(constructor)]
500/// pub fn new(initial_supply: U256) -> Self {
501/// let caller = Self::env().caller();
502/// Self::env().emit_event(Transferred {
503/// from: None,
504/// to: Some(caller),
505/// value: initial_supply,
506/// });
507/// Self {
508/// total_supply: initial_supply,
509/// }
510/// }
511///
512/// #[ink(message)]
513/// pub fn total_supply(&self) -> U256 {
514/// self.total_supply
515/// }
516/// }
517/// }
518/// ```
519///
520/// ## Example: Flipper
521///
522/// The below code shows the complete implementation of the so-called Flipper
523/// ink! smart contract.
524/// For us it acts as the "Hello, World!" of the ink! smart contracts because
525/// it is minimal while still providing some more or less useful functionality.
526///
527/// It controls a single `bool` value that can be either `false` or `true`
528/// and allows the user to flip this value using the `Flipper::flip` message
529/// or retrieve the current value using `Flipper::get`.
530///
531/// ```
532/// #[ink::contract]
533/// pub mod flipper {
534/// #[ink(storage)]
535/// pub struct Flipper {
536/// value: bool,
537/// }
538///
539/// impl Flipper {
540/// /// Creates a new flipper smart contract initialized with the given value.
541/// #[ink(constructor)]
542/// pub fn new(init_value: bool) -> Self {
543/// Self { value: init_value }
544/// }
545///
546/// /// Flips the current value of the Flipper's boolean.
547/// #[ink(message)]
548/// pub fn flip(&mut self) {
549/// self.value = !self.value;
550/// }
551///
552/// /// Returns the current value of the Flipper's boolean.
553/// #[ink(message)]
554/// pub fn get(&self) -> bool {
555/// self.value
556/// }
557/// }
558/// }
559/// ```
560#[proc_macro_attribute]
561pub fn contract(attr: TokenStream, item: TokenStream) -> TokenStream {
562 contract::generate(attr.into(), item.into()).into()
563}
564
565/// Marks trait definitions to ink! as special ink! trait definitions.
566///
567/// There are some restrictions that apply to ink! trait definitions that
568/// this macro checks. Also ink! trait definitions are required to have specialized
569/// structure so that the main [`#[ink::contract]`](`macro@crate::contract`) macro can
570/// properly generate code for its implementations.
571///
572/// # Example
573///
574/// # Trait definition:
575///
576/// ```
577/// #[ink::trait_definition]
578/// pub trait Erc20 {
579/// /// Returns the total supply of the ERC-20 smart contract.
580/// #[ink(message)]
581/// fn total_supply(&self) -> ink::U256;
582///
583/// /// Transfers balance from the caller to the given address.
584/// #[ink(message)]
585/// fn transfer(&mut self, amount: ink::U256, to: ink::Address) -> bool;
586///
587/// // etc.
588/// }
589/// ```
590///
591/// # Trait implementation
592///
593/// Given the above trait definition you can implement it as shown below:
594///
595/// ```
596/// #[ink::contract]
597/// mod base_erc20 {
598/// use ink::U256;
599/// # // We somehow cannot put the trait in the doc-test crate root due to bugs.
600/// # #[ink::trait_definition]
601/// # pub trait Erc20 {
602/// # /// Returns the total supply of the ERC-20 smart contract.
603/// # #[ink(message)]
604/// # fn total_supply(&self) -> U256;
605/// #
606/// # /// Transfers balance from the caller to the given address.
607/// # #[ink(message)]
608/// # fn transfer(&mut self, amount: U256, to: Address) -> bool;
609/// # }
610/// #
611/// #[ink(storage)]
612/// pub struct BaseErc20 {
613/// total_supply: U256,
614/// }
615///
616/// impl BaseErc20 {
617/// #[ink(constructor)]
618/// pub fn new(initial_supply: U256) -> Self {
619/// Self { total_supply: initial_supply }
620/// }
621/// }
622///
623/// impl Erc20 for BaseErc20 {
624/// /// Returns the total supply of the ERC-20 smart contract.
625/// #[ink(message)]
626/// fn total_supply(&self) -> U256 {
627/// self.total_supply
628/// }
629///
630/// #[ink(message)]
631/// fn transfer(&mut self, amount: U256, to: Address) -> bool {
632/// unimplemented!()
633/// }
634/// }
635/// }
636/// ```
637///
638/// ## Header Arguments
639///
640/// The `#[ink::trait_definition]` macro can be provided with some additional
641/// comma-separated header arguments:
642///
643/// - `namespace: String`
644///
645/// The namespace configuration parameter is used to influence the generated
646/// selectors of the ink! trait messages. This is useful to disambiguate
647/// ink! trait definitions with equal names.
648///
649/// **Usage Example:**
650/// ```
651/// #[ink::trait_definition(namespace = "foo")]
652/// pub trait TraitDefinition {
653/// #[ink(message)]
654/// fn message1(&self);
655///
656/// #[ink(message, selector = 42)]
657/// fn message2(&self);
658/// }
659/// ```
660///
661/// **Default value:** Empty.
662///
663/// - `keep_attr: String`
664///
665/// Tells the ink! code generator which attributes should be passed to call builders.
666/// Call builders are used for making cross-contract calls and are automatically
667/// generated for contracts.
668///
669/// **Usage Example:**
670/// ```
671/// #[ink::trait_definition(keep_attr = "foo, bar")]
672/// pub trait Storage {
673/// #[ink(message)]
674/// // #[foo]
675/// fn message1(&self);
676///
677/// #[ink(message)]
678/// // #[bar]
679/// fn message2(&self);
680/// }
681/// ```
682///
683/// **Allowed attributes by default:** `cfg`, `cfg_attr`, `allow`, `warn`, `deny`,
684/// `forbid`, `deprecated`, `must_use`, `doc`, `rustfmt`.
685#[proc_macro_attribute]
686pub fn trait_definition(attr: TokenStream, item: TokenStream) -> TokenStream {
687 trait_def::analyze(attr.into(), item.into()).into()
688}
689
690/// Defines the interface of a "callee" contract and generates a wrapper type which can be
691/// used for interacting with the contract.
692///
693/// The interface is defined using a trait, and the macro generates a native Rust type
694/// (a contract reference) that implements this trait, so it can be used in any Rust
695/// context that expects types.
696///
697/// # Example
698///
699/// # Definition
700///
701/// ```
702/// #[ink::contract_ref(abi = "sol")]
703/// pub trait Erc20 {
704/// /// Returns the total supply of the ERC-20 smart contract.
705/// #[ink(message)]
706/// fn total_supply(&self) -> ink::U256;
707///
708/// /// Transfers balance from the caller to the given address.
709/// #[ink(message)]
710/// fn transfer(&mut self, amount: ink::U256, to: ink::Address) -> bool;
711///
712/// // etc.
713/// }
714/// ```
715///
716/// # Usage
717///
718/// Given the above interface, you can use the generated contract reference in a
719/// "caller" contract as shown below:
720///
721/// ```
722/// #[ink::contract]
723/// mod erc20_caller {
724/// use ink::U256;
725/// # // We somehow cannot put the trait in the doc-test crate root due to bugs.
726/// # #[ink::contract_ref(abi = "sol")]
727/// # pub trait Erc20 {
728/// # /// Returns the total supply of the ERC-20 smart contract.
729/// # #[ink(message)]
730/// # fn total_supply(&self) -> U256;
731/// #
732/// # /// Transfers balance from the caller to the given address.
733/// # #[ink(message)]
734/// # fn transfer(&mut self, amount: U256, to: Address) -> bool;
735/// # }
736/// #
737/// #[ink(storage)]
738/// pub struct Erc20Caller {
739/// callee: ink::Address,
740/// }
741///
742/// impl Erc20Caller {
743/// #[ink(constructor)]
744/// pub fn new(addr: ink::Address) -> Self {
745/// Self { callee: addr }
746/// }
747///
748/// #[ink(message)]
749/// pub fn call_erc20(&self) {
750/// // Calls the ERC20 contract using the contract ref generated above.
751/// let total = Erc20Ref::from(self.callee).total_supply();
752///
753/// // Do some fun stuff!
754/// }
755/// }
756/// }
757/// ```
758///
759/// ## Header Arguments
760///
761/// The `#[ink::contract_ref]` macro can be provided with some additional
762/// comma-separated header arguments:
763///
764/// - `abi: String`
765///
766/// Specifies the ABI (Application Binary Interface) of the "callee" contract.
767///
768/// **Usage Example:**
769/// ```
770/// #[ink::contract_ref(abi = "sol")]
771/// pub trait Callee {
772/// #[ink(message)]
773/// fn message1(&self);
774///
775/// #[ink(message, selector = 42)]
776/// fn message2(&self);
777/// }
778/// ```
779///
780/// **Default value:** Empty.
781///
782/// **Allowed values:** `"ink"`, `"sol"`
783///
784/// **NOTE**: When no value is provided, the generated contract reference will use the
785/// ABI of the root contract (i.e "ink" in "ink" and "all" ABI mode and "sol" in "sol"
786/// ABI mode).
787///
788/// - `env: impl Environment`
789///
790/// Specifies the environment to use for the generated contract reference.
791///
792/// This should be the same environment used by the root contract (if any).
793///
794/// The environment must implement the `Environment` (defined in `ink_env`)
795/// trait and provides all the necessary fundamental type definitions for `Balance`,
796/// `AccountId` etc.
797///
798/// **Usage Example:**
799///
800/// Given a custom `Environment` implementation:
801/// ```
802/// #[derive(Clone)]
803/// pub struct MyEnvironment;
804///
805/// impl ink_env::Environment for MyEnvironment {
806/// const NATIVE_TO_ETH_RATIO: u32 = 100_000_000;
807/// const TRUST_BACKED_ASSETS_PRECOMPILE_INDEX: u16 = 0x0120;
808/// const POOL_ASSETS_PRECOMPILE_INDEX: u16 = 0x0320;
809/// type AccountId = [u8; 16];
810/// type Balance = u128;
811/// type Hash = [u8; 32];
812/// type Timestamp = u64;
813/// type BlockNumber = u32;
814/// type EventRecord = ();
815/// }
816/// ```
817/// A user might define an interface (and generate a contract reference) that uses the
818/// above custom `Environment` implementation as demonstrated below:
819/// ```
820/// #[ink::contract_ref(env = MyEnvironment)]
821/// pub trait Callee {
822/// #[ink(message)]
823/// fn message(&self);
824///
825/// // ...
826/// }
827///
828/// # #[derive(Clone)]
829/// # pub struct MyEnvironment;
830/// #
831/// # impl ink_env::Environment for MyEnvironment {
832/// # const NATIVE_TO_ETH_RATIO: u32 = 100_000_000;
833/// # const TRUST_BACKED_ASSETS_PRECOMPILE_INDEX: u16 = 0x0120;
834/// # const POOL_ASSETS_PRECOMPILE_INDEX: u16 = 0x0320;
835/// # type AccountId = [u8; 16];
836/// # type Balance = u128;
837/// # type Hash = [u8; 32];
838/// # type Timestamp = u64;
839/// # type BlockNumber = u32;
840/// # type EventRecord = ();
841/// # }
842/// ```
843///
844/// **Default value:** `DefaultEnvironment` defined in `ink_env` crate.
845#[proc_macro_attribute]
846pub fn contract_ref(attr: TokenStream, item: TokenStream) -> TokenStream {
847 contract_ref::analyze(attr.into(), item.into()).into()
848}
849
850/// Implements the necessary traits for a `struct` to be emitted as an event from a
851/// contract.
852///
853/// By default, a signature topic will be generated for the event. This allows consumers
854/// to filter and identify events of this type. Marking an event with `anonymous`
855/// means no signature topic will be generated or emitted.
856/// Custom signature topic can be specified with `signature_topic = <32 byte hex string>`.
857///
858/// `signature_topic` and `anonymous` are conflicting arguments.
859///
860/// # Examples
861///
862/// ```
863/// #[ink::event]
864/// pub struct MyEvent {
865/// pub field: u32,
866/// #[ink(topic)]
867/// pub topic: [u8; 32],
868/// }
869///
870/// // Setting `anonymous` means no signature topic will be emitted for the event.
871/// #[ink::event(anonymous)]
872/// pub struct MyAnonEvent {
873/// pub field: u32,
874/// #[ink(topic)]
875/// pub topic: [u8; 32],
876/// }
877/// // Setting `signature_topic = <hex_string>` specifies custom signature topic.
878/// #[ink::event(
879/// signature_topic = "1111111111111111111111111111111111111111111111111111111111111111"
880/// )]
881/// pub struct MyCustomSignatureEvent {
882/// pub field: u32,
883/// #[ink(topic)]
884/// pub topic: [u8; 32],
885/// }
886/// ```
887#[proc_macro_attribute]
888pub fn event(attr: TokenStream, item: TokenStream) -> TokenStream {
889 event::generate(attr.into(), item.into()).into()
890}
891
892/// Prepares the type to be fully compatible and usable with the storage.
893/// It implements all necessary traits and calculates the storage key for types.
894/// `Packed` types don't have a storage key, but non-packed types (like `Mapping`, `Lazy`
895/// etc.) require calculating the storage key during compilation.
896///
897/// Consider annotating structs and enums that are intended to be a part of
898/// the storage with this macro. If the type is packed then the usage of the
899/// macro is optional.
900///
901/// If the type is non-packed it is best to rely on automatic storage key
902/// calculation via `ink::storage_item`.
903///
904/// The usage of `KEY: StorageKey` generic allows to propagate the parent's storage key to
905/// the type and offset the storage key of the type. It is helpful for non-packed types
906/// that can be used several times in the contract. Each field should have a unique
907/// storage key, so propagation of the parent's storage key allows one to achieve it.
908///
909/// The macro should be called before `derive` macros because it can change the type.
910///
911/// All required traits can be:
912/// - Derived manually via `#[derive(...)]`.
913/// - Derived automatically via deriving of `scale::Decode` and `scale::Encode`.
914/// - Derived via this macro.
915///
916/// # Example
917///
918/// ## Trait implementation
919///
920/// ```
921/// use ink_prelude::vec::Vec;
922/// use ink::storage::{
923/// Lazy,
924/// Mapping,
925/// };
926/// use ink::storage::traits::{
927/// StorageKey,
928/// StorableHint,
929/// };
930/// use ink::storage::traits::Storable;
931///
932/// // Example of how to define a packed type.
933/// #[ink::storage_item(packed)]
934/// #[derive(Default, Debug)]
935/// struct Packed {
936/// s1: u128,
937/// s2: Vec<u128>,
938/// // Fails because `StorableHint` is only implemented for `Vec` where `T: Packed`.
939/// // s3: Vec<NonPacked>,
940/// }
941///
942/// // Example of how to define the packed type with generics.
943/// #[ink::storage_item(packed)]
944/// #[derive(Default, Debug)]
945/// struct PackedGeneric<T: ink::storage::traits::Packed> {
946/// s1: (u128, bool),
947/// s2: Vec<T>,
948/// s3: String,
949/// }
950///
951/// // Example of how to define the non-packed type.
952/// // Note: `packed` argument defaults to `false`, so it can be omitted for non-packed types,
953/// // so the definition below is equivalent to `#[ink::storage_item(packed = false)]`.
954/// #[ink::storage_item]
955/// #[derive(Default, Debug)]
956/// struct NonPacked {
957/// s1: Mapping<u32, u128>,
958/// s2: Lazy<u128>,
959/// }
960///
961/// // Example of how to define the non-packed generic type.
962/// #[ink::storage_item]
963/// #[derive(Default, Debug)]
964/// struct NonPackedGeneric<T>
965/// where
966/// T: Default + core::fmt::Debug,
967/// T: ink::storage::traits::Packed,
968/// {
969/// s1: u32,
970/// s2: T,
971/// s3: Mapping<u128, T>,
972/// }
973///
974/// // Example of how to define the non-packed generic type with manually derived storage traits.
975/// #[ink::storage_item(derive = false)]
976/// #[derive(Storable, StorableHint, StorageKey)]
977/// #[cfg_attr(
978/// feature = "std",
979/// derive(scale_info::TypeInfo, ink::storage::traits::StorageLayout)
980/// )]
981/// #[derive(Default, Debug)]
982/// struct NonPackedGenericManual<T>
983/// where
984/// T: Default + core::fmt::Debug,
985/// T: ink::storage::traits::Packed,
986/// {
987/// s1: u32,
988/// s2: T,
989/// s3: Mapping<u128, T>,
990/// }
991///
992/// // Example of how to define a complex packed type.
993/// #[ink::storage_item(packed)]
994/// #[derive(Default, Debug)]
995/// struct PackedComplex {
996/// s1: u128,
997/// s2: Vec<u128>,
998/// s3: Vec<Packed>,
999/// }
1000///
1001/// // Example of how to define a complex non-packed type.
1002/// #[ink::storage_item]
1003/// #[derive(Default, Debug)]
1004/// struct NonPackedComplex<KEY: StorageKey> {
1005/// s1: (String, u128, Packed),
1006/// s2: Mapping<u128, u128>,
1007/// s3: Lazy<u128>,
1008/// s4: Mapping<u128, Packed>,
1009/// s5: Lazy<NonPacked>,
1010/// s6: PackedGeneric<Packed>,
1011/// s7: NonPackedGeneric<Packed>,
1012/// // Fails because: the trait `ink::storage::traits::Packed` is not implemented for `NonPacked`
1013/// // s8: Mapping<u128, NonPacked>,
1014/// }
1015/// ```
1016///
1017/// ## Header Arguments
1018///
1019/// The `#[ink::storage_item]` macro can be provided with an additional comma-separated
1020/// header argument:
1021///
1022/// - `packed: flag`
1023///
1024/// Storage items flagged as `packed` use "packed" layout .
1025///
1026/// **Usage Example:**
1027/// ```
1028/// use ink::storage::Mapping;
1029///
1030/// #[ink::storage_item(packed)]
1031/// struct PackedGeneric<T: ink::storage::traits::Packed> {
1032/// s1: (u128, bool),
1033/// s2: Vec<T>,
1034/// s3: String,
1035/// }
1036/// ```
1037///
1038/// **Default value:** not set.
1039/// **Note**: The default behavior is to use "non-packed" layout, and automatically
1040/// derive storage keys for each field.
1041///
1042/// - `derive: bool`
1043///
1044/// The `derive` configuration parameter is used to enable/disable auto deriving of
1045/// all required storage traits.
1046///
1047/// **Usage Example:**
1048/// ```
1049/// use ink::storage::Mapping;
1050/// use ink::storage::traits::{
1051/// StorableHint,
1052/// StorageKey,
1053/// Storable,
1054/// };
1055///
1056/// #[ink::storage_item(derive = false)]
1057/// #[derive(StorableHint, Storable, StorageKey)]
1058/// struct NonPackedGeneric<T: ink::storage::traits::Packed> {
1059/// s1: u32,
1060/// s2: Mapping<u128, T>,
1061/// }
1062/// ```
1063///
1064/// **Default value:** true.
1065#[proc_macro_attribute]
1066pub fn storage_item(attr: TokenStream, item: TokenStream) -> TokenStream {
1067 storage_item::generate(attr.into(), item.into()).into()
1068}
1069
1070/// Defines a unit test that makes use of ink!'s off-chain testing capabilities.
1071///
1072/// If your unit test does not require the existence of an off-chain environment
1073/// it is fine to not use this macro since it bears some overhead with the test.
1074///
1075/// Note that this macro is not required to run unit tests that require ink!'s
1076/// off-chain testing capabilities but merely improves code readability.
1077///
1078/// ## How do you find out if your test requires the off-chain environment?
1079///
1080/// Normally if the test recursively uses or invokes some contract methods that
1081/// call a method defined in `self.env()` or `Self::env()`.
1082///
1083/// An examples is the following:
1084///
1085/// ```no_compile
1086/// let caller: AccountId = self.env().caller();
1087/// ```
1088///
1089/// # Example
1090///
1091/// ```
1092/// #[cfg(test)]
1093/// mod tests {
1094/// // Conventional unit test that works with assertions.
1095/// #[ink::test]
1096/// fn test1() {
1097/// // test code comes here as usual
1098/// }
1099///
1100/// // Conventional unit test that returns some Result.
1101/// // The test code can make use of operator-`?`.
1102/// #[ink::test]
1103/// fn test2() -> Result<(), ink_env::Error> {
1104/// // test code that returns a Rust Result type
1105/// }
1106/// }
1107/// ```
1108#[proc_macro_attribute]
1109pub fn test(attr: TokenStream, item: TokenStream) -> TokenStream {
1110 ink_test::generate(attr.into(), item.into()).into()
1111}
1112
1113synstructure::decl_derive!(
1114 [Event, attributes(ink)] =>
1115 /// Derives an implementation of the [`ink::Event`] trait for the given `struct`.
1116 ///
1117 /// **Note** [`ink::Event`] requires [`scale::Encode`] implementation.
1118 ///
1119 /// Usually this is used in conjunction with the [`EventMetadata`] derive.
1120 ///
1121 /// For convenience there is the [`event`] attribute macro that will expand to all the necessary
1122 /// derives for an event implementation, including this one.
1123 ///
1124 /// # Example
1125 ///
1126 /// ```
1127 /// use ink::{
1128 /// Event,
1129 /// env::DefaultEnvironment,
1130 /// };
1131 /// use scale::Encode;
1132 ///
1133 /// #[derive(Event, Encode)]
1134 /// struct MyEvent {
1135 /// a: u32,
1136 /// #[ink(topic)]
1137 /// b: [u8; 32],
1138 /// }
1139 ///
1140 /// #[derive(Event, Encode)]
1141 /// #[ink(anonymous)] // anonymous events do not have a signature topic
1142 /// struct MyAnonEvent {
1143 /// a: u32,
1144 /// #[ink(topic)]
1145 /// b: [u8; 32],
1146 /// }
1147 ///
1148 /// ink_env::emit_event(MyEvent { a: 42, b: [0x42; 32] });
1149 /// ink_env::emit_event(MyAnonEvent { a: 42, b: [0x42; 32] });
1150 /// ```
1151 ///
1152 /// # The Signature Topic
1153 ///
1154 /// By default, the [`ink::Event::SIGNATURE_TOPIC`] is calculated as follows:
1155 ///
1156 /// `blake2b("EventStructName(field1_type_name,field2_type_name)")`
1157 ///
1158 /// The hashing of the topic is done at codegen time in the derive macro, and as such only has
1159 /// access to the **names** of the field types as they appear in the code. As such, if the
1160 /// name of a field of a struct changes, the signature topic will change too, even if the
1161 /// concrete type itself has not changed. This can happen with type aliases, generics, or a
1162 /// change in the use of a `path::to::Type` qualification.
1163 ///
1164 /// Practically this means that two otherwise identical event definitions will have different
1165 /// signature topics if the name of a field type differs. For example, the following two events
1166 /// will have different signature topics:
1167 ///
1168 /// ```
1169 /// #[derive(ink::Event, scale::Encode)]
1170 /// pub struct MyEvent {
1171 /// a: u32,
1172 /// }
1173 ///
1174 /// mod other_event {
1175 /// type MyU32 = u32;
1176 ///
1177 /// #[derive(ink::Event, scale::Encode)]
1178 /// pub struct MyEvent {
1179 /// a: MyU32,
1180 /// }
1181 /// }
1182 ///
1183 /// assert_ne!(<MyEvent as ink::env::Event>::SIGNATURE_TOPIC, <other_event::MyEvent as ink::env::Event>::SIGNATURE_TOPIC);
1184 /// ```
1185 ///
1186 /// ## Custom Signature
1187 ///
1188 /// Sometimes it is useful to specify the custom signature topic.
1189 /// For example, when the event definition from the other contract is not accessible.
1190 ///
1191 /// The macro provides `#[ink(signature_topic = _)]` nested macro that allows to provide
1192 /// 32 byte hex string of the custom signature topic.
1193 ///
1194 /// Generates custom signature topic
1195 /// ```
1196 /// #[derive(ink::Event, scale::Encode)]
1197 /// #[ink(signature_topic = "1111111111111111111111111111111111111111111111111111111111111111")]
1198 /// pub struct MyCustomSignatureEvent {
1199 /// pub field: u32,
1200 /// pub topic: [u8; 32],
1201 /// }
1202 ///
1203 /// assert_eq!(Some([17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17]),
1204 /// <MyCustomSignatureEvent as ink::env::Event>::SIGNATURE_TOPIC)
1205 ///```
1206 /// ## Anonymous Events
1207 ///
1208 /// If the event is annotated with `#[ink(anonymous)]` then no signature topic is generated.
1209 /// `#[ink(signature_topic = _)]` should not be used.
1210 event::event_derive
1211);
1212
1213synstructure::decl_derive!(
1214 [EventMetadata] =>
1215 /// Derives the [`ink::EventMetadata`] trait for the given `struct`, which provides metadata
1216 /// about the event definition.
1217 ///
1218 /// Requires that the `struct` also implements the [`ink::Event`] trait,
1219 /// so this derive is usually used in combination with the [`Event`] derive.
1220 ///
1221 /// Metadata is not embedded into the contract binary, it is generated from a separate
1222 /// compilation of the contract with the `std` feature, therefore this derive must be
1223 /// conditionally compiled e.g. `#[cfg_attr(feature = "std", derive(::ink::EventMetadata))]`
1224 /// (see example below).
1225 ///
1226 /// For convenience there is the [`event`] attribute macro that will expand to all the necessary
1227 /// derives for an event implementation, including this one.
1228 ///
1229 /// # Example
1230 ///
1231 /// ```
1232 /// use ink::{
1233 /// Event,
1234 /// env::DefaultEnvironment,
1235 /// };
1236 /// use scale::Encode;
1237 ///
1238 /// #[cfg_attr(feature = "std", derive(::ink::EventMetadata))]
1239 /// #[derive(Event, Encode)]
1240 /// struct MyEvent {
1241 /// a: u32,
1242 /// #[ink(topic)]
1243 /// b: [u8; 32],
1244 /// }
1245 ///
1246 /// assert_eq!(<MyEvent as ink::metadata::EventMetadata>::event_spec().args().len(), 2);
1247 /// ```
1248 ///
1249 /// The generated code will also register this implementation with the global static distributed
1250 /// slice [`ink::metadata::EVENTS`], in order that the metadata of all events used in a contract
1251 /// can be collected.
1252 event::event_metadata_derive
1253);
1254
1255synstructure::decl_derive!(
1256 [Storable] =>
1257 /// Derives `ink::storage`'s `Storable` trait for the given `struct`, `enum` or `union`.
1258 ///
1259 /// # Examples
1260 ///
1261 /// ```
1262 /// use ink::storage::traits::Storable;
1263 ///
1264 /// #[derive(Storable)]
1265 /// struct NamedFields {
1266 /// a: u32,
1267 /// b: [u32; 1],
1268 /// }
1269 ///
1270 /// let value = <NamedFields as Storable>::decode(&mut &[123, 123][..]);
1271 /// ```
1272 storage::storable_derive
1273);
1274synstructure::decl_derive!(
1275 [StorableHint] =>
1276 /// Derives `ink::storage`'s `StorableHint` trait for the given `struct` or `enum`.
1277 ///
1278 /// If the type declaration contains generic `StorageKey`,
1279 /// it will use it as salt to generate a combined storage key.
1280 ///
1281 /// # Examples
1282 ///
1283 /// ```
1284 /// use ink::storage::traits::{
1285 /// Storable,
1286 /// StorableHint,
1287 /// StorageKey,
1288 /// AutoStorableHint,
1289 /// AutoKey,
1290 /// ManualKey,
1291 /// };
1292 ///
1293 /// #[derive(Default, StorableHint, Storable)]
1294 /// struct NamedFields {
1295 /// a: u32,
1296 /// b: [u32; 32],
1297 /// }
1298 ///
1299 /// let _: NamedFields = <NamedFields as StorableHint<AutoKey>>::Type::default();
1300 /// let _: NamedFields = <NamedFields as StorableHint<ManualKey<123>>>::Type::default();
1301 /// ```
1302 storage::storable_hint_derive
1303);
1304synstructure::decl_derive!(
1305 [StorageKey] =>
1306 /// Derives `ink::storage`'s `StorageKey` trait for the given `struct` or `enum`.
1307 ///
1308 /// # Examples
1309 ///
1310 /// ```
1311 /// use ink::storage::traits::{
1312 /// AutoStorableHint,
1313 /// StorageKey,
1314 /// ManualKey,
1315 /// AutoKey,
1316 /// };
1317 ///
1318 /// #[derive(StorageKey)]
1319 /// struct NamedFields {
1320 /// a: u32,
1321 /// b: [u32; 32],
1322 /// }
1323 ///
1324 /// assert_eq!(<NamedFields as StorageKey>::KEY, 0);
1325 ///
1326 /// #[derive(StorageKey)]
1327 /// struct NamedFieldsManualKey<KEY: StorageKey> {
1328 /// a: <u32 as AutoStorableHint<ManualKey<0, KEY>>>::Type,
1329 /// b: <[u32; 32] as AutoStorableHint<ManualKey<1, KEY>>>::Type,
1330 /// }
1331 ///
1332 /// assert_eq!(<NamedFieldsManualKey<()> as StorageKey>::KEY, 0);
1333 /// assert_eq!(<NamedFieldsManualKey<AutoKey> as StorageKey>::KEY, 0);
1334 /// assert_eq!(<NamedFieldsManualKey<ManualKey<123>> as StorageKey>::KEY, 123);
1335 /// ```
1336 storage::storage_key_derive
1337);
1338synstructure::decl_derive!(
1339 [StorageLayout] =>
1340 /// Derives `ink::storage`'s `StorageLayout` trait for the given `struct` or `enum`.
1341 ///
1342 /// # Examples
1343 ///
1344 /// ```
1345 /// use ink_metadata::layout::Layout::Struct;
1346 /// use ink::storage::traits::StorageLayout;
1347 ///
1348 /// #[derive(StorageLayout)]
1349 /// struct NamedFields {
1350 /// a: u32,
1351 /// b: [u32; 32],
1352 /// }
1353 ///
1354 /// let key = 0x123;
1355 /// let mut value = NamedFields {
1356 /// a: 123,
1357 /// b: [22; 32],
1358 /// };
1359 ///
1360 /// if let Struct(layout) = <NamedFields as StorageLayout>::layout(&key) {
1361 /// assert_eq!(*layout.fields()[0].name(), "a");
1362 /// assert_eq!(*layout.fields()[1].name(), "b");
1363 /// }
1364 /// ```
1365 storage::storage_layout_derive
1366);
1367
1368/// Derive the re-exported traits `ink::scale::Encode`, `ink::scale::Decode` and
1369/// `ink::scale_info::TypeInfo`. It enables using the built in derive macros for these
1370/// traits without depending directly on the `parity-scale-codec` and `scale-info` crates.
1371///
1372/// # Options
1373/// - `Encode`: derives `ink::scale::Encode`
1374/// - `Decode`: derives `ink::scale::Decode`
1375/// - `TypeInfo`: derives `ink::scale_info::TypeInfo`
1376///
1377/// # Examples
1378///
1379/// ```
1380/// #[ink::scale_derive(Encode, Decode, TypeInfo)]
1381/// pub enum Error {}
1382/// ```
1383/// This is a convenience macro that expands to include the additional `crate` attributes
1384/// required for the path of the re-exported crates.
1385///
1386/// ```
1387/// #[derive(::ink::scale::Encode, ::ink::scale::Decode)]
1388/// #[codec(crate = ::ink::scale)]
1389/// #[cfg_attr(
1390/// feature = "std",
1391/// derive(::scale_info::TypeInfo),
1392/// scale_info(crate = ::ink::scale_info)
1393/// )]
1394/// pub enum Error {}
1395/// ```
1396#[proc_macro_attribute]
1397pub fn scale_derive(attr: TokenStream, item: TokenStream) -> TokenStream {
1398 match scale::derive(attr.into(), item.into()) {
1399 Ok(output) => output.into(),
1400 Err(err) => err.to_compile_error().into(),
1401 }
1402}
1403
1404synstructure::decl_derive!(
1405 [SolDecode] =>
1406 /// Derives an implementation of `ink::SolDecode`
1407 /// for the given `struct` or `enum`.
1408 ///
1409 /// # Note
1410 ///
1411 /// All field types (if any) must implement [`ink::SolDecode`].
1412 ///
1413 /// # Example
1414 ///
1415 /// ```
1416 /// use ink_macro::SolDecode;
1417 ///
1418 /// #[derive(SolDecode)]
1419 /// struct UnitStruct;
1420 ///
1421 /// #[derive(SolDecode)]
1422 /// struct TupleStruct(bool, u8, String);
1423 ///
1424 /// #[derive(SolDecode)]
1425 /// struct FieldStruct {
1426 /// status: bool,
1427 /// count: u8,
1428 /// reason: String,
1429 /// }
1430 ///
1431 /// #[derive(SolDecode)]
1432 /// enum SimpleEnum {
1433 /// One,
1434 /// Two,
1435 /// Three,
1436 /// }
1437 ///
1438 /// #[derive(SolDecode)]
1439 /// struct NestedStruct {
1440 /// unit: UnitStruct,
1441 /// tuple: TupleStruct,
1442 /// fields: FieldStruct,
1443 /// enumerate: SimpleEnum,
1444 /// }
1445 ///
1446 /// #[derive(SolDecode)]
1447 /// struct GenericStruct<T> {
1448 /// concrete: u8,
1449 /// generic: T,
1450 /// }
1451 /// ```
1452 ///
1453 /// # Note
1454 ///
1455 /// Solidity has no semantic equivalent for enums with fields
1456 /// (i.e. [Solidity enums][sol-enum] can only express the equivalent of
1457 /// Rust [unit-only][rust-enum-unit-only] or [field-less][rust-enum-field-less] enums).
1458 /// So mapping complex Rust enums (i.e. enums with fields) to "equivalent" Solidity
1459 /// representations typically yields complex structures based on
1460 /// tuples (at [Solidity ABI encoding][sol-abi] level)
1461 /// and structs (at Solidity language level).
1462 ///
1463 /// Because of this, this `Derive` macro doesn't generate [`ink::SolEncode`]
1464 /// implementations for enums with fields.
1465 ///
1466 /// [sol-enum]: https://docs.soliditylang.org/en/latest/types.html#enums
1467 /// [rust-enum-unit-only]: https://doc.rust-lang.org/reference/items/enumerations.html#r-items.enum.unit-only
1468 /// [rust-enum-field-less]: https://doc.rust-lang.org/reference/items/enumerations.html#r-items.enum.fieldless
1469 /// [sol-abi]: https://docs.soliditylang.org/en/latest/abi-spec.html#mapping-solidity-to-abi-types
1470 sol::sol_decode_derive
1471);
1472
1473synstructure::decl_derive!(
1474 [SolEncode] =>
1475 /// Derives an implementation of `ink::SolEncode`
1476 /// for the given `struct` or `enum`.
1477 ///
1478 /// # Note
1479 ///
1480 /// All field types (if any) must implement [`ink::SolEncode`].
1481 ///
1482 /// # Example
1483 ///
1484 /// ```
1485 /// use ink_macro::SolEncode;
1486 ///
1487 /// #[derive(SolEncode)]
1488 /// struct UnitStruct;
1489 ///
1490 /// #[derive(SolEncode)]
1491 /// struct TupleStruct(bool, u8, String);
1492 ///
1493 /// #[derive(SolEncode)]
1494 /// struct FieldStruct {
1495 /// status: bool,
1496 /// count: u8,
1497 /// reason: String,
1498 /// }
1499 ///
1500 /// #[derive(SolEncode)]
1501 /// enum SimpleEnum {
1502 /// One,
1503 /// Two,
1504 /// Three,
1505 /// }
1506 ///
1507 /// #[derive(SolEncode)]
1508 /// struct NestedStruct {
1509 /// unit: UnitStruct,
1510 /// tuple: TupleStruct,
1511 /// fields: FieldStruct,
1512 /// enumerate: SimpleEnum,
1513 /// }
1514 ///
1515 /// #[derive(SolEncode)]
1516 /// struct GenericStruct<T> {
1517 /// concrete: u8,
1518 /// generic: T,
1519 /// }
1520 /// ```
1521 ///
1522 /// # Note
1523 ///
1524 /// Solidity has no semantic equivalent for enums with fields
1525 /// (i.e. [Solidity enums][sol-enum] can only express the equivalent of
1526 /// Rust [unit-only][rust-enum-unit-only] or [field-less][rust-enum-field-less] enums).
1527 /// So mapping complex Rust enums (i.e. enums with fields) to "equivalent" Solidity
1528 /// representations typically yields complex structures based on
1529 /// tuples (at [Solidity ABI encoding][sol-abi] level)
1530 /// and structs (at Solidity language level).
1531 ///
1532 /// Because of this, this `Derive` macro doesn't generate [`ink::SolEncode`]
1533 /// implementations for enums with fields.
1534 ///
1535 /// [sol-enum]: https://docs.soliditylang.org/en/latest/types.html#enums
1536 /// [rust-enum-unit-only]: https://doc.rust-lang.org/reference/items/enumerations.html#r-items.enum.unit-only
1537 /// [rust-enum-field-less]: https://doc.rust-lang.org/reference/items/enumerations.html#r-items.enum.fieldless
1538 /// [sol-abi]: https://docs.soliditylang.org/en/latest/abi-spec.html#mapping-solidity-to-abi-types
1539 sol::sol_encode_derive
1540);
1541
1542synstructure::decl_derive!(
1543 [SolErrorDecode] =>
1544 /// Derives an implementation of `ink::sol::SolErrorDecode`
1545 /// for the given `struct` or `enum`.
1546 ///
1547 /// # Note
1548 ///
1549 /// - All field types (if any) must implement [`ink::SolDecode`].
1550 /// - The error representation derived is a [Solidity custom error][sol-error]
1551 /// (or multiple Solidity custom error in the case of an enum,
1552 /// i.e. one for each enum variant).
1553 ///
1554 /// [sol-error]: https://soliditylang.org/blog/2021/04/21/custom-errors/
1555 ///
1556 /// # Example
1557 ///
1558 /// ```
1559 /// use ink_macro::SolErrorDecode;
1560 ///
1561 /// // Represented as a Solidity custom error with no parameters
1562 /// #[derive(SolErrorDecode)]
1563 /// struct UnitError;
1564 ///
1565 /// // Represented as a Solidity custom error with parameters
1566 /// #[derive(SolErrorDecode)]
1567 /// struct ErrorWithParams(bool, u8, String);
1568 ///
1569 /// // Represented as a Solidity custom error with named parameters
1570 /// #[derive(SolErrorDecode)]
1571 /// struct ErrorWithNamedParams {
1572 /// status: bool,
1573 /// count: u8,
1574 /// reason: String,
1575 /// }
1576 ///
1577 /// // Represented as multiple Solidity custom errors
1578 /// // (i.e. each variant represents a Solidity custom error)
1579 /// #[derive(SolErrorDecode)]
1580 /// enum MultipleErrors {
1581 /// UnitError,
1582 /// ErrorWithParams(bool, u8, String),
1583 /// ErrorWithNamedParams {
1584 /// status: bool,
1585 /// count: u8,
1586 /// reason: String,
1587 /// }
1588 /// }
1589 /// ```
1590 sol::sol_error_decode_derive
1591);
1592
1593synstructure::decl_derive!(
1594 [SolErrorEncode] =>
1595 /// Derives an implementation of `ink::sol::SolErrorEncode`
1596 /// for the given `struct` or `enum`.
1597 ///
1598 /// # Note
1599 ///
1600 /// - All field types (if any) must implement [`ink::SolEncode`].
1601 /// - The error representation derived is a [Solidity custom error][sol-error]
1602 /// (or multiple Solidity custom error in the case of an enum,
1603 /// i.e. one for each enum variant).
1604 ///
1605 /// [sol-error]: https://soliditylang.org/blog/2021/04/21/custom-errors/
1606 ///
1607 /// # Example
1608 ///
1609 /// ```
1610 /// use ink_macro::SolErrorEncode;
1611 ///
1612 /// // Represented as a Solidity custom error with no parameters
1613 /// #[derive(SolErrorEncode)]
1614 /// struct UnitError;
1615 ///
1616 /// // Represented as a Solidity custom error with parameters
1617 /// #[derive(SolErrorEncode)]
1618 /// struct ErrorWithParams(bool, u8, String);
1619 ///
1620 /// // Represented as a Solidity custom error with named parameters
1621 /// #[derive(SolErrorEncode)]
1622 /// struct ErrorWithNamedParams {
1623 /// status: bool,
1624 /// count: u8,
1625 /// reason: String,
1626 /// }
1627 ///
1628 /// // Represented as multiple Solidity custom errors
1629 /// // (i.e. each variant represents a Solidity custom error)
1630 /// #[derive(SolErrorEncode)]
1631 /// enum MultipleErrors {
1632 /// UnitError,
1633 /// ErrorWithParams(bool, u8, String),
1634 /// ErrorWithNamedParams {
1635 /// status: bool,
1636 /// count: u8,
1637 /// reason: String,
1638 /// }
1639 /// }
1640 /// ```
1641 sol::sol_error_encode_derive
1642);
1643
1644synstructure::decl_derive!(
1645 [SolErrorMetadata] =>
1646 /// Derives an implementation of `ink::metadata::sol::SolErrorMetadata`
1647 /// for the given `struct` or `enum`.
1648 ///
1649 /// # Note
1650 ///
1651 /// - All field types (if any) must implement [`ink::SolEncode`].
1652 /// - The error representation derived is a [Solidity custom error][sol-error]
1653 /// (or multiple Solidity custom error in the case of an enum,
1654 /// i.e. one for each enum variant).
1655 ///
1656 /// [sol-error]: https://soliditylang.org/blog/2021/04/21/custom-errors/
1657 ///
1658 /// # Example
1659 ///
1660 /// ```
1661 /// use ink_macro::SolErrorMetadata;
1662 ///
1663 /// // Represented as a Solidity custom error with no parameters
1664 /// #[derive(SolErrorMetadata)]
1665 /// struct UnitError;
1666 ///
1667 /// // Represented as a Solidity custom error with parameters
1668 /// #[derive(SolErrorMetadata)]
1669 /// struct ErrorWithParams(bool, u8, String);
1670 ///
1671 /// // Represented as a Solidity custom error with named parameters
1672 /// #[derive(SolErrorMetadata)]
1673 /// struct ErrorWithNamedParams {
1674 /// status: bool,
1675 /// count: u8,
1676 /// reason: String,
1677 /// }
1678 ///
1679 /// // Represented as multiple Solidity custom errors
1680 /// // (i.e. each variant represents a Solidity custom error)
1681 /// #[derive(SolErrorMetadata)]
1682 /// enum MultipleErrors {
1683 /// UnitError,
1684 /// ErrorWithParams(bool, u8, String),
1685 /// ErrorWithNamedParams {
1686 /// status: bool,
1687 /// count: u8,
1688 /// reason: String,
1689 /// }
1690 /// }
1691 /// ```
1692 sol::sol_error_metadata_derive
1693);
1694
1695/// Implements the necessary traits for ABI encoding/decoding this type as revert error
1696/// data.
1697///
1698/// # Example
1699///
1700/// ```
1701/// #[ink::error]
1702/// pub enum Error {}
1703/// ```
1704///
1705/// # Note
1706///
1707/// This is a convenience macro that expands to the necessary lower-level macros depending
1708/// on the ink! project's specified ABI i.e.
1709///
1710/// - `ink::scale_derive` attribute macro for ABI mode "ink" or "all"
1711/// - `ink::SolErrorEncode`, `ink::SolErrorDecode` and `ink::SolErrorMetadata` custom
1712/// `Derive` macros for ABI mode "sol" or "all".
1713///
1714/// Using this macro is roughly equivalent to the following definition:
1715/// ```
1716/// #[cfg_attr(not(ink_abi = "sol"), ::ink::scale_derive(Encode, Decode, TypeInfo))]
1717/// #[cfg_attr(
1718/// any(ink_abi = "sol", ink_abi = "all"),
1719/// derive(::ink::SolErrorDecode, ::ink::SolErrorEncode)
1720/// )]
1721/// #[cfg_attr(
1722/// all(feature = "std", any(ink_abi = "sol", ink_abi = "all")),
1723/// derive(::ink::SolErrorMetadata)
1724/// )]
1725/// pub enum Error {}
1726/// ```
1727#[proc_macro_attribute]
1728pub fn error(attr: TokenStream, item: TokenStream) -> TokenStream {
1729 error::derive(attr.into(), item.into()).into()
1730}
1731
1732#[cfg(test)]
1733pub use contract::generate_or_err;