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