Solidity & MetaMask Compatibility
With ink! v6, we have introduced an abi
field in a custom ink-lang
table
in the package.metadata
table of a contract's manifest
file (i.e. the Cargo.toml
file) - more details here.
It allows building your contract in Solidity ABI compatibility mode
when declared as follows:
[package.metadata.ink-lang]
abi = "sol"
The implication of supporting Solidity ABI encoding is that all types used as constructor/message argument and return types, and event argument types must define a mapping to an equivalent Solidity ABI type.
Rust/ink! to Solidity ABI type mapping
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.
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
…