Anchoring
Batch receipts into a Merkle tree and publish the root on Robinhood Chain.
Prove / anchoring
Anchoring gives a batch of receipts a public timestamp on Robinhood Chain. It needs a funded signer in PROVN_ANCHOR_KEY. A deployment without one still seals and publishes batches, and reports them as unanchored.
The tree
- Leaf: SHA-256 of the receipt payload bytes.
- Parent: SHA-256 of the left child's bytes followed by the right child's.
- Odd count: the last node moves up a level unchanged.
import { createHash } from "node:crypto";
const sha256 = (b: Buffer) => createHash("sha256").update(b).digest();
export function merkleRoot(payloads: Buffer[]): Buffer {
let level = payloads.map(sha256);
while (level.length > 1) {
const next: Buffer[] = [];
for (let i = 0; i < level.length; i += 2) {
next.push(i + 1 < level.length ? sha256(Buffer.concat([level[i], level[i + 1]])) : level[i]);
}
level = next;
}
return level[0];
}The transaction
Provn sends a 0-value transaction whose calldata is a 6-byte tag followed by the 32-byte root.
0x50524f564e01 + <32-byte root>
50 52 4f 56 4e "PROVN"
01 format versionFetch the transaction from the public RPC and read its input. It starts with 0x50524f564e01, and the 64 hex characters after that are the root.
curl https://rpc.mainnet.chain.robinhood.com \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","id":1,"method":"eth_getTransactionByHash","params":["0xANCHOR_TX_HASH"]}'Inclusion proofs
GET /v1/receipts/:id/proof returns the Merkle path for a receipt and the anchor status of its batch. Hash the receipt payload, combine it with each step of the path, and compare the result with the root in the transaction. GET /v1/anchors lists batches.
curl https://YOUR-PROVN-HOST/v1/receipts/req_4tQ8.../proof
curl https://YOUR-PROVN-HOST/v1/anchorsWhat an anchor shows
- The receipt existed in this exact form no later than the block that holds the root.
- Provn can't swap in a different receipt without changing the root.
What it does not show
- Anything about the answer or the upstream host that the receipt itself doesn't show.
- Any timestamp for a batch marked
unanchored. That batch has a root but no transaction on chain.