Looking for an ink! Successor on Polkadot? Introducing wrevive
Over the last months it has become increasingly clear that ink! is effectively unmaintained.
For teams who have invested in ink! and for new developers entering the Polkadot ecosystem, this creates a painful gap: there is no simple, actively-maintained, ink!-style smart contract SDK that feels familiar and is pleasant to use.
We (a small community team) ended up in the same situation.
Instead of giving up on the ink! developer experience, we decided to build a lightweight, pragmatic replacement on top of PolkaVM:
wrevive — a Rust contract toolkit for pallet-revive (PolkaVM)
GitHub: https://github.com/wetee-dao/wrevive
Our goal is not to reinvent everything. Our goal is to provide:
- A familiar experience for ink! developers
- A minimal, easy-to-read codebase that welcomes contributors
- A clean path forward for Polkadot contracts on PolkaVM
We are looking for early users, reviewers, and maintainers from the Polkadot community.
What is wrevive?
wrevive is a Cargo workspace that currently includes:
wrevive-api– contract runtime API with a unifiedEnv(on-chain/off-chain) plus:Storage,Mapping,List,List2D
wrevive-macro– ink!-style proc macros:#[revive_contract]#[revive(constructor)]/#[revive(message)]- Generates
deploy()/call()dispatch and ABI
cargo-wrevive–cargo wrevive buildsubcommand- Builds PolkaVM
.polkavmartifacts - Emits ABI JSON (including ink!-style ABI)
- Builds PolkaVM
exampleswrevive-contract: a SCALE-codec example contract usingwrevive-api+wrevive-macro(recommended starting point)
Repo: wrevive on GitHub
Workspace layout:
wrevive/
├── Cargo.toml
├── crates/
│ ├── wrevive-api/
│ ├── wrevive-macro/
│ └── cargo-wrevive/
├── examples/
│ └── wrevive-contract/
├── COVERAGE.md
└── README.md
Design Philosophy
We built wrevive with a few strict principles:
- Extreme simplicity & lightness
- Small, focused codebase
- Minimal “magic” so contributors can understand the whole stack
- Familiarity for ink! users
- ink!-style macros, entrypoints, and call conventions
- ink!-style ABI output for tool compatibility
- Leverage existing work
- We carefully studied ink! and PolkaVM code and re-applied the good ideas
- We intentionally avoid over-engineering or building a huge framework
- Developer experience first
- This is essentially a DX layer on top of
cargo-pvm-contract - We keep close to the existing PolkaVM toolchain, but smoother to use
- This is essentially a DX layer on top of
In other words: as close as possible to ink!, but on a modern, maintainable, minimal foundation.
Developer Experience: Writing Contracts
The recommended way to write contracts is to use wrevive-api + wrevive-macro.
From the example in examples/wrevive-contract/src/contract.rs:
- Entrypoints: put
#[revive_contract]onmod contract { ... } - Constructor:
#[revive(constructor)] pub fn deploy(...) -> ... - Messages:
#[revive(message)] pub fn foo(...) -> ...
Storage helpers:
storage!(b"...")→Storage<T>mapping!(b"...")→Mapping<K, V>list!(b"...")→List<Idx, V>list_2d!(b"...")→List2D<K1, Idx, V>
Prefixes for these storage items are derived from Blake2s256 (first 4 bytes), and #[revive_contract] will check for duplicate prefixes at compile time.
Common types
wrevive-api offers a set of SCALE-friendly types that you can use directly in storage and messages:
Address– 20-byte address (EVM/account compatible)H256– 32-byte hashU256– 256-bit unsigned integer (big-endian, EVM compatible)BlockNumber–u32Bytes– alias forVec<u8>
Examples: Storage<Address>, Mapping<Address, U256>, Mapping<H256, Bytes>.
Address and H256 can be converted to / from [u8; 20] / [u8; 32] via From/Into implementations, which is convenient when interfacing with other tooling.
Call Convention (ink!-style)
The generated call() method follows an ink!-compatible call convention:
- Read the first 4 bytes of call data as selector (
u32::from_be_bytes). - Decode
call_data[4..]as SCALE-encoded arguments, in order.
So the payload layout is:
payload = selector (4 bytes) ++ SCALE(args...)
Selector rules:
- With
#[revive(message, selector = 0x...)]:
use the provided 4-byte selector. - Otherwise: use the first 4 bytes of BLAKE2s256(function_name) (ink!-compatible behavior).
This makes it much easier to integrate wrevive contracts with existing ink!-oriented tooling and workflows.
Quick Start
Prerequisites
- Rust toolchain (nightly recommended)
cargo wrevive buildmay rely on unstable-Z ...flags- If you must use stable, you might need
RUSTC_BOOTSTRAP=1(not recommended for production)
rust-srccomponent (for build-std / cross builds):
rustup component add rust-src
Install cargo wrevive
From the repo root:
cargo install --path crates/cargo-wrevive
Build the example contract (.polkavm + ABI)
cargo wrevive build -p wrevive-contract
This produces (under the workspace target/ directory):
- PolkaVM bytecode:
target/<bin>.release.polkavm - ABI (JSON):
target/<bin>.release.abi.json(emitted bycargo-wrevive) - ABI (ink!-style):
target/contract/<contract_name>.json(emitted at compile time by#[revive_contract])
Filenames depend on the bin name and contract name resolution—check target/ after building.
Status: Work in Progress (Not Production-Ready… Yet)
We want to be very clear:
Status: Work in progress. Not production-ready.
APIs, ABIs, and behaviors may change without notice. Use at your own risk.
That said, this is exactly the phase where community feedback and contributions matter most:
- We can still change APIs relatively freely
- We can still simplify and improve the design
- We can still align with the expectations of ink! and Polkadot developers before ossifying anything
Why We’re Posting This Here
Because ink! is no longer actively maintained, the Polkadot ecosystem risks:
- Fragmentation across multiple small contract frameworks
- Loss of the familiar ink!-style developer experience
- Higher barrier to entry for new Rust developers
wrevive is our attempt to offer a realistic path forward:
- Stay close to ink!'s mental model and tooling
- Build on PolkaVM and
pallet-revive - Keep the implementation extremely simple and transparent, so more people can read, audit, and contribute
We are not a big company or a foundation project. We are just builders who need this tooling to exist—and we suspect many of you do too.
How You Can Help
If any of this resonates with you, there are several ways to get involved:
- Kick the tires
- Clone the repo, build the example contract, and try writing a small contract:
- https://github.com/wetee-dao/wrevive
- Review the design
- Look at
wrevive-api,wrevive-macro, andcargo-wrevive - Open issues for API ergonomics, missing features, or edge cases
- Look at
- Contribute code
- Help us:
- Improve documentation and examples
- Stabilize the ABI / call conventions
- Polish the macros and DX
- Help us:
- Integrate with tools
- If you maintain wallets, UIs, dev tools, or infra:
- Check if our ink!-style ABI and call conventions are enough
- Tell us what’s missing for smooth integration
- If you maintain wallets, UIs, dev tools, or infra:
We are especially interested in feedback from:
- Teams currently using ink! in production or testnets
- Tooling authors who want to keep supporting an ink!-like ecosystem
- Runtime / node developers who care about
pallet-revive/ PolkaVM
Call to the Polkadot Community
If you believe that Rust-based smart contracts and ink!-style DX are still important for Polkadot, we would love your input and help.
- Repo: https://github.com/wetee-dao/wrevive
- Example contract:
examples/wrevive-contract - Issues & discussions: please open them on GitHub
Let’s work together to keep the ink! spirit alive—with a simpler, more maintainable, community-driven successor on PolkaVM.