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