How it works
Nothing here is a diagram of something that happens elsewhere. Every line below is a line you can run: the page compiles, the browser proves, the chain checks.
A function is a straight line arithmetic program over the scalar field of BN254. It has four input slots and sixteen steps. A step reads two cells that have already been written, applies one of six operations, and writes one cell. The value of the function is the last cell.
| Op | Does |
|---|---|
| ADD | v[a] + v[b] |
| SUB | v[a] - v[b] |
| MUL | v[a] · v[b] |
| ADDK | v[a] + k |
| MULK | v[a] · k |
| CONST | k |
An opcode and its two operand indices fit in thirteen bits, so all sixteen steps of a program fit in a single field element. The shape of a function is one number. What is left is the immediates, which are full width.
program = Poseidon(Poseidon(TAG, codePack), k₀) … k₁₅
That chain is short enough for the EVM to walk, which is the whole reason it is shaped this way: an author can publish the body later and have the chain itself recompute the commitment and agree it is the same function. About 515 000 gas, once, and only if the author wants it.
A caller posts Poseidon(INPUT_TAG, Poseidon(x₀…x₃), salt) and a ciphertext for whoever operates the function. The inputs are not in the transaction, not in the logs, and not in the mempool. The salt is what stops a guess being confirmed by hashing it.
Whatever is paid above the function's fee is the bounty, and it goes whole to whoever answers. If nobody answers within a day, the caller takes everything back — the fee included, because nothing was computed. If the function is retired in the meantime, the wait is waived.
A groth16 proof over four public signals: the program commitment, the input commitment, the value, and a binding. It says, in one sentence:
I know a program with that commitment and an input behind that seal, and running one on the other gives y.
The binding is rebuilt by the contract from the chain id, the executor, the call id and the address settling it. A proof lifted out of the mempool verifies for nobody else, so a bounty cannot be taken in flight. Verification costs 216 319 gas, and it happens before a single wei moves.
| Circuit | 12 772 constraints, groth16 over BN254 |
| Ceremony | hermez phase 1, two contributions, an Ethereum block as beacon |
| Proving, in a browser | ≈ 1 s |
| Verification, on chain | 216 319 gas |
Half of a function's fee is the author's, pulled when they want it. The other half is endowed to the function itself. Anyone may spend an endowment: compound buys the coin on the open market — judged against half an hour of price rather than the price of the moment, and reverting rather than filling badly — and binds what it buys to that function. One percent of the endowment pays whoever spent the gas.
Bound coin is weight. Weight ranks the canon and nothing else: it votes on nothing, it earns nothing, it cannot be taken by anybody. It leaves in exactly one way — the author retires the function, which closes it to any further call and returns every coin and every unspent wei at once.
The coin has no mint, no owner, no tax, no cap on a buy or on a balance, no blacklist and no proxy. The registry and the executor have no admin, no setter and no upgrade path. The only privileged address in the system is the executor, which the registry creates itself, in its own constructor, and which can do exactly one thing: credit a function's endowment out of a call it has already verified.
Everything a cycle is tuned by — the author's share, the keeper's tip, the slip tolerance, the window, the compound floor, the refund delay — is a constructor argument, bounded on construction, and zero is a valid setting for any of them.