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