Skip to main content
Attestcoin is the trust root of Orru. It is how Creditcoin learns that a payment happened on Ethereum without taking anyone’s word for it, ours included. Every statement Orru issues, and every credit draw against one, depends on an attestation that this page describes end to end.
Etherscan finds it. Attestcoin proves it. Creditcoin never takes anyone’s word.

The pieces

What Attestcoin establishes, and what it does not

The precompile authenticates that a transaction was included in an attested Ethereum block and returns its receipt. That is all. It does not check that the transaction succeeded, and it does not interpret the receipt. Both are the application’s job, and both are done in AttestationRegistry. For Demo Payroll the authenticated receipt contains an ERC-20 transfer, so Attestcoin proves the payment itself. For Semuni, an off-chain payer, the receipt contains the payer’s anchored commitment, so Attestcoin proves that the approved payer attested to the payment. It does not prove that a bank transfer settled. The statement records which payer the evidence came from, so a verifier can apply its own policy to each.

On-chain: the consumer contract

contracts/src/attestcoin/USCBase.sol is the adapter around the verifier interface. Its execute function is permissionless, because the proof is the authorization:
  1. computes a query id from (chainKey, blockHeight, txIndex) and refuses one already processed, so a source transaction is consumed once;
  2. calls the native query verifier with the encoded transaction, Merkle root, siblings, lower endpoint digest and continuity roots;
  3. only if that returns true, hands the receipt to _processAndEmitEvent.
contracts/src/creditcoin/AttestationRegistry.sol overrides _processAndEmitEvent and adds the five checks the precompile deliberately leaves out: Receipts are bounded to 256 matching logs. Every surviving log records the earliest authenticated Ethereum height in provenAtHeight[commitment][payer], marks acceptedByPayer[commitment][payer], and emits CommitmentAccepted(commitment, payer, queryId, blockHeight). Acceptance is idempotent so a repeated commitment cannot strand the others in the same receipt. A receipt with no accepted log reverts NoTrustedLogs. Each of these rules has a negative test in contracts/test.

Composed with the zero-knowledge proof

Attestcoin proves a commitment was anchored. A Noir proof, built in the user’s browser, shows that the amounts behind three commitments fall in one income band. The two are joined in CredentialRegistry.issue:
The same bytes32 is checked on both sides. That binding is the security: requiring two unrelated facts would not be composition. The newest provenAtHeight across the three becomes the statement’s evidenceEndHeight, and DemoCreditPool refuses to disburse below its minimumEvidenceHeight (EvidenceTooOld). A credit decision cannot happen without an attestation.

Off-chain: the worker

worker/src/attest.ts carries anchored payments from Ethereum to Creditcoin with the official SDK. Discovery uses Etherscan and is trusted for nothing; a found payment is only a candidate until the precompile accepts it.
  1. Scan Sepolia for PaymentAnchored events with a checkpoint journal that walks ancestors on a reorg and never advances past a mismatch.
  2. Keep only anchors whose payer is approved on the registry (an allowlist first, then a cached on-chain lookup, bounded per pass).
  3. Wait until Attestcoin covers anchor block + 10 (WORKER_ATTEST_LOOKAHEAD), read through PrecompileChainInfoProvider and the proof builder’s /api/v1/attested-height/1.
  4. Fetch the proof bundle from proofProvider.service.ProofBuilder and submit execute from the relayer key.
  5. Read back acceptedByPayer for every (commitment, payer) pair before recording the anchor as done; a submitted transaction is not the same as an accepted commitment.
It runs unattended every five minutes in .github/workflows/attest-cron.yml, oldest first, fifteen anchors per pass, because verification cost rises with event age.

In the product

The demo faucet page reads Attestcoin’s own state so a tester can watch it work: get_latest_attestation_height_and_hash(1) from the chain-info precompile and the proof builder’s attested height, whichever is lower, against the block the claim needs. The four stages it shows are real: sent to Ethereum, Ethereum confirmed, Attestcoin covered, Creditcoin accepted. Review and statement screens read acceptedByPayer for the exact pairs, never a cache of what was submitted.

Limits, stated plainly

  • Attestcoin reads Ethereum only. Payments on other chains reach Orru only by a payer anchoring a commitment on Ethereum.
  • It trails Ethereum by roughly seven minutes, and the relay adds up to five, so a fresh anchor takes ten to fifteen minutes to become provable.
  • Verification cost grows with event age, about tenfold after a day. The worker processes fresh events first.
  • Inclusion is not success, and an anchor is the payer’s word. The contract handles the first; the statement discloses the second by naming the payer.
  • The write layer (Creditcoin to Ethereum) is not live in this window. The receiver design, an adapter between the Inbox and the application with the emitter validated against a trusted set, is written down and not depended on.

See it on-chain

One complete run, made on 12 September 2026 by a fresh wallet through the demo faucet: The earlier Semuni batch on this page’s sibling, Two payer models, went the same way: anchor 0xfd96eaf3…df1cbf, attestation 0x49743077…83e5fd0, statement 0xb5f78f3d…902d4ab. Check an acceptance yourself, with one of that batch’s public commitments:
The registry has processed more than sixty attestation transactions since it was deployed. The full list is on Blockscout.