Skip to content

Latest commit

 

History

History
537 lines (340 loc) · 22 KB

02-plutus-protocol.md

File metadata and controls

537 lines (340 loc) · 22 KB

COOP Plutus protocol

This document contains information about all the wallets, tokens, minting policies, validators and transactions used in COOP and their relationship.

Protocol parameters

Parameters set at Protocol genesis.

Total quantity of $AA tokens to mint. These tokens can be distributed to any number of Authentication Authority wallets to provide:

  1. Backup and redundancy in case of loss,
  2. Multi-signature scheme for minting authentication tokens.

Required quantity of $AA tokens that must be consumed when minting authentication tokens. These tokens can be in one or many inputs, enabling multi-signature scheme to be adopted.

To following is instantiated by God:

  1. @FsV validator script,
  2. @CertV validator script,
  3. $CERT-policy minting policy script,
  4. $AUTH-policy minting policy script,
  5. $FS-policy minting policy script.

Protocol state

To understand the state of the Protocol it's sufficient to query the UTxOs at:

  1. @CertV validator that holds the non-garbage-collected certificates,
  2. @FsV validator that holds the non-garbage-collected fact statements.

TODO: Add a relational schema to convey the state structure and semantics.

Scripts invoked:

Signatories:

Scenario:

God mints $AA tokens and sends them to a single Authentication Authority.

graph TD
    GodWallet["God wallet"]
    AaWallet["Authentication Authority wallet"]
    AaMp[("$AA-policy")]
    MintAaTx{"mint-aa-tx quantity oref"}

    GodWallet ---> |"oref output"|MintAaTx

    AaMp ---> |"$AA/hash(oref) x quantity"|MintAaTx
    MintAaTx ---> |"$AA/hash(oref) x quantity"|AaWallet
Loading

The TokenName of the $AA token is set to a hash of the input pointed to by oref (see Hashing inputs for uniqueness).

Scripts invoked:

Signatories:

Scenario:

Bob and Alice are Authentication Authority and they mint authentication by minting a $CERT token and paying it to the @CertV validator, and minting $AUTH x quantity tokens and paying them to a single Authenticator.

graph TD
    AuthMp[("$AUTH-policy")]
    CertMp[("$CERT-policy")]
    CertV["@CertV validator"]
    AuthWallet["Authenticator wallet"]
    AaWalletBob["Authentication Authority wallet - Bob"]
    AaWalletAlice["Authentication Authority wallet - Alice"]

    MintAuthTx{"mint-authentication-tx validity quantity $CERT-RDMR"}

    AaWalletBob -->|$AA x 1|MintAuthTx
    AaWalletAlice -->|$AA x 1|MintAuthTx
    MintAuthTx -->|$AA x 1|AaWalletBob
    MintAuthTx -->|$AA x 1|AaWalletAlice

    CertMp -->|"$CERT/id x 1"|MintAuthTx
    MintAuthTx -->|"$CERT/id x 1 + CertDatum(id, validity, $CERT-RDMR)"|CertV

    AuthMp -->|"$AUTH/id x quantity"|MintAuthTx
    MintAuthTx -->|$AUTH/id x quantity|AuthWallet
Loading

id is computed by hashing $AA inputs consumed (see Hashing inputs for uniqueness).

The quantity of $AA tokens required is determined by the Required Authentication Authority tokens protocol parameter.

Scripts invoked:

Signatories:

Scenario:

Submitter publishes two Fact Statements, namely fsA and fsB, within a single transaction. Authenticator provides $AUTH tokens for each of the published Fact Statement and adds a $FEE that will be paid by the Submitter to the Fee Collector. The Fact Statements are made available as UTxOs at the @FsV validator for future referencing in ref-fact-statement-tx transactions.

graph TD
    FsMp[("FS-policy")]
    AuthMp[("$AUTH-policy")]
    FsV["@FsV validator"]
    AuthWallet["Authenticator wallet"]
    CertV["@CertV validator"]
    FeeCollector["$FEE collector"]

    MintFactTx{"mint-fact-statement-tx [fsA, fsB]"}

    CertV -.->|"$CERT/authId x 1 + CertDatum(authId, validity, _)"|MintFactTx

    AuthWallet -->|"$AUTH/authId x N"|MintFactTx
    AuthWallet -->|"$AUTH/authId x M"|MintFactTx
    MintFactTx -->|"$AUTH/authId x 2"|AuthMp
    MintFactTx -->|"$AUTH/authId x (N-1)"|AuthWallet
    MintFactTx -->|"$AUTH/authId x (M-1)"|AuthWallet
    
    FsMp -->|"$FS/fsId1 x 1"|MintFactTx
    FsMp -->|"$FS/fsId2 x 1"|MintFactTx
    MintFactTx -->|"$FS/fsId1 x 1 + fsA"|FsV
    MintFactTx -->|"$FS/fsId2 x 1 + fsB"|FsV

    SubmitterWallet -->|"$FEE x feeQuantity"|MintFactTx
    MintFactTx -->|"$FEE x feeQuantity"|FeeCollector
Loading

fsA and fsB transaction parameters are isomorphic to FsDatum in that they contain a Fact Statement, along with its unique Fact Statement ID as provided by the Oracle's Fact Statement Store, the validity information and the Submitter public key hash. The fsId1 and fsId2 are computed by hashing corresponding $AUTH inputs used to authenticate each produced Fact Statement (see Hashing inputs for uniqueness).

Each $AUTH used must be valid, and the validity is asserted by checking the referenced @CertV UTxO.

Scripts invoked:

Signatories:

Scenario:

Certificate redeemer garbage collects obsolete certificates from @CertV validator and reclaims the Min UTxO Ada held within. CertDatum indicates which $CERT-RDMR token must be spend in order to garbage collect an obsolete certificate.

graph TD
    CertMp[("$CERT-policy")]
    CertV["@CertV validator"]
    CertRdmrWallet["Certificate redeemer wallet"]

    GcCertTx{"gc-certificate-tx"}


    CertV -->|"$CERT/id1 x 1 <> $ADA x minUtxo + CertDatum(id1, validity, $CERT-RDMR)"|GcCertTx
    GcCertTx -->|"$CERT/id1 x 1"|CertMp
    CertV -->|"$CERT/id2 x 1 <> $ADA x minUtxo + CertDatum(id2, validity, $CERT-RDMR)"|GcCertTx
    GcCertTx -->|"$CERT/id2 x 1"|CertMp

    CertRdmrWallet -->|"$CERT-RDMR x n"|GcCertTx
    GcCertTx -->|"$CERT-RDMR x n <> $ADA x minUtxo x 2"|CertRdmrWallet
Loading

$CERT-RDMR tokens are sent back to the Certificate redeemer and all obsolete $CERT tokens are burned.

Scripts invoked:

Signatories:

Scenario:

The original Submitter of the mint-fact-statement-tx transaction, as indicated in the FsDatum, garbage collects the obsolete Fact Statement UTxOs available at @FsV.

graph TD
    FsMp[("$FS-policy")]
    FsV["@FsV validator"]
    SubmitterWallet["Submitter"]

    GcFsTx{"gc-fact-statement-tx"}


    FsV -->|"$FS/id1 x 1 <> $ADA x minUtxo + FsDatum(id1, validity1, submitter)"|GcFsTx
    FsV -->|"$FS/id2 x 1 <> $ADA x minUtxo + FsDatum(id2, validity2, submitter)"|GcFsTx

    SubmitterWallet -->|"signature"|GcFsTx

    GcFsTx -->|"$FS/id1 x 1 <> $FS/id1 x 1"|FsMp
    GcFsTx -->|"$ADA x minUtxo x 2"|SubmitterWallet
Loading

Scripts invoked:

Signatories:

Scenario:

User unlocks a reward by referencing two Fact Statements, namely fsA and fsB, and consumes a reward input from the Consumer script that they pay to themselves.

graph TD
    FsV["@FsV validator"]
    ConsumerV["Consumer script"]
    UserWallet["User"]
    RefFsTx{"ref-fact-statement-tx"}


    FsV -.->|"$FS/id1 x 1 + fsA"|RefFsTx
    FsV -.->|"$FS/id2 x 1 + fsB"|RefFsTx
    ConsumerV -->|"$REWARD"|RefFsTx

    RefFsTx -->|"$REWARD"|UserWallet
Loading

The Consumer script must check that the referenced @FsV validator inputs containing Fact Statements have the expected $FS CurrencySymbol.

Self managed token, the Protocol Design doesn't enforce how these tokens are obtained. For convenience, the implementation enables Protocol Operators to mint 'One Shot' tokens to be used as $CERT-RMDR tokens.

These tokens are used in gc-certificate-tx transactions to authenticate garbage collection of obsolete certificates.

This token is used by COOP Consumers to authenticate the Fact Statement reference inputs.

Any token the Protocol Operator wishes to use as a 'fee', which includes but is not exclusive to $ADA.

These tokens are spent from Submitter wallets and paid to the Fee Collector in mint-fact-statement-tx transactions.

$AA minting policy script.

Script is defined in Coop.Plutus.Aux.mkOneShotMp and is instantiated at Protocol genesis with the following parameters:

  • quantity denotes the [total amount of $AA tokens to mint](#total-aa-tokens),
  • tokenName is set to a hash of the of the 'oref' output,
  • oref the output owned by the God wallet that must be consumed in order to validate minting.

Participates in transactions:

Script is invoked only once at Protocol genesis.

$CERT minting policy script.

Script is defined in Coop.Plutus.mkCertMp and is instantiated at Protocol genesis with the Coop.Types.CertMpParams parameter.

Participates in transactions:

Script is invoked throughout the Protocol lifetime.

$AUTH minting policy script.

Script is defined in Coop.Plutus.mkAuthMp and is instantiated at Protocol genesis with the Coop.Types.AuthMpParams parameter.

Participates in transactions:

Scripts is invoked throughout the Protocol lifetime.

$FS minting policy script.

Script is defined in Coop.Plutus.mkFsMp and is instantiated at Protocol genesis with the Coop.Types.FsMpParams parameter.

Participates in transactions:

Script is invoked throughout the Protocol lifetime.

Script is defined in Coop.Plutus.certV and is instantiated at Protocol genesis.

Validator guarding Certificate UTxOs that contain:

  1. Coop.Types.CertDatum datum,
  2. $CERT token.

Participates in transactions:

Script is invoked throughout the Protocol lifetime.

Script is defined in Coop.Plutus.fsV and is instantiated at Protocol genesis.

Validator guarding Fact Statement UTxOs that contain:

  1. Coop.Types.FsDatum datum,
  2. $FS token.

Participates in transactions:

Script is invoked throughout the Protocol lifetime.

Any script that references COOP Fact Statement UTxOs.

A wallet used to initialize the protocol (ie. Protocol genesis). Can be discarded after use.

Authentication Authority wallets holding $AA tokens used to authenticate minting ephemeral authentication tokens. Note that there can be any number of such wallets and it's left to the Protocol Operator to manage their distribution.

Must be held in a safe environment as compromising $AA wallets can undermine the entire protocol.

Authenticator wallets hold the $AUTH ephemeral tokens that are attached to each Fact Statement minting transaction to denote 'authentication' by the Publisher.

Authenticators are used extensively by the Fact Statement publishing backend and as such should be kept safe. However, unlike the Authentication Authority wallets, if compromised these wallets only impact the integrity of the Protocol for the duration of $AUTH tokens held within. After that point compromised wallets can be discarded and replaced with fresh ones, which would then receive new $AUTH tokens.

Protocol Operators manage how many $AUTH tokens are minted, how long they are valid and which Authenticator wallets will receive them.

Submitter is a wallet used by the user that submits the Fact Statement minting transactions transaction obtained in the Fact Statement Publishing protocol.

The wallet needs to provide enough $FEE tokens as indicated in the Fact Statement Publishing protocol.

Certificate redeemer wallets hold the $CERT-RDMR tokens and are managed by the Protocol Operator similar to how Authenticator wallets are managed. In fact, both wallets can be consolidated in a single wallet for convenience.

Certificate redeemer wallets are in charge of garbage collecting obsolete certificates by providing the corresponding $CERT-RDMR tokens as indicated in the CertDatum.

Fee collector is any wallet or validator the Protocol Operator decides to use to collect $FEE tokens in Fact Statement minting transactions.

Appendix

Transaction diagrams are specified using the Mermaid Sequence Diagrams.

Sequence diagram element description:

  • Rectangle - Something with an Address (Validator or Wallet),
  • Pool - A minting policy,
  • Diamond - Transaction (sometimes with parameters),
  • Line
    • Consumes TxOut if going from an Address (Rectangle),
    • Mints a value if going from a Minting Policy (Pool),
    • Burns a value if going to a Minting Policy (Pool),
    • Provides a signature if going from a Wallet
  • Dotted - references TxOut

Textual notation used

Values

A Token is a tuple of CurrencySymbol and TokenName (also knows as AssetClass).

Value --> Token x Quantity [<> Token x Quantity]
Token --> $CurrencySymbol/TokenName | $CurrencySymbol
CurrencySymbol --> <all caps with dashes>
TokenName --> <any>

For brevity the TokenName can be ommitted when appropriate.

Examples:

  • $ADA x 1
  • $ADA x q
  • $FOO x 1
  • $FOO/bar x q <> $ADA x minUtxoAda
Inputs and outputs
IO --> Value + Datum
Datum --> <some record/product notation>

Examples:

  • $FOO/bar x q <> $ADA x minUtxoAda + MyDatum(foo=1, bar=2)
Transaction
Transaction --> TransactionName [Parameters]
Parameters --> Parameter [Parameters]
TransactionName --> <lowercase with dashes>
Parameter --> <camelCase>

Examples:

  • mint-sometokens-tx quantity tokenName
  • always-validates-tx

Here we specify the procedure used by COOP to create unique identifiers on-chain. Once created these are used as TokenName and various identifiers.

The procedure takes in a list of output references and returns a unique bytestring:

  1. Given a list of output references denoted as orefs :: [(TxId, Int)],
  2. Order orefs to create sortedOrefs :: [(TxId, Int)],
  3. Convert TxId and OutputIndex in sortedOrefs to a bytestring format to create sortedOrefsB :: [(ByteString, ByteString)],
  4. Convert sortedOrefsB to a bytestring format by concatenating all the elements to create normalized :: Bytestring,
  5. Hash that normalized bytestring with Blake2b_256 to create unique :: ByteString,
  6. Return unique bytestring.

This procedure is implemented in Coop.Pab.Aux.hashTxInputs function used off-chain, and Coop.Plutus.Aux.hashTxInputs function used on-chain.

References