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.
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.
Proposed Repository Shape
The current repository can evolve toward this layout (paths marked planned are not in the repo yet):Target and IR
modules exist.
Target Profile
Every target should be described by aTargetProfile.
Conceptually:
| Target id | Family | Artifact | Status |
|---|---|---|---|
evm | EVM | Runtime bytecode | Implemented baseline |
wasm-near | Wasm host | NEAR-compatible Wasm | Researched in Lean fork |
wasm-cosmwasm | Wasm host | CosmWasm Wasm | New implementation track |
solana-sbpf-linker | Solana | Solana sBPF ELF .so | New preferred research track |
solana-zig-fork | Solana | Solana sBPF ELF .so | Fallback/reference track |
move-sui | Move | Sui Move package | Research/codegen track |
move-aptos | Move | Aptos Move package | Research/codegen track |
psy-dpn | ZK circuit sourcegen | DPN circuit JSON + ABI | Experimental/codegen track |
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 | EVM | NEAR | CosmWasm | Solana | Sui | Aptos | Psy DPN |
|---|---|---|---|---|---|---|---|
| Persistent scalar state | Slot storage | Host KV | Host KV | Account data | Object fields | Account resources | Psy storage/state |
| Caller/sender | msg.sender | predecessor/signer | MessageInfo.sender | signer account | TxContext.sender | signer | Psy user/context |
| Native value received | msg.value | attached deposit | funds in message info | lamport accounts | coin objects | coin resources | Psy-specific asset flow |
| Events/logs | EVM logs | logs/events | events/attributes | logs/events | events | events | Research |
| Cross-contract call | call/staticcall | promises | submessages | CPI | module calls/transactions | module calls | invoke_sync / invoke_deferred |
| State account/object selection | implicit contract | implicit contract | implicit contract | explicit accounts | explicit objects | account resources | Psy contract/user state |
| Dynamic map storage | mapping/keccak slot | KV prefixes | KV prefixes | account-owned data or PDAs | dynamic fields/tables | table resources | fixed-capacity Psy storage |
| Contract deployment package | bytecode | Wasm | Wasm | ELF .so | Move package | Move package | DPN circuit JSON + deploy JSON |
Artifact Metadata
Every build should emitproof-forge-artifact.json next to the target output.
Initial schema:
CLI Shape
The current CLI supports EVM bytecode directly:scripts/<target>/
while the CLI is being generalized.
EVM Target
Current pipeline:- Keep
ProofForge.Evmas the first concrete target adapter / extension SDK. - Keep
.evm-methodsas 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: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.
- 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:interface_version_8allocatedeallocateinstantiateexecutequery- optional later:
migrate,reply,sudo,ibc_*
- Counter contract with
instantiate,execute({"increment":{}}), andquery({"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:
Lean.Solana: account, instruction data, signer, PDA, CPI, log, return data.lean_solana_*bridge functions in Zig.solana_contract_root.zig: exports the singleentrypoint(input) -> u64.- Instruction dispatch metadata, replacing NEAR-style method exports.
- Explicit account schemas for each entrypoint.
index fields in
targets/solana-sbf.md):
- 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:
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 withUID.
Pipeline:
| Portable concept | Sui mapping |
|---|---|
| Contract state | Object struct with id: UID |
| Caller | TxContext.sender(ctx) |
| Entry method | public entry fun |
| Native value | Coin<T> objects |
| Events | sui::event::emit |
| Dynamic map | table, dynamic fields, or explicit child objects |
- Counter object with
init,increment,get. - Generate
Move.tomlandsources/counter.move. - Add Move unit tests.
Aptos
Aptos uses a module/resource model closer to account-scoped storage. Pipeline:| Portable concept | Aptos mapping |
|---|---|
| Contract state | struct State has key under an account |
| Caller | &signer |
| Entry method | public entry fun |
| Native value | aptos_coin / fungible asset APIs |
| Events | event module APIs |
| Dynamic map | table resources |
- Account-owned counter resource.
initialize(account: &signer)increment(account: &signer)get(addr: address): u64
Implementation Phases
Aligned with RFC 0001 and decisions.md:Phase 1: Target registry, portable IR, metadata
- Add target ids and capability sets (capability-registry.md).
- Implement portable IR per portable-ir.md.
- Define Counter shared scenario.
- Add artifact metadata schema.
- Keep current EVM command working.
Phase 2: Parallel spikes (CosmWasm + Solana)
- Wasm-host extraction and
wasm-cosmwasmCounter spike. solana-sbpf-linkerCounter spike with instruction manifest.- Both depend on Phase 1 completion; may run in parallel.
Phase 3: EVM hardening (ongoing)
- Emit
proof-forge-artifact.jsonfor 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-linkeras primary Solana path;solana-zig-forkas 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.