3

I am trying to figure out how to write a script where you can make sure the datum value doesn't change each time an output gets consumed. For example, in the auction script in the pioneer program each step along the way someone wants to consume a previous output to up the bid. Suppose you wanted to store some meta deta in the datum and have it carried on the block chain, like a secondary beneficiary, imagine an auction house fee that gets set when the action is created.

Each end point supplies the the datum to be set as the output of the transaction. The endpoint code runs off chain. So it seems that there is no way to set a static datum value, especially for any script which allows the public to access, like an auction.

Is my understanding correct and this is just a limitation of the cardano smart contract?

Thank you in advance

2
  • I have a very similar question that could be answered by answering your question. I would be keen to see an answer to your question.
    – FTM
    Jan 14, 2022 at 7:02
  • 1
    In the on-chain validator script, you can inspect the transaction outputs through the ScriptContext. An output has a datum hash field available. You can then assert that the hash is equal to the hash of the input datum. Ref: playground.plutus.iohkdev.io/doc/haddock/plutus-ledger-api/html/… Jan 14, 2022 at 14:11

1 Answer 1

2

There are multiple ways to do that.

Option 1:

If you have "script-wide" constants, like your mentioned example of an auction house fee, I suggest parameterizing your contract like it is done in Lecture #3 instead of storing that value in each output's datum.

Option 2:

If you really want to ensure some or all of the datum fields are recreated when it is consumed you can do that too. By default for any spending transaction from a script, Plutus expects you to provide the datum value/file whose hash matches the one stored on-chain for the UTxO you're trying to spend in your transaction.

Your validator can check for an output recreated at its own address with a certain value and datum. If the datum shall be the exact same as previously you can simply check if the hash of the newly created output equals the one you're consuming.

Otherwise, you can also provide the datum (not the hash) of the newly created output in the transaction and validate it within the script. You can do that via the CLI by using:

--tx-out ADDRESS VALUE
[--tx-out-datum-embed-file FILE | --tx-out-datum-embed-value JSON VALUE]

or using CSL:

[...]
TransactionOutputBuilder.new()
    .with_address(yourScriptAddress)
    .with_data_hash(hashOfYourNewDatum) // does not include the datum value
    .next()
    .with_value(Value.new(someOutputValueOrMinADA))
    .build()

// Adding transaction datum values
// Must at least include a datum value for every script output that is being 
// spent + optionally any additional datums necessary for the script validation
const datums = PlutusList.new();
datums.add(datumBuilder(1));
datums.add(datumBuilder(2));

const transactionWitnessSet = TransactionWitnessSet.new();
transactionWitnessSet.set_plutus_data(datums);
[...]

export const datumBuilder(n: number): PlutusData {
    const fields = PlutusList.new();
      fields.add(PlutusData.new_integer(BigInt.from_str(`${n}`)));
      return PlutusData.new_constr_plutus_data(
          ConstrPlutusData.new(
            BigNum.from_str('0'),
            fields
          )
        );
}

Once, you've added the datum value of the newly created script output to the transaction you can retrieve it in your Plutus code like similarly to any other datum:

[...]
where
    -- returns new outputs of this script
    ownOutputs :: [TxOut]
    ownOutputs = getContinuingOutputs ctx

    -- returns Datum value for a tx output if it is provided
    outputDatum :: TxOut -> Maybe Datum
    outputDatum o = txOutDatumHash o >>= flip findDatum info

Related answers to that topic:

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.