Skip to main content
Status: Accepted Date: 2026-06-30

Summary

RFC 0001 defines the product direction. This RFC defines the first engineering shape for implementing that direction. ProofForge should not use one backend strategy for every chain. It should split targets into implementation families:
  • Direct compiler targets: ProofForge owns most lowering logic, as with the current EVM/Yul backend.
  • Wasm host targets: ProofForge emits a Wasm module plus chain-specific host ABI adapters, as with NEAR and CosmWasm.
  • Binary toolchain targets: ProofForge emits an intermediate object/bitcode and calls a chain-specific packager/linker, as with Solana sBPF.
  • Source codegen targets: ProofForge emits target source packages, as with Sui Move and Aptos Move.
  • ZK circuit sourcegen targets: ProofForge emits target source packages and delegates circuit artifact generation to target-native tooling, as with Psy/DPN.
This keeps the portable contract model stable while allowing each chain family to keep its native ABI, storage model, tooling, and tests.

Design Goals

  • Keep Lean as the user-facing language for business logic, types, and proofs.
  • Keep target differences explicit through capabilities and target manifests.
  • Integrate with mature target-native tools before replacing them.
  • Make every build produce machine-readable artifact metadata.
  • Make every supported target earn support through at least one local smoke test and one capability matrix entry.
Non-goal: arbitrary Lean code should not be expected to compile to every target. The supported subset will be determined by the portable contract IR and the selected target’s capability profile.

Proposed Repository Shape

The current repository can evolve toward this layout (paths marked planned are not in the repo yet):
This is not a required one-shot refactor. It is a direction for staged work. The existing EVM implementation can remain where it is until Target and IR modules exist.

Target Profile

Every target should be described by a TargetProfile. Conceptually:
Initial target ids: Future research (not in registry until scheduled): wasm-polkadot (ink!). See decisions.md.

Capability Matrix

The compiler should use a target capability matrix before lowering. If a contract uses a capability that the target cannot represent, the build should fail with a precise diagnostic. Capability ids are canonical in capability-registry.md. The semantic matrix below maps portable meaning to target mechanics.

Artifact Metadata

Every build should emit proof-forge-artifact.json next to the target output. Initial schema:
The cloud platform can later store exactly this metadata, plus deployment addresses, transaction hashes, and test reports.

CLI Shape

The current CLI supports EVM bytecode directly:
The target-oriented CLI should eventually expose:
Near-term implementation can keep target scripts under scripts/<target>/ while the CLI is being generalized.

EVM Target

Current pipeline:
Implementation notes:
  • Keep ProofForge.Evm as the first concrete target adapter / extension SDK.
  • Keep .evm-methods as target metadata until a unified manifest exists.
  • Add artifact metadata around the existing bytecode path.
  • Add golden Yul snapshots for simple examples before major IR refactors.

NEAR Target

The Lean fork already demonstrates the desired Wasm-host pattern:
Key pieces observed in the fork:
  • Lean.Near: Lean SDK with @[extern "lean_near_*"] functions.
  • host/near/lean_near.zig: bridge from Lean objects to NEAR host imports.
  • tools/zigc-near: wrapper that generates method exports and links runtime.
  • near-strip-wasi-imports.cjs: removes WASI imports and checks MVP Wasm compatibility.
Implementation improvements needed for ProofForge:
  • Move lean_near_* extern declarations out of core EmitZig runtime externs.
  • Make host bridge selection target-driven instead of “all Wasm means NEAR”.
  • Move method export metadata into a generic target manifest.
  • Keep NEAR as the first reference for Wasm-host runtime shape.

CosmWasm Target

CosmWasm should share the Wasm-host family with NEAR, but it needs a separate adapter. Wasm is the artifact format; the contract ABI is different. Expected pipeline:
Required exports:
  • interface_version_8
  • allocate
  • deallocate
  • instantiate
  • execute
  • query
  • optional later: migrate, reply, sudo, ibc_*
The entrypoint adapter should use the CosmWasm region-pointer ABI. The first implementation should keep messages JSON-backed to avoid adding a full schema compiler before the backend exists. Authoritative SDK and spike sketch: targets/wasm-family.md (Counter spike section). Do not duplicate SDK definitions here. Zig bridge sketch:
First smoke test:
  • Counter contract with instantiate, execute({"increment":{}}), and query({"get_count":{}}).
  • Build Wasm.
  • Run cosmwasm-check.
  • Run a local Rust or CLI-based smoke that calls instantiate/execute/query.

Solana Target

Solana should have two implementation profiles.

Preferred track: solana-sbpf-linker

The zignocchio project shows a useful no-fork flow:
This matches the “intermediate artifact plus target packager” pattern used by EVM/Solang-style flows. ProofForge pipeline:
Required Solana adapter pieces:
  • Lean.Solana: account, instruction data, signer, PDA, CPI, log, return data.
  • lean_solana_* bridge functions in Zig.
  • solana_contract_root.zig: exports the single entrypoint(input) -> u64.
  • Instruction dispatch metadata, replacing NEAR-style method exports.
  • Explicit account schemas for each entrypoint.
Solana method manifest sketch (format: TOML v0, subject to change — full example with account index fields in targets/solana-sbf.md):
Root adapter sketch:
Testing strategy:
  • Fast deterministic program tests: Mollusk where possible.
  • Deployment-style smoke: solana-test-validator --bpf-program.
  • First contract: no CPI, one PDA/account state.
  • Second contract: CPI to System Program.
  • Third contract: SPL Token CPI.

Fallback/reference track: solana-zig-fork

The solana-sdk-mono project shows another route:
This route is useful because the SDK already models accounts, CPI, typed accounts, events, and program tests in a mature way. It should remain a reference even if ProofForge chooses sbpf-linker first.

Move Targets

Move targets should not try to compile the full Lean runtime. The first implementation should generate Move source packages from a restricted portable IR. Shared Move restrictions:
  • First-order functions only.
  • No closures or higher-order runtime values.
  • No arbitrary Lean heap objects at runtime.
  • Data types must map to Move structs/enums or generated variants.
  • Effects must be target capabilities, not arbitrary IO.
  • Proofs stay in Lean and are checked before Move code generation.

Sui

Sui uses an object-centric Move model. Persistent state should map to objects with UID. Pipeline:
Sui mapping: First Sui POC:
  • Counter object with init, increment, get.
  • Generate Move.toml and sources/counter.move.
  • Add Move unit tests.

Aptos

Aptos uses a module/resource model closer to account-scoped storage. Pipeline:
Aptos mapping: First Aptos POC:
  • Account-owned counter resource.
  • initialize(account: &signer)
  • increment(account: &signer)
  • get(addr: address): u64
Sui object POC follows in a separate slice after Aptos (see decisions.md).

Implementation Phases

Aligned with RFC 0001 and decisions.md:

Phase 1: Target registry, portable IR, metadata

Phase 2: Parallel spikes (CosmWasm + Solana)

  • Wasm-host extraction and wasm-cosmwasm Counter spike.
  • solana-sbpf-linker Counter spike with instruction manifest.
  • Both depend on Phase 1 completion; may run in parallel.

Phase 3: EVM hardening (ongoing)

  • Emit proof-forge-artifact.json for EVM builds.
  • Golden output tests for core EVM examples.

Phase 4: Move sourcegen (Aptos first)

  • Restricted Move-compatible IR subset.
  • Aptos counter package; Sui object POC as follow-up.

Phase 5: Cross-target scenario hardening and cloud prep

  • Shared scenario tests across multiple targets.
  • Cloud platform design after two+ Experimental targets.

Open Engineering Risks

  • Lean runtime on sBPF may be too large or use unsupported sections.
  • Full Lean heap/object model may be too expensive for Solana compute budgets.
  • CosmWasm may require a tighter no-WASI runtime than NEAR’s first path.
  • Move codegen requires a real ownership/resource model, not string templates.
  • A portable IR that is too close to EVM will fail on Solana and Move.
  • A portable IR that is too generic will become unusable for real contracts.

Settled Decisions

See decisions.md for the decision log. Key items:
  • Phase 1 before non-EVM spikes.
  • CosmWasm and Solana spikes in parallel after Phase 1.
  • solana-sbpf-linker as primary Solana path; solana-zig-fork as fallback.
  • Aptos-first Move POC; Sui follows.

Research References

  • EVM baseline in this repository: ProofForge.Compiler.LCNF.EmitYul, ProofForge.Evm, scripts/evm/foundry-smoke.sh.
  • NEAR reference in local Lean fork (lean4-zig-compiler): Lean.Near.lean, tools/zigc-near, src/runtime/zig/host/near.
  • Solana fork-target reference: https://github.com/DaviRain-Su/solana-sdk-mono.git.
  • Solana stock-Zig reference: https://github.com/vitorpy/zignocchio.
  • sbpf-linker: https://github.com/blueshift-gg/sbpf-linker.
  • CosmWasm docs: https://cosmwasm.cosmos.network/.
  • Sui Move docs: https://docs.sui.io/concepts/sui-move-concepts.
  • Aptos Move docs: https://aptos.dev/network/blockchain/move.