Skip to main content
Version: v6

Metadata Title Picture

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! typeSolidity ABI typeNotes
boolbool
iN for N ∈ {8,16,32,64,128}intNe.g i8int8
uN for N ∈ {8,16,32,64,128}uintNe.g u8uint8
ink::U256uint256
Stringstring
Box<str>string
ink::Address / ink::H160addressink::Address is a type alias for the ink::H160 type used for addresses in pallet-revive
[T; N] for const N: usizeT[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 <= 32bytesNe.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 T1U1, ... T12U12 e.g. (bool, u8, Address)(bool, uint8, address)

SolEncode is additionally implemented for reference and smart pointer types below:

Rust/ink! typeSolidity ABI typeNotes
&str, &mut strstring
&T, &mut T, Box<T>Te.g. &i8 ↔ int8
&[T], &mut [T]T[]e.g. &[i8]int8[]
note

Rust's Option and Result types are notable omissions from the default mappings. This is because they don't have semantically 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.

note

Rust's coherence/orphan rules mean that you can only implement the SolEncode and SolDecode traits for local types.

MetaMask

You can use MetaMask to interact with your ink! smart contract via the Solidity ABI.

To set up your wallet and connect to the appropriate network, follow this quick start guide: Connect MetaMask to Polkadot Hub Testnet

Network Details – Polkadot Hub Testnet

Network name: Polkadot Hub TestNet

Currency symbol: PAS

Chain ID: 420420422

RPC URL: https://testnet-passet-hub-eth-rpc.polkadot.io

Block explorer URL: https://blockscout-passet-hub.parity-testnet.parity.io/

For step-by-step manual configuration instructions, see this guide: Connect MetaMask to Polkadot Hub Testnet.

Solidity Tooling

You can deploy and interact with ink! smart contracts using popular Solidity tools like Hardhat and Foundry thanks to the Solidity-compatible ABI output.

Full Tutorial: Use Solidity Tooling with ink! Contracts

This guide walks through compiling an ink! contract with Solidity metadata, configuring Hardhat, deploying to the Polkadot Hub Testnet, and interacting with the contract using Ethers.js.

Block explorers

PolkaVM smart contracts are compatible with Ethereum-style block explorers such as BlockScout, which is already integrated with the Polkadot Hub Testnet.

For additional information and instructions, check out: Polkadot Smart Contract Block Explorers