plutus-wasm 1.65.0.0 — 32-bit-correct Plutus evaluator
plutus 1.65.0.0, made correct and tested on wasm32 (WORD_SIZE_IN_BITS == 32).
Upstream Plutus assumes a 64-bit machine word; on wasm32 several default builtins silently diverge from
the on-chain (64-bit) evaluator. This release tracks upstream 1.65.0.0 with a small, CPP-gated stack
that makes wasm32 evaluation byte-identical to the chain — and proves it by running upstream's own
test suite under wasmtime.
What's verified
- Full upstream suite green on wasm32 under wasmtime:
plutus-core-test2294,untyped-plutus-core-test
870,plutus-ir-test332,index-envs-test36,satint-test17,flat-test1491. (flat-big-test
is a multi-GB memory stress test, gated — incompatible with wasm32's address space.) - 64-bit neutrality: all changes are gated behind
#if WORD_SIZE_IN_BITS == 64, so the source the
node compiles is byte-identical to upstream. Verified: the affected suites pass on x86_64 unchanged. - UPLC deserialization is platform-independent (flat
Word64codec), so a script decodes identically on
wasm32 and on-chain.
How to use it
1. As a source dependency (wallets, verifiers, anyone embedding the evaluator in their own wasm).
Pin this rev and cross-compile your own wasm with the corrected plutus linked in:
source-repository-package
type: git
location: https://github.com/lambdasistemi/plutus.git
tag: d6b0a1988 # or: 1.65.0.0-wasm32
subdir: plutus-core plutus-ledger-api plutus-tx
Builds are cached in the paolino cachix cache, so you pull the prebuilt wasm dep closure instead of
recompiling. This is how cardano-ledger-wasi and cardano-mpfs-offchain consume it.
Verified end-to-end: repinning cardano-ledger-wasi to this rev builds wasm-tx-inspector.wasm with
no API changes, and its tx.evaluate.scripts smoke evaluates real Plutus scripts on wasm32 →
ExUnits memory=376813, steps=369294715 (within budget).
2. As a standalone evaluator (no Haskell toolchain) — verified.
Download uplc.wasm from the assets and run the real CEK + cost model on a UPLC program:
printf '(program 1.0.0 [ [ (builtin addInteger) (con integer 40) ] (con integer 2) ])' > add.uplc
wasmtime run --dir . --dir /tmp uplc.wasm -- evaluate -i add.uplc # -> (con integer 42)
wasmtime run --dir . --dir /tmp uplc.wasm -- evaluate -i add.uplc -c # adds CPU budget: 181308 / Memory budget: 602Runs the same under a browser WASI shim — the "real CEK in the browser" use case.
3. Reproduce the proof (verified end-to-end). Needs a checkout — the goldens / test/data live in
the source, not the .wasm:
git clone -b 1.65.0.0-wasm32 https://github.com/lambdasistemi/plutus && cd plutus
nix build .#wasm-plutus-core-test
WASMTIME=$(nix build --no-link --print-out-paths .#wasm-toolchain)/bin/wasmtime
( cd plutus-core && "$WASMTIME" run --dir . --dir /tmp \
../result/plutus-core-test.wasm --hedgehog-tests 1000 --no-create )
# -> All 2294 tests passedTo just build the artifact without cloning: nix build github:lambdasistemi/plutus/1.65.0.0-wasm32#wasm-plutus-core-test
— the ref is required (bare github:lambdasistemi/plutus resolves to the default branch, which has
no wasm targets). The 🕸️ Wasm32 Testsuite workflow (runs-on: nixos, cachix-cached) runs the full
matrix on every push.
Assets
uplc.wasm(24.6 MB) — the UPLC evaluator (real CEK + cost model) compiled to wasm32-wasi. Verified under wasmtime:evaluate -i <prog>→ result;-c→ result +ExBudget.SHA256SUMS.