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;