Solidity & MetaMask Compatibility
With ink! v6, we have introduced a new attribute argument abi
for the #[ink::contract]
macro.
It allows building your contract in Solidity ABI compatibility mode (more details here).
The implication of supporting Solidity ABI encoding is that all types used as constructor/message arguments and return types must define a mapping to an equivalent Solidity type.
This mapping is defined using the SolEncode
and SolDecode
traits,
which are analogs to scale::Encode
and scale::Decode
(but for Solidity ABI encoding/decoding).
You won't be able to use Rust types for which no mapping to a Solidity type exists.
An error about a missing trait implementation for this type will be thrown.
Rust/ink! to Solidity ABI type mapping
Default/provided mappings
SolEncode
and SolDecode
are implemented
for the following Rust/ink! primitive types creating a mapping
to the corresponding Solidity ABI types as shown in the table below:
Rust/ink! type | Solidity ABI type | Notes |
---|---|---|
bool | bool | |
iN for N ∈ {8,16,32,64,128} | intN | e.g i8 ↔ int8 |
uN for N ∈ {8,16,32,64,128} | uintN | e.g u8 ↔ uint8 |
ink::U256 | uint256 | |
String | string | |
Box<str> | string | |
ink::Address / ink::H160 | address | ink::Address is a type alias for the ink::H160 type used for addresses in pallet-revive |
[T; N] for const N: usize | T[N] | e.g. [i8; 64] ↔ int8[64] |
Vec<T> | T[] | e.g. Vec<i8> ↔ int8[] |
Box<[T]> | T[] | e.g. Box<[i8]> ↔ int8[] |
ink::SolBytes<u8> | bytes1 | |
ink::SolBytes<[u8; N]> for 1 <= N <= 32 | bytesN | e.g. ink::SolBytes<[u8; 1]> ↔ bytes1 |
ink::SolBytes<Vec<u8>> | bytes | |
ink::SolBytes<Box<[u8]>> | bytes | |
(T1, T2, T3, ... T12) | (U1, U2, U3, ... U12) | where T1 ↔ U1 , ... T12 ↔ U12 e.g. (bool, u8, Address) ↔ (bool, uint8, address) |
SolEncode
is additionally implemented for reference and smart
pointer types below:
Rust/ink! type | Solidity ABI type | Notes |
---|---|---|
&str , &mut str | string | |
&T , &mut T , Box<T> | T | e.g. &i8 ↔ int8 |
&[T] , &mut [T] | T[] | e.g. &[i8] ↔ int8[] |
Rust's Option
and Result
types are notable omissions from the default mappings.
This is because they don't have equivalent Solidity ABI types.
Mappings for arbitrary custom types
See the rustdoc for SolEncode
and SolDecode
for instructions for implementing the traits for arbitrary custom types.
Rust's coherence/orphan rules mean that you can
only implement the SolEncode
and SolDecode
traits for local types.
The following sections have not yet been written for ink! v6.
TODO @davidsemakula
MetaMask
…
Hardhat, Foundry, etc.
…
Block explorers
…