SkyhookStart here

Pay-to-Smart-Contract

Pay-to-Smart-Contract (P2SC, sometimes P2S) is a way for any smart contract to accept payments in shielded ZEC and act on them. It is a minimal implementation of Skyhook, the mechanism that verifies shielded Zcash payments on other chains, and it is separate from the Skyhook Bridge: there is no swap, no escrow and no counterparty to find. A P2SC contract simply recognizes that a shielded payment reached it, reads how much was paid, and runs whatever logic its author wrote.

Building on an existing deployment

A P2SC contract doesn’t need its own finality machinery. It connects to an existing Skyhook deployment’s validators and block store, and uses that deployment’s rollups to learn which Zcash blocks are final, in the same way that a contract built on Uniswap v2’s interfaces can trade against an existing Uniswap deployment’s pools instead of creating its own. The P2SC contract adds only the part that is specific to it: what counts as a valid payment, and what happens when one arrives.

Because the finality comes from the shared deployment, a P2SC contract inherits its guarantees, including full FlyClient sampling by default and the option of root-anchored rollups, without its author having to build or audit them.

Static-recipient deposits

The most common form, and the one built and tested so far, fixes the payment’s recipient in the contract. The contract stores a shielded address, as its diversified base g_d and public key pk_d, and treats itself as the counterparty to every payment made to that address:

  1. A user sends shielded ZEC to the contract’s address from any Zcash wallet.
  2. Once the payment’s block is final, anyone submits the proof: the transaction’s inclusion under a finalized root, and the openings of the payment’s note.
  3. The contract checks that the note was paid to its own g_d and pk_d, reads the value v directly from the openings, and checks that the payment hasn’t been counted before.
  4. If v is an amount the contract allows, it runs its logic.
graph TD U["User's wallet"] -->|"shielded ZEC to the contract's address"| Z["Zcash"] Z --> F["Finality from the shared deployment"] F --> C["P2SC contract: recipient = its g_d, pk_d; read v"] C --> A["Mint an NFT, mint wrapped ZEC, unlock access, ..."]

The logic can be anything a contract can do. A contract might mint an NFT for a payment of an exact price, mint wrapped ZEC one-for-one against deposits, sell access or credits, or unlock funds or rights held elsewhere. Because v is read from the payment itself, pricing and limits are enforced by the contract rather than reported by anyone.

Who holds the ZEC

A P2SC contract recognizes payments; it doesn’t hold or spend ZEC. The ZEC goes to the fixed address, and only the holder of that address’s keys can move it on the Zcash side. For many uses that is exactly right: a shop that sells NFTs for ZEC wants the ZEC paid to its own wallet. For a wrapped-ZEC token, it means that redemption depends on whoever controls the address, while deposits need no one’s cooperation, a split of trust described on the comparison page.

Privacy

A P2SC deposit reveals what any Skyhook payment reveals. The depositor, as the sender of a shielded payment, stays private. The recipient’s address is visible, but in P2SC that is the contract’s own address, published deliberately, so nothing about any user is exposed by it. The amount is visible, since the contract reads it to decide what to do. No viewing key is involved at any point.

Relationship to the Skyhook Bridge

The Skyhook Bridge and P2SC use the same verification and the same finality, and differ in what surrounds them. The bridge matches two parties who want to swap, holds one side in escrow, and pays whichever side delivers. P2SC has no second party: the contract is the recipient, and the payment is the whole interaction. P2SC is not part of this grant’s milestones; it is one of the extensions that Skyhook makes possible, and one that already works.

See also