Releases: use-ink/ink
v6.0.0-beta.1
Here's how you can use this release:
cargo install --force --locked --version 6.0.0-beta.1 cargo-contract [dependencies]
ink = { version = "6.0.0-beta.1" }
[dev-dependencies]
ink_e2e = { version = "6.0.0-beta.1" }
# we moved the sandbox testing environment to a separate crate
# this one cannot be published to crates.io yet
ink_sandbox = { git = "https://github.com/use-ink/ink.git", branch = "6.0.0-beta.1" }You also need to install the latest ink-node release (there are binaries available for this release!).
If you use cargo install and are on Mac: click the link, there's a note for you, there's a system dependency required now.
Compatibility:
- Rust >= 1.88
cargo-contract6.0.0-beta.1ink-nodev0.47.0polkadot-sdkfrompolkadot-sdk/cbab8ed4be1941420dd25dc81102fb79d8e2a7f0(Oct 15, 2025)- Paseo Passet Hub (was upgraded here)
Full Changelog
Added
- Implement
bn128precompiles ‒ 2708 - Add example how to call Solidity precompiles ‒ 2716
- Add
packedflag tostorage_itemattribute and improve related diagnostics ‒ #2722 - Implement
pallet-revivehost functionsgas_price,call_data_size,return_data_size,gas_left‒ #2694 - Add
ink_precompilescrate with ERC-20 assets precompile interface ‒ #2686
Changed
- Refactor contract ref generation and add automatic re-exporting ‒ #2710
v6.0.0-beta
Version 6.0.0-beta
Here's how you can use this release:
cargo install --force --locked --version 6.0.0-beta cargo-contract [dependencies]
ink = { version = "6.0.0-beta" }
[dev-dependencies]
ink_e2e = { version = "6.0.0-beta" }
# we moved the sandbox testing environment to a separate crate
# this one cannot be published to crates.io yet
ink_sandbox = { git = "https://github.com/use-ink/ink.git", branch = "6.0.0-beta" }You also need to install the latest ink-node release (there are binaries available for this release!).
If you use cargo install and are on Mac: click the link, there's a note for you, there's a system dependency required now.
Compatibility:
- Rust >= 1.88
cargo-contract6.0.0-betaink-nodev0.46.0polkadot-sdkfrompolkadot-sdk/cbab8ed4be1941420dd25dc81102fb79d8e2a7f0(Oct 15, 2025)- Paseo Passet Hub (was upgraded here)
Breaking Changes
We moved the sandbox testing environment to a separate crate.
It changes the current behaviour from:
[dev-dependencies]
ink_e2e = { version = "v6.0.0-alpha.4", feature = "sandbox" }to
[dev-dependencies]
ink_e2e = { version = "6.0.0-beta" }
ink_sandbox = { git = "https://github.com/use-ink/ink.git", branch = "6.0.0-beta" }In the tests, you need to apply this change when using sandbox. Instead of:
#[ink_e2e::test(backend(runtime_only(sandbox = sandbox_runtime::ContractCallerSandbox)))]Change to:
#[ink_sandbox::test(backend(runtime_only(
sandbox = sandbox_runtime::ContractCallerSandbox,
client = ink_sandbox::SandboxClient
)))]Full Changelog
Added
- Implements the API for the
pallet-revivehost functiongas_limit- #2691 - Implements the API for the
pallet-revivehost functionto_account_id- #2578 - Add
#[ink::contract_ref]attribute - #2648 - Add
ink_revive_types(and removepallet-revivedependency fromink_e2e) - #2657 - non-allocating Solidity ABI encoder - #2655
- Implement XCM precompile, stabilize XCM API - #2687
Changed
- Marks the
pallet-revivehost functionaccount_idstable - #2578 - Stabilize
is_contract- #2654 - Extract
sandboxfromink_e2einto a newink_sandboxcrate - #2659 - Synchronize with
polkadot-sdk/1b1cef306d9ceebf963fd15a04b5c79ee2618bce‒ 2675 - Refactor
AbiEncodeWith::encode_to_slice- #2676 - Refactor
ArgumentListencoding and abstractions - #2678 - More flexible
SolEncodeimplementation forByteSlice- #2681 - Synchronize with
polkadot-sdk/cbab8ed4be1941420dd25dc81102fb79d8e2a7f0‒ 2689
Fixed
v6.0.0-alpha.4
Version 6.0.0-alpha.4
Here's how you can use this release:
cargo install --force --locked --git https://github.com/use-ink/cargo-contract --tag v6.0.0-alpha.4ink = { git = "https://github.com/use-ink/ink.git", tag = "v6.0.0-alpha.4", default-features = false, features = ["unstable-hostfn"] }
ink_e2e = { git = "https://github.com/use-ink/ink.git", tag = "v6.0.0-alpha.4", default-features = false }You also need to install the latest ink-node release (there are binaries available for this release!).
Compatibility:
- Rust >= 1.88
cargo-contractv6.0.0-alpha.4ink-nodev0.45.1polkadot-sdkfromuse-ink/polkadot-sdk/a71ec19a94702ea71767ba5ac97603ea6c6305c1- Passet Hub (was upgraded on Sep 12, 2025)
We have to use a slight fork of polkadot-sdk for the moment. It's just polkadot-sdk/master plus two
commits on top with pre-compiles. Those two commits are PRs to polkadot-sdk that haven't been merged yet, but should be any day now.
Added
- Add integration test for arithmetic overflow checks - #2631
- E2E: Misc quality of life improvements, new API functions, better debuggability ‒ 2634
Changed
- Error on message and constructor
selectoroverrides in Solidity ABI mode - #2638 - Improve abstractions for Solidity ABI encoding
Resulttypes - #2635 - Feature gate
xcm- #2641 - Refactor multi ABI interfaces for event emission via
ink_env- #2643
Fixed
v6.0.0-alpha.3
Version 6.0.0-alpha.3
Here's how you can use this release:
cargo install --force --locked --git https://github.com/use-ink/cargo-contract --tag v6.0.0-alpha.3ink = { git = "https://github.com/use-ink/ink.git", tag = "v6.0.0-alpha.3", default-features = false, features = ["unstable-hostfn"] }
ink_e2e = { git = "https://github.com/use-ink/ink.git", tag = "v6.0.0-alpha.3", default-features = false }You also need to install the latest ink-node release (there are binaries available for this release!).
Compatibility:
- Rust >= 1.88
cargo-contractv6.0.0-alpha.3ink-nodev0.45.1polkadot-sdkfromuse-ink/polkadot-sdk/a71ec19a94702ea71767ba5ac97603ea6c6305c1- Passet Hub (was upgraded on Sep 12, 2025)
We have to use a slight fork of polkadot-sdk for the moment. It's just polkadot-sdk/master plus two
commits on top with pre-compiles. Those two commits are PRs to polkadot-sdk that haven't been merged yet, but should be any day now.
Added
- Support functions of the
StorageandSystempre-compiles ‒ 2619
Changed
- Synchronize with
polkadot-sdk/c40b36c3a7c208f9a6837b80812473af3d9ba7f7‒ 2589 - Synchronize with
polkadot-sdk/a71ec19a94702ea71767ba5ac97603ea6c6305c1‒ 2619 - Refactor multi ABI interfaces - #2618
- Upgrade to Rust edition 2024 - #2624
Removed
- Removed functionalities around calling into the runtime and chain extensions ‒ 2621
- Remove
Environment::MAX_EVENT_TOPICSand removeEnvironmentgeneric type from event abstractions - #2622
Fixed
v6.0.0-alpha.1
Intermediate alpha release for ink!.
This release is compatible with:
polkadot-sdkcommitcb629d46ebf00aa65624013a61f9c69ebf02b0b4cargo-contractv6.0.0-alpha.1ink-nodev0.44.0 (notice there are binary releases linked)- Passet Hub if no newer pull request has been merged than this one
To depend on this release:
ink = { git = "https://github.com/use-ink/ink", tag = "v6.0.0-alpha.1" }
ink_e2e = { git = "https://github.com/use-ink/ink", tag = "v6.0.0-alpha.1" }
v6.0.0-alpha
This 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 - ...
v5.1.1
v5.1.0
This is the first ink! release outside of Parity. ink! was started at Parity and during this year became a community project maintained by the ink! Alliance, a loose group of former Parity employees and teams who want ink! to ensure a bright future for ink!.
You can find more details about the community handover in this X post. Generally, the only thing changing on the user-facing side is that the repositories have been moved from paritytech to the new GitHub organization use-ink.
❣ We want to say a big thank you to our Polkadot community, which recently decided on funding the continued maintenance and development of ink! with a Polkadot Treasury grant.
Highlights
This version of ink! comes with three highlights plus some minor fixes.
(1) XCM Support
ink! 5.1 supports the usage of XCM in contracts, developers are no longer limited to cross-contract calls, but can now execute cross-parachain calls.
We added a contract example that demonstrates the usage: contract-xcm
We also added a new page on our documentation website: https://use.ink/basics/xcm.
You can view the Rust docs of the two functions here:
(2) Call an ink! contract from a polkadot-sdk runtime
ink! 5.1 comes with basic support for calling contracts from a Polkadot runtime. We've added this example that demonstrates how to call flipper from a polkadot-sdk runtime pallet.
Calling a contract from the runtime is an interesting application for parachains, as they can put logic into a contract instead of their runtime. Contracts have a number of advantages, as they are easier to upgrade and allow for faster development iteration cycles.
The limitations currently are:
- Contract calls can only be made to trait messages. This makes sense in the
pallet-contractscontext, as it is better to depend on a trait rather than a contract impl, since you are working against an interface. - Only contract messages can be called currently, no constructors.
- The API could be nicer.
(3) E2E Testing
We replaced our drink sandbox dependency with an internal ink! crate. In case you use DRink!:
First, you should upgrade your drink dependency to version = "0.18.0". Second, these are the two changes you have to make:
- #[ink_e2e::test(backend(runtime_only(sandbox = ink_e2e::MinimalSandbox)))]
+ #[ink_e2e::test(backend(runtime_only(sandbox = ink_e2e::DefaultSandbox)))]- ink_e2e = { version = "5", features = ["drink"] }
+ ink_e2e = { version = "5", features = ["sandbox"] }Compatibility
The compatibility changes a bit to ink! 5.0:
- Rust:
>= 1.81 cargo-contract:>= 5.0.0polkadot-sdk: >= v1.12.0
(this release stabilized thepallet-contractsXCM functions that ink! uses)substrate-contracts-node:>= 0.42.0- DRink!:
>= 0.18.0
For the linter incargo-contractthe Rust toolchain version changed.
To upgrade:
export TOOLCHAIN_VERSION=nightly-2024-09-05
rustup install $TOOLCHAIN_VERSION
rustup component add rust-src --toolchain $TOOLCHAIN_VERSION
rustup run $TOOLCHAIN_VERSION cargo install cargo-dylint dylint-link
Added
- [Runtime-to-Contract Calls] Environment agnostic contract invocation API, for calling contracts from runtime ‒ #2219
- [Runtime-to-Contract Calls] Add
no-panic-handlerfeature ‒ #2164 - [Runtime-to-Contract Calls] Add example for calling a contract from a runtime pallet ‒ #2189
- [XCM] Add
xcm_executeandxcm_sendsupport ‒ #1912 - [Linter] Add links to detailed lint description ‒ #2170
- [E2E] Adds a message to SandboxErr to add context for easier debugging ‒ #2218
- [E2E] Add ability to take and restore snapshots ‒ #2261 (thanks @0xLucca!)
- [E2E] Demonstrate usage of seeds for secret URIs in E2E test for chain snapshots ‒ #2163
Changed
- Update repository URLs & references from
paritytechGitHub organization to newuse-inkone ‒ #2220 and #2248 - [E2E] Update
subxtandpolkadot-sdkdependencies ‒ #2174 - [Drink backend] Replace
drinksandbox with internalink_sandbox‒ #2158
Fixed
- [XCM] Fix XCM-support to single encode the XCM message ‒ #2278
- [Examples] ERC-721:
burn()clears token approval ‒ #2099 - [E2E] Fix outdated docs for
[ink_e2e::test]‒ #2162 - [E2E] Build contracts before initializing node rpc ‒ #2168
- [E2E]
set_account_balancenow can't set balance below existential deposit ‒ #1983 (thanks @0xLucca!) - [E2E] Fix outdated docs for
[ink_e2e::test]‒ #2162
v5.0.0
ℹ️ We have created a migration guide from ink! 4 to ink! 5. It also contains an overview over all breaking changes and newly added features.
You can view it here.
Summary
This release addresses the rest of the severities described in the OpenZeppelin security review of ink! and cargo-contract.
One of the notable addressed issues is the proxy selector clashing attack.
As of this release, ink! only allows exactly one other message with a well-known reserved selector to be defined.
You can read more about the change in the #1827 and #2031.
ink! 5.0.0 features a significant number of new features:
- We have introduced a new API based on the calculated or specified selectors for the event definition. This allows events to be defined in separate files and modules, and be shared across multiple ink! contracts - #1827 and #2031.
- @pmikolajczyk41 has introduced an alternative E2E testing framework, DRink!, that support quasi-testing model, it allows the test simulate a running node as part of the E2E test while improving debugging experience such as allowing to set breakpoint and step through each stage of execution cycle.
- Following improvements in E2E, we have added a call builder API that allows to easily build calls while significantly reducing boilerplate code - #1917 and #2075
- Another notable introduction in 5.0.0 release is the support for multiple chain extensions that empower developers
to build even more sophisticated and advanced contracts for supported chains - #1958. - To further address our consideration of the intrinsic security of ink! smart contracts,
we have disallowed unchecked arithmetic expressions.cargo-contractwill fail to compile the contract with the raw arithmetic operation - #1831.
These are the main features we have introduced in this release. We also encourage developers
to have a look at more detailed changelog entries to find out about any breaking changes that may affect
the development of new ink! contracts.
Compatibility
See the compatibility section of our migration guide for a detailed description. On a high level:
- Rust:
>= 1.70 cargo-contract:>= 4.0.0- polkadot-sdk: >= 0.9.3. But if using the new functions introduced in #2123 and #2077 >= 1.8.0 and if using the new functions introduced in #2076 >= 1.9.0.
polkadot-js/apiandpolkadot-js/api-contract:>= 10.12.1substrate-contracts-node:>= 0.39.0
Changelog
Added
- Add Hash trait to Selector struct - #2149
instantiate_v2with additional limit parameters #2123- Custom signature topic in Events - #2031
- [Linter]
non_fallible_apilint - #2004 - [Linter] Publish the linting crates on crates.io - #2060
- [E2E] Added
create_call_builderfor testing existing contracts - #2075 call_v2cross-contract calls with additional limit parameters - #2077delegate_dependencyapi calls - #2076- Allow mutable parameters in messages - #2004
- Clean E2E configuration parsing - #1922
- Make
set_code_hashgeneric - #1906 - Provide a
StorageVecdatastructure built on top ofLazy- #1995 - Add fallible methods for
MappingandLazy- #1910 - [E2E] Allow testing with live-chain state - #1949
- [E2E] Call builders and extra gas margin option - #1917
- [Linter]
storage_never_freedlint - #1932 - [Linter]
strict_balance_equalitylint - #1914 - [Linter]
no_mainlint - #2001 - Reexport
scaledependencies, introduce#[ink::scale_derive]- #1890 - Upgradeable contracts example - #1889
- Persist static buffer size in metadata - #1880
- Modify static buffer size via environmental variables - #1869
- Added
sr25519_verifyfunction toink_env#1840 - Events
2.0- #1827 - Add
set_block_numberto off-chain test apiEngine- #1806 - Stabilize
call_runtime‒ #1749 - Schema generation - #1765
- Restrict wildcard selectors to have exactly one other message - #1708
- [Linter] Warn when primitive number is annotated as event topic - #1837
- [Drink backend] allow for arbitrary runtime - #1892
- [Drink backend] support runtime call - #1891
- [Drink backend] Make tests generic
E2EBackendtrait - #1867 - [Drink backend] Backend choice ‒ #1864
- [Drink backend] Backend traits - #1857
- [Drink backend] Abstract error and result structs - #1844
Changed
- Use name-only syntax for
anonymousink! event item configuration argument - #2140 - Restrict syntax for setting default ink! e2e test runtime-only emulator - #2143
- Restrict syntax for setting ink! e2e test node to auto - #2146
- Bump Substrate crates - #2141
- Minor fixes - #2144,
#2137, #2132 - Bump metadata version to 5 #2126
- Use
MaxEncodedLenfor output buffer size #2128 Mapping: Reflect all possible failure cases in comments ‒ #2079- [E2E] Rename
.callto.call_builder‒ #2078 - Improve syntax for ink! e2e
runtime_onlyattribute argument - #2083 - [E2E] Remove
additional_contractsparameter #2098 - [E2E] change node url backend config - #2101
- Messages return
TypeSpecdirectly - #1999 - Fail when decoding from storage and not all bytes consumed - #1897
- Support multiple chain extensions - #1958
- New example of how to use multiple chain extensions in one contract.
- Affects the usage of the
#[ink::chain_extension]macro and the definition of the chain extension.
- Split up
ink_lintingto mandatory and extra libraries - #2032 - [E2E] resolve DispatchError error details for dry-runs - #1994
- [E2E] update to new
drinkAPI - #2005 - Reexport
scaledependencies, introduce#[ink::scale_derive]‒ #1890 - Use of workspace dependencies and properties - #1835
- Remove of unchecked arithmetic - #1831
- Use
decode_allfor decoding cross contract call result - #1810 - [E2E] build contracts at runtime instead of during codegen - #1881
- [E2E] crate refactoring - #1830
- [E2E] improve call API, remove
build_message+ callback - #1782
Fixed
- Fix alignment in allocator [#2100](...