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