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