Build real things · ≈ 15 min

Escrow: holding value between strangers

A buyer, a seller, and a contract that will only ever do one of two things with the money.

Escrow is the smallest useful thing two parties who do not trust each other can share. The buyer deposits. Then exactly one of two outcomes happens: the money releases to the seller, or it refunds to the buyer. Never both, never neither-forever, never something else.

The whole design is a state machine, and writing the states down first is most of the work:

NEW ──deposit──▶ FUNDED ──release──▶ RELEASED
                   │
                   └────refund────▶ REFUNDED

RELEASED and REFUNDED are terminal. Once you are in one, nothing can move you out. That single property is what makes escrow safe to use.

The bug to avoid is the second payout. If release does not check the current state, a seller can call it twice and be paid twice — or call it after a refund has already returned the money to the buyer. The contract pays out value it no longer has, and whoever asks last gets nothing.

Guard every transition on the state you are *leaving*, not just on who is calling. "Only the buyer may refund" is not enough; it must also be true that the escrow is currently FUNDED.

The real contracts/examples/escrow adds a dispute path with an arbiter who can resolve in either direction, plus cancel_before_deposit. Same state machine, more edges. Get the two-outcome core right first.

Your turn

Build the escrow core. deposit moves NEW → FUNDED (buyer only). release moves FUNDED → RELEASED (buyer only, pays the seller). refund moves FUNDED → REFUNDED (seller only, returns to the buyer). Both terminal states must reject everything afterwards.

Hints

Stuck? Ask

Answered by Animica's own free inference network. It is donated GPU capacity, so give it 20-30 seconds.