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