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;