On Ethereum’s agent registries: ERC-8004
ERC-8004, Trustless Agents, puts agents in three registries on EVM chains:
- the Identity Registry, an ERC-721 whose token URI names an agent’s registration file;
- the Reputation Registry, which keeps the feedback clients give an agent;
- the Validation Registry, which keeps validators’ answers to requests to check an agent’s work.
sion agent erc8004 makes everything those registries take that is the
agent’s, or its client’s, to write. It writes each call out as a
transaction (chainId, to, data) for a wallet to send. It never sends
one, never reads a chain, and needs no RPC provider.
The addresses are those of the reference deployment
(erc-8004-contracts).
On Ethereum, Optimism, Polygon, Base and Arbitrum One the Identity
Registry is 0x8004A169FB4a3325136EB29fA0ceB6D2e539a432 and the
Reputation Registry 0x8004BAa17C55a88189AE136b182e5fdA19dE9b63. On
Sepolia, Base Sepolia, Optimism Sepolia, Arbitrum Sepolia, Polygon Amoy,
Linea Sepolia, BNB Smart Chain’s testnet, Avalanche Fuji and Hedera’s
testnet they are 0x8004A818BFB912233c491871b3d84c89A494BD9e and
0x8004B663056A597Dffe9eCcC1965A193B7388713. On any other chain,
--registry gives the address; none is guessed. No Validation Registry is
listed as deployed yet, so validate takes its address.
The registration file
$ sion agent erc8004 card lead --description "Pays Acme's invoices." \
--a2a https://lead.example/.well-known/agent-card.json --x402 \
--agent-id 22 --chain 11155111 --out registration.json
wrote lead's registration file: registration.json
The file is the spec’s registration-v1. It holds the agent’s name and
description and its services: the A2A card, the MCP server and the web
page you name, and always its Siontology DID (did:sion:<chain>:<agent>).
Its supportedTrust is reputation and crypto-economic. Both are what
the DID leads to on Siontology: the agent’s record of what it was paid for
and delivered, and the bonds behind its claims, which an adjudicator can
rule against. Once the agent is registered, --agent-id adds its entry
(eip155:<chain>:<registry>). --data-uri prints the file as a data:
URI too, to keep it wholly on chain. check <file> reads any
registration file and checks its type, its name and its entries.
The description is public. It is never taken from the operator’s instructions.
Registering, and binding the agent’s wallet
$ sion agent erc8004 register --uri https://lead.example/agent.json --chain 11155111
{
"chainId": 11155111,
"to": "0x8004A818BFB912233c491871b3d84c89A494BD9e",
"data": "0xf2c298be…",
"what": "registers an agent whose registration file is at https://lead.example/agent.json"
}
The owner sends register(agentURI) and becomes the token’s owner. The
registry sets the agent’s wallet to the owner at first. To make another
wallet the agent’s, that wallet signs an EIP-712 AgentWalletSet for the
registry (domain ERC8004IdentityRegistry, version 1). wallet signs
it with the key in EVM_PRIVATE_KEY, which is read from the environment
and kept nowhere. Then it writes setAgentWallet for the owner to send:
$ EVM_PRIVATE_KEY=… sion agent erc8004 wallet 22 --owner 0x1111111111111111111111111111111111111111 --chain 11155111
0x2c7536E3605D9C16a7a3D7b1898e529396a65c23 signs that it is agent 22's wallet until 2026-11-07T08:38:33Z; 0x1111111111111111111111111111111111111111 sends this:
{
"chainId": 11155111,
"to": "0x8004A818BFB912233c491871b3d84c89A494BD9e",
"data": "0x2d1ef5ae…",
"what": "makes 0x2c7536E3605D9C16a7a3D7b1898e529396a65c23 agent 22's wallet"
}
The registry takes a signature good for at most five minutes by the
chain’s clock. wallet signs for four unless told otherwise (--within),
so a clock a little ahead of the chain’s does not push it past the limit,
and the owner sends the call soon after.
Feedback and validation
A client gives feedback with feedback <agent> --value <decimal> --client <address>, and --tag1, --tag2 and --endpoint to say what
it is about. The command writes the spec’s feedback file (--out) and
the giveFeedback call, which names the file by its URI (--uri) and its
Keccak digest. The value is a decimal: 99.77 is 9977 with two decimals.
The registry refuses feedback from the agent’s own owner and its
operators.
A validator answers a request with validate --request <digest> --response <0–100> --registry <address>. --found <file> names what it
found by its Keccak digest, at --uri. On Siontology, a verifier who
rebuilt and scored a release and attested it on its bond
(Improving itself) can give
the same answer on Ethereum, pointing at its attestation.
What was checked, and what was not
The EIP-712 digest and signature of AgentWalletSet, and the calls
register, setAgentWallet, giveFeedback and validationResponse,
match those that eth-account 0.13.4 and eth-abi compute from the same
input. A signature wallet made through the binary recovers to its wallet
there. The unit tests in crates/sion-cli/src/erc8004.rs hold those
values. Nothing was sent to a chain, so no deployed registry has accepted
these calls.