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