v6.0.0-alpha
Pre-releaseThis is our first alpha release for ink! v6. We release it together with cargo-contract v6.0.0-alpha.
The biggest change is that we are in the process of migrating from pallet-contracts +
WebAssembly (executed in wasmi) to pallet-revive +
RISC-V (executed in PolkaVM).
This is a major breaking change, ink! v6 will only be compatible with cargo-contract >= v6
and chains that include pallet-revive.
We did a detailed write-up of the background to this development and the reasoning
here. We also updated the ink/ARCHITECTURE.md
to reflect the new setup.
Compatibility of this release:
In the following we'll describe some breaking changes on a high-level. The
context to understand them is that the pallet-revive team has Ethereum/Solidity
support as the number one priority. All their design decisions derive from that,
they don't want to maintain code that is unnecessary for that objective.
🚧 This is an alpha release, changes will still happen and there are rough edges. 🚧
Cross-contract calling Solidity contracts
We are introducing a new attribute abi for the #[ink::contract] macro.
These are the values it takes:
#[ink::contract(abi = "all")]
#[ink::contract(abi = "sol")]
#[ink::contract(abi = "ink")]
The default currently is abi = "ink", but we might change this before a production
release.
The implication of supporting Solidity ABI encoding is that there is a restriction on
the types you can use as constructor/message arguments or return types.
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.
Please note that your contract sizes will get larger if you support both the ink!
and Solidity ABI.
Types
Contract Balance: U256
For the type of a contract's balance, pallet-revive uses depending on the context
- either the configured
pallet_revive::Config::Currencytype (which corresponds
to theink::Environment::Balancetype. - or a hardcoded
U256(which corresponds to what Ethereum uses).
In this alpha release we just adhere to requiring the types thatpallet-reviveuses.
In an upcoming beta release this could be simplified to reduce UX friction by just
using one type everywhere and converting to thepallet-reviveone.
Contract Address: Address / H160
For a contract's account, pallet-revive is using either the configured AccountId type
of the polkadot-sdk runtime, or H160.
Address is a more semantically named type alias for H160 defined in ink_primitives,
and re-exported in the ink crate.
Finding the Address/H160 for an AccountId is done via an address derivation scheme
derived in #7662.
After instantiating a contract, the address is no longer returned by pallet-revive.
Instead one has to derive it from given parameters (see the linked PR). cargo-contract
does that automatically.
For contract instantiations and contract calls the pallet requires that a 1-to-1 mapping
of an AccountId to an Address/H160 has been created. This can be done via the
map_account/unmap_account API.
The PR #6096 contains more
information.
Besides the publicly exposed crate functions, we've introduced a new subcommand
cargo contract account that allows resolving the H160 contract address to the
Substrate AccountId which it is mapped to.
Contract Hash: H256
For a contract's hash value, pallet-revive uses a fixed H256, Previously,
the ink::Environment::Hash type referenced the hash type being used for the
contract's hash. Now it's just a fixed H256.
Contract delegates can no longer be done by code
In pallet-contracts (and hence up until ink! v5), a pattern for upgradeable
contracts was to delegate the contract execution to a different code, e.g. to
a new version of the contract's code.
This distinction of contract code that was uploaded to a chain vs. an instantiated
contract from this code no longer exists in pallet-revive. If you want to
delegate the execution, you will have to specify another contract's address
to which code you want to delegate to. This other contract needs to be instantiated
on-chain.
For the execution, the context of the contract that delegates will continue
to be used (storage, caller, value).
Specifically the delegate API changed like this:
/// ink! v5
#[derive(Clone)]
pub struct DelegateCall<E: Environment> {
code_hash: E::Hash,
call_flags: CallFlags,
}
/// ink! v6
#[derive(Clone)]
pub struct DelegateCall {
address: H160,
flags: CallFlags,
ref_time_limit: u64,
proof_size_limit: u64,
deposit_limit: Option<[u8; 32]>,
}
Feature ink/unstable-hostfn
In pallet-revive a number of functions can only be called by smart contracts
if the chain that the pallet is running on has enabled the feature
pallet-revive/unstable-hostfn.
This feature is not enabled on Kusama or Westend!
It is enabled for the substrate-contracts-node version that we linked above.
New debugging workflow
Previously pallet-contracts returned a debug_message field with contract
instantiations and dry-runs.
Whenever ink::env::debug_println was invoked in a contract, ink! wrote debugging
info to this field. This functionality has been removed. Instead pallet-revive now
supports other means of debugging.
The most relevant new debugging workflow is the tracing API. There are a number
of PRs that implemented it, so we won't link a specific one here. A good starting
point to look deeper into it is the tracing.rs.
We have implemented barebones support for this tracing API in the 6.0.0-alpha
versions of ink! + cargo-contract. But it's really barebones and should
certainly be improved before a production release.
Please see our developer documentation
for more details.
We've also added a contract example to illustrate these new debugging strategies:
debugging-strategies.
Restrictions which cfg attributes can be used
This change was done as a recommendation from the ink! 5.x audit.
In a nutshell it prevents developers from hiding functionality in a contract,
that would not be visible in the metadata (so e.g. on a block explorer).
The relevant PR is #2313.
From ink! 6.0 on only these attributes are allowed in #[cfg(…)]:
testfeature(withoutstd)anynotall
Metadata Changes
The field source.wasm was renamed to source.contract_binary.
no_main
Previously ink! contracts started with this line:
#![cfg_attr(not(feature = "std"), no_std)]This line instructs the Rust compiler to not link the Rust
standard library with your contract.
If you want to know about why:
we have an entry
"Why is Rust's standard library (stdlib) not available in ink!?"
Please see our developer documentation
in our FAQ.
With ink! v6, an additional crate-level attribute needs to be set:
#![cfg_attr(not(feature = "std"), no_std, no_main)]It instructs the compiler not to use the default fn main() {} function as the
entry point for your smart contract. This is needed because PolkaVM uses a different
entry point (the deploy function).
substrate-contracts-node can no longer be used
The substrate-contracts-node is still maintained by Parity for ink! v5 and
pallet-contracts, but it does not support pallet-revive.
We've set up a new project in its place: ink-node.
As before, it functions as a simple local development node.
It contains pallet-revive in a default configuration.
You can find binary releases of the node here.
Changed
- Restrict which
cfgattributes can be used ‒ #2313 - More idiomatic return types for metadata getters - #2398
- Define static distributed events slice in
inkcrate - #2487
Added
- Support for
caller_is_root- #2332 - Allow setting features for contract build in E2E tests - #2460
- Improve support for Solidity ABI calling conventions - #2411
- Implement contract invocation in off-chain environment engine - #1957
- Abstractions for mapping arbitrary Rust types to Solidity ABI compatible types - #2441
- Documentation for contract abi arg and provided Rust/ink! to Solidity type mappings - 2463
- Implement
SolDecode,SolTypeDecodeand supportSolBytesfor boxed slices - 2476
Fixed
- [E2E] Have port parsing handle comma-separated list ‒ #2336
- Always use ink! ABI/ SCALE codec for constructor and instantiation related builders and utilities - #2474
- Get rid of "extrinsic for call failed: Pallet error: Revive::AccountAlreadyMapped" - 2483
- CI disk usage via standardised toolchains:
stable1.86,nightly2025-02-20 - #2484 - CI contract size submission - #2490
- CI relax criteria for
measurements-masterartifact lookup - #2491