Ink! Is Stalling – Let’s Revive Polkadot Smart Contracts with wrevive

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:

:backhand_index_pointing_right: 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 unified Env (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-wrevivecargo wrevive build subcommand
    • Builds PolkaVM .polkavm artifacts
    • Emits ABI JSON (including ink!-style ABI)
  • examples
    • wrevive-contract: a SCALE-codec example contract using wrevive-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

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] on mod 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 hash
  • U256 – 256-bit unsigned integer (big-endian, EVM compatible)
  • BlockNumberu32
  • Bytes – alias for Vec<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:

  1. Read the first 4 bytes of call data as selector (u32::from_be_bytes).
  2. 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 build may rely on unstable -Z ... flags
    • If you must use stable, you might need RUSTC_BOOTSTRAP=1 (not recommended for production)
  • rust-src component (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 by cargo-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
  • Review the design
    • Look at wrevive-api, wrevive-macro, and cargo-wrevive
    • Open issues for API ergonomics, missing features, or edge cases
  • Contribute code
    • Help us:
      • Improve documentation and examples
      • Stabilize the ABI / call conventions
      • Polish the macros and DX
  • 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

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.

Let’s work together to keep the ink! spirit alive—with a simpler, more maintainable, community-driven successor on PolkaVM.

2 Likes