An Anoma Resource Machine (ARM) application that lets an Anoma transaction trigger arbitrary EVM calls.
A GenericCall resource encodes one or more EVM calls. When the resource is
consumed/created, the protocol adapter forwards those calls to the on-chain
GenericCallForwarder contract, which executes them on the target EVM. The
resource logic is a RISC0 zero-knowledge circuit that proves the forwarded
calldata matches the resource's committed label_ref and value_ref.
A GenericCall resource is always ephemeral and binds two references:
label_ref = hash(forwarder_addr)— pins the resource to a specificGenericCallForwardercontract.value_ref = hash(abi_encode(calls))— pins the resource to the exact set of EVM calls ((address to, uint256 value, bytes data)[]).
When the resource is constrained, the circuit:
- Asserts the resource is ephemeral.
- Recomputes
label_refandvalue_reffrom the witness and checks them against the resource. - Computes the resource's nullifier (if consumed) or commitment (if created).
- Emits the ABI-encoded forwarder calldata as an external payload blob (with
DeletionCriterion::Immediately) for the protocol adapter to deliver to the forwarder contract.
| Crate | Description |
|---|---|
generic_call_witness |
no_std-friendly witness library: the GenericCall type and the LogicCircuit constraint logic that runs inside the zkVM guest. |
generic_call_library |
Host-side prover. Wraps the witness in GenericCallLogic (LogicProver) and embeds the compiled guest ELF and image ID. |
generic_call_circuit |
The RISC0 guest binary and integration tests. Building it produces the ELF and image ID consumed by generic_call_library. Excluded from the workspace. |
The workspace crates build with the standard toolchain:
cargo build --workspace --all-targetsThe circuit is a separate package (it needs the RISC0 toolchain) and is built and tested from its own directory:
cd generic_call_circuit
cargo build --all-targets
cargo test -- --nocapturegeneric_call_library embeds a prebuilt guest ELF
(generic_call_library/elf/generic-call-guest.bin) and its image ID
(GENERIC_CALL_ID). After changing the witness/circuit, rebuild the guest with
the RISC0 toolchain, copy the resulting ELF into generic_call_library/elf/,
and update GENERIC_CALL_ID in generic_call_library/src/lib.rs
with the printed image ID.
GPL-3.0