locked proofs
prove_by is prove with two additions: lock the proof to one verifier, and attach metadata. This is the builder chapter.
Chapter 3 had a catch. By default, anyone can verify your proof and close it. Fine for receipts. Bad for anything adversarial, like an escrow or a bet, where a stranger closing your proof early ruins the game. prove_by fixes that.
the verifier lock
When you create a proof with prove_by, you can name a required verifier, one exact address. From then on:
- Only that address, signing the transaction, can verify the proof. Anyone else gets
UnauthorizedVerifier. - The lock can be a program address too. A twin instruction,
verify_by, lets a program be the verifier while a separate payer wallet covers the fees. Receipts for robots. - Expire ignores the lock. After the timer, anyone can still sweep the proof. This is on purpose, so a lost verifier key never traps a deposit on chain.
the metadata field
prove_by can also attach metadata: raw bytes stored inside the proof account after the typed fields. This is why the bigger account sizes from chapter 2 exist. With a required verifier set, about 210 bytes of metadata fit in base, about 650 in standard, and about 2,100 in premium. Metadata that does not fit the chosen size fails with MetadataOverflow.
Two rules about metadata:
- The program never reads it. No parsing, no validation. It's a sticky note, not a contract. Your app gives it meaning.
- It's public and permanent, like everything else on chain. Same rule as chapter 2: hash anything sensitive.
builder recipes
- Escrow check-ins. The user proves a commitment, your program is the locked verifier, and settlement is the verify call.
- Oracle attestations. A bot proves data with metadata describing the feed, locked to your settlement program.
- Sealed-bid anything. Bidders prove hashed bids locked to the auction program. Each reveal is a verify call.