Skip to main content

token_pool_output_only_extra_sighash_data

Function token_pool_output_only_extra_sighash_data 

Source
pub fn token_pool_output_only_extra_sighash_data(
    action_type: TokenTransitionActionType,
    token_id: &[u8; 32],
    owner_id: &[u8; 32],
    platform_version: &PlatformVersion,
) -> Result<Vec<u8>, ProtocolError>
Expand description

Extra sighash data of an outputs-only token pool bundle — TokenShield, TokenMintToPool, TokenClaimToPool and TokenDirectPurchaseToPool: the bundle’s domain tag, the token id and the identity the bundle is attributed to.

These bundles have no spends, so nothing pins them to a pool: their anchor is never checked against one — the client builds it against the empty tree — and the proof and binding signature verify against any pool. Without this data the authorized bundle bytes are a free-standing, self-verifying object that anybody can lift out of the mempool into a transition of their own. Each of the three fields closes one direction of that:

  • The token id keeps a bundle out of every other token’s pool. That pool has its own nullifier tree, so a copy there would leave both notes spendable; the harm is that the recipient would hold notes derived from one rho in two pools, which links their spends across pools.
  • The tag keeps the kinds’ preimages disjoint in the same pool. Bundles of different kinds are otherwise indistinguishable to the proof — same flags, same empty-tree anchor, and the same value balance whenever the amounts match. A same-pool reuse is also caught by the nullifier record described below.
  • The owner keeps it out of every other identity’s transition of the same kind into the same pool. Without it a copier could take a bundle from the mempool and land it ahead of its author, funding the notes the author built with its own tokens, credits or claim, or minting them with its own authority. The author’s own transition would then be refused on its recorded dummy nullifier and charged its fee.

owner_id is the batch owner, except for a group action mint, where it is the group action’s proposer: a group action pins the digest of the bundle’s actions, so every other signer submits the proposer’s bundle unchanged and the preimage must not depend on whose batch carries it. TokenShield, TokenClaimToPool and TokenDirectPurchaseToPool are never group actions.

The preimage does not stop the owner from submitting its own bundle twice. That, and any other repeat of a bundle into the same pool, consensus refuses on the state side: every token pool write that takes an outputs-only bundle records the bundle’s dummy nullifiers in the pool’s nullifier tree, and a bundle whose dummy nullifier is already there is refused with NullifierAlreadySpentError. A repeat that got through would land a second note with the same commitment and the same rho, hence the same nullifier, of which only one could ever be spent.