Skip to content

Commit

Permalink
Merge #4238
Browse files Browse the repository at this point in the history
4238: Add V2 script context equivalence test shell scripts r=Jimbo4350 a=Jimbo4350

This pr adds two plutus scripts with accompanying shell scripts:
`scripts/babbage/script-context-equivalance-test.sh`
`scripts/babbage/script-mint-context-equivalance-test.sh`

The plutus scripts test various fields in the `ScriptContext` for equivalence in our redeemer that is created by the `create-script-context` executable (from `plutus-example` in `plutus-apps`). The shell script succeed depending on if the fields in the `ScriptContext` are actually equivalent to what is in our redeemer.


Co-authored-by: Jordan Millar <[email protected]>
  • Loading branch information
iohk-bors[bot] and Jimbo4350 authored Sep 1, 2022
2 parents 7038de9 + 289b7e4 commit b112a60
Show file tree
Hide file tree
Showing 13 changed files with 361 additions and 15 deletions.
2 changes: 2 additions & 0 deletions cardano-api/src/Cardano/Api.hs
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,7 @@ module Cardano.Api (

-- ** Fee calculation
transactionFee,
toLedgerEpochInfo,
estimateTransactionFee,
evaluateTransactionFee,
estimateTransactionKeyWitnessCount,
Expand Down Expand Up @@ -578,6 +579,7 @@ module Cardano.Api (
-- *** Local state query
LocalStateQueryClient(..),
QueryInMode(..),
SystemStart(..),
QueryInEra(..),
QueryInShelleyBasedEra(..),
QueryUTxOFilter(..),
Expand Down
10 changes: 5 additions & 5 deletions cardano-api/src/Cardano/Api/Fees.hs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
-- | Fee calculation
--
module Cardano.Api.Fees (

-- * Transaction fees
transactionFee,
estimateTransactionFee,
Expand All @@ -40,6 +39,7 @@ module Cardano.Api.Fees (

-- * Internal helpers
mapTxScriptWitnesses,
toLedgerEpochInfo,
) where

import Prelude
Expand Down Expand Up @@ -578,10 +578,6 @@ evaluateTransactionExecutionUnits _eraInMode systemstart history pparams utxo tx
of Left err -> Left (TransactionValidityTranslationError err)
Right exmap -> Right (fromLedgerScriptExUnitsMap exmap)

toLedgerEpochInfo :: EraHistory mode -> EpochInfo (Either Text.Text)
toLedgerEpochInfo (EraHistory _ interpreter) =
hoistEpochInfo (first (Text.pack . show) . runExcept) $
Consensus.interpreterToEpochInfo interpreter

toAlonzoCostModelsArray
:: Map AnyPlutusScriptVersion CostModel
Expand Down Expand Up @@ -637,6 +633,10 @@ evaluateTransactionExecutionUnits _eraInMode systemstart history pparams utxo tx
obtainHasFieldConstraint CollateralInAlonzoEra f = f
obtainHasFieldConstraint CollateralInBabbageEra f = f

toLedgerEpochInfo :: EraHistory mode -> EpochInfo (Either Text.Text)
toLedgerEpochInfo (EraHistory _ interpreter) =
hoistEpochInfo (first (Text.pack . show) . runExcept) $
Consensus.interpreterToEpochInfo interpreter

-- ----------------------------------------------------------------------------
-- Transaction balance
Expand Down
2 changes: 0 additions & 2 deletions cardano-cli/src/Cardano/CLI/Shelley/Run/Transaction.hs
Original file line number Diff line number Diff line change
Expand Up @@ -43,10 +43,8 @@ import Ouroboros.Consensus.Shelley.Eras (StandardAllegra, StandardCryp

--TODO: do this nicely via the API too:
import qualified Cardano.Binary as CBOR

--TODO: following import needed for orphan Eq Script instance
import Cardano.Ledger.Shelley.Scripts ()
import Cardano.Ledger.ShelleyMA.TxBody ()

import Cardano.CLI.Environment (EnvSocketError, readEnvSocketPath, renderEnvSocketError)
import Cardano.CLI.Run.Friendly (friendlyTxBS, friendlyTxBodyBS)
Expand Down
3 changes: 1 addition & 2 deletions scripts/babbage/example-babbage-script-usage.sh
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ export UTXO_SKEY="${UTXO_SKEY:-example/utxo-keys/utxo1.skey}"
export RESULT_FILE="${RESULT_FILE:-$WORK/result.out}"

echo "Socket path: $CARDANO_NODE_SOCKET_PATH"
echo "Socket path: $(pwd)"

ls -al "$CARDANO_NODE_SOCKET_PATH"

Expand Down Expand Up @@ -110,7 +109,7 @@ $CARDANO_CLI query utxo --address $plutusspendingscriptaddr --testnet-magic "$TE
plutuslockedutxotxin=$(jq -r 'keys[0]' $WORK/plutusutxo.json)
lovelaceatplutusspendingscriptaddr=$(jq -r ".[\"$plutuslockedutxotxin\"].value.lovelace" $WORK/plutusutxo.json)

#Get read only reference input
# Get read only reference input
$CARDANO_CLI query utxo --address "$readonlyaddress" --cardano-mode \
--testnet-magic "$TESTNET_MAGIC" --out-file $WORK/read-only-ref-input-utxo.json
readonlyrefinput=$(jq -r 'keys[0]' $WORK/read-only-ref-input-utxo.json)
Expand Down
198 changes: 198 additions & 0 deletions scripts/babbage/script-context-equivalance-test.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,198 @@
#!/usr/bin/env bash

# Unofficial bash strict mode.
# See: http://redsymbol.net/articles/unofficial-bash-strict-mode/
set -e
set -o pipefail

export WORK="${WORK:-example/work}"
export BASE="${BASE:-.}"
export CARDANO_CLI="${CARDANO_CLI:-cardano-cli}"
export CARDANO_NODE_SOCKET_PATH="${CARDANO_NODE_SOCKET_PATH:-example/main.sock}"
export TESTNET_MAGIC="${TESTNET_MAGIC:-42}"
export UTXO_VKEY="${UTXO_VKEY:-example/utxo-keys/utxo1.vkey}"
export UTXO_SKEY="${UTXO_SKEY:-example/utxo-keys/utxo1.skey}"
export RESULT_FILE="${RESULT_FILE:-$WORK/result.out}"

mkdir -p "$WORK"

echo "Socket path: $CARDANO_NODE_SOCKET_PATH"

ls -al "$CARDANO_NODE_SOCKET_PATH"

# NB: This plutus script uses a "typed" redeemer and "typed" datum.
plutusscriptinuse="$BASE/scripts/plutus/scripts/v2/context-equivalence-test.plutus"
# This datum hash is the hash of the typed 42
scriptdatumhash="fcaa61fb85676101d9e3398a484674e71c45c3fd41b492682f3b0054f4cf3273"
datumfilepath="$BASE/scripts/plutus/data/typed-42.datum"
redeemerfilepath="$BASE/scripts/plutus/data/script-context.redeemer"
certifyingscript="scripts/plutus/scripts/v2/stake-script.plutus"

# Create certificate
cardano-cli stake-address registration-certificate \
--stake-script-file "$certifyingscript" \
--out-file "$WORK/script.regcert"

# Step 1: Create a tx output with a datum hash at the script address. In order for a tx output to be locked
# by a plutus script, it must have a datahash. We also need collateral tx inputs so we split the utxo
# in order to accommodate this.


plutusscriptaddr=$($CARDANO_CLI address build --payment-script-file "$plutusscriptinuse" --testnet-magic "$TESTNET_MAGIC")
# The input at the readonlyaddress will be used as a reference input
readonlyaddress=addr_test1vz3t3f2kgy2re66tnhgxc4t8jgylw2cqfnxdwlrq9agfmtstxxkm5

mkdir -p "$WORK"

utxoaddr=$($CARDANO_CLI address build --testnet-magic "$TESTNET_MAGIC" --payment-verification-key-file "$UTXO_VKEY")

$CARDANO_CLI query utxo --address "$utxoaddr" --cardano-mode --testnet-magic "$TESTNET_MAGIC" --out-file $WORK/utxo-1.json
cat $WORK/utxo-1.json

txin=$(jq -r 'keys[]' $WORK/utxo-1.json)
lovelaceattxin=$(jq -r ".[\"$txin\"].value.lovelace" $WORK/utxo-1.json)
lovelaceattxindiv6=$(expr $lovelaceattxin / 6)

$CARDANO_CLI query protocol-parameters --testnet-magic "$TESTNET_MAGIC" --out-file $WORK/pparams.json

$CARDANO_CLI transaction build \
--babbage-era \
--cardano-mode \
--testnet-magic "$TESTNET_MAGIC" \
--change-address "$utxoaddr" \
--tx-in "$txin" \
--tx-out "$readonlyaddress+$lovelaceattxindiv6" \
--tx-out "$plutusscriptaddr+$lovelaceattxindiv6" \
--tx-out-datum-hash "$scriptdatumhash" \
--tx-out "$utxoaddr+$lovelaceattxindiv6" \
--protocol-params-file "$WORK/pparams.json" \
--out-file "$WORK/create-datum-output.body"

$CARDANO_CLI transaction sign \
--tx-body-file $WORK/create-datum-output.body \
--testnet-magic "$TESTNET_MAGIC" \
--signing-key-file $UTXO_SKEY \
--out-file $WORK/create-datum-output.tx

# SUBMIT
$CARDANO_CLI transaction submit --tx-file $WORK/create-datum-output.tx --testnet-magic "$TESTNET_MAGIC"
echo "Pausing for 5 seconds..."
sleep 5

# Step 2
# After "locking" the tx output at the script address, we can now can attempt to spend
# the "locked" tx output below.

$CARDANO_CLI query utxo --address $plutusscriptaddr --testnet-magic "$TESTNET_MAGIC" --out-file $WORK/plutusutxo.json

plutusutxotxin=$(jq -r 'keys[]' $WORK/plutusutxo.json)

$CARDANO_CLI query utxo --address $utxoaddr --cardano-mode --testnet-magic "$TESTNET_MAGIC" --out-file $WORK/utxo-2.json
cat $WORK/utxo-2.json
txinCollateral=$(jq -r 'keys[0]' $WORK/utxo-2.json)


dummyaddress=addr_test1vpqgspvmh6m2m5pwangvdg499srfzre2dd96qq57nlnw6yctpasy4

lovelaceatplutusscriptaddr=$(jq -r ".[\"$plutusutxotxin\"].value.lovelace" $WORK/plutusutxo.json)

# Get read only reference input
$CARDANO_CLI query utxo --address "$readonlyaddress" --cardano-mode \
--testnet-magic "$TESTNET_MAGIC" --out-file $WORK/read-only-ref-input-utxo.json
readonlyrefinput=$(jq -r 'keys[0]' $WORK/read-only-ref-input-utxo.json)



# We need to generate a dummy redeemer (the cli demands a redeemer) in order to create a txbody from which we can generate
# a tx and then derive the correct redeemer.
create-script-context --plutus-v2 --out-file "$WORK/script-context.redeemer"

correctredeemer="$WORK/script-context.redeemer"

echo "Constructing dummy tx..."

# Create dummy certificate
certifyingscript="scripts/plutus/scripts/v2/stake-script.plutus"
cardano-cli stake-address registration-certificate \
--stake-script-file "$certifyingscript" \
--out-file "$WORK/script.regcert"

requiredsignerhash=$(cardano-cli address key-hash --payment-verification-key-file ${UTXO_VKEY})

# DUMMY TX! We generate the actual redeemer from this!
# --certificate-file "$WORK/script.regcert" \
redeemerfilepath="$BASE/scripts/plutus/data/42.redeemer"
$CARDANO_CLI transaction build \
--babbage-era \
--cardano-mode \
--testnet-magic "$TESTNET_MAGIC" \
--script-invalid \
--change-address "$utxoaddr" \
--invalid-before 1 \
--invalid-hereafter 400 \
--certificate-file "$WORK/script.regcert" \
--read-only-tx-in-reference "$readonlyrefinput" \
--tx-in "$plutusutxotxin" \
--tx-in-collateral "$txinCollateral" \
--tx-out "$dummyaddress+10000000" \
--tx-in-script-file "$plutusscriptinuse" \
--tx-in-datum-file "$datumfilepath" \
--protocol-params-file "$WORK/pparams.json" \
--tx-in-redeemer-file "$redeemerfilepath" \
--required-signer-hash "$requiredsignerhash" \
--out-file $WORK/test-alonzo.body

$CARDANO_CLI transaction sign \
--tx-body-file $WORK/test-alonzo.body \
--testnet-magic "$TESTNET_MAGIC" \
--signing-key-file "${UTXO_SKEY}" \
--out-file $WORK/test-alonzo.tx

# Generate the "real" redeeemer!

create-script-context \
--generate-tx "$WORK/test-alonzo.tx" \
--plutus-v2 \
--out-file "$WORK/script-context.redeemer" \
--cardano-mode \
--testnet-magic 42 \

echo "Constructing real tx..."
# REAL TX!

$CARDANO_CLI transaction build \
--babbage-era \
--cardano-mode \
--testnet-magic "$TESTNET_MAGIC" \
--script-valid \
--invalid-before 1 \
--invalid-hereafter 400 \
--change-address "$utxoaddr" \
--certificate-file "$WORK/script.regcert" \
--read-only-tx-in-reference "$readonlyrefinput" \
--tx-in "$plutusutxotxin" \
--tx-in-collateral "$txinCollateral" \
--tx-out "$dummyaddress+10000000" \
--tx-in-script-file "$plutusscriptinuse" \
--tx-in-datum-file "$datumfilepath" \
--protocol-params-file "$WORK/pparams.json" \
--tx-in-redeemer-file "$correctredeemer" \
--required-signer-hash "$requiredsignerhash" \
--out-file $WORK/test-alonzo-final.body

$CARDANO_CLI transaction sign \
--tx-body-file $WORK/test-alonzo-final.body \
--testnet-magic "$TESTNET_MAGIC" \
--signing-key-file "${UTXO_SKEY}" \
--out-file $WORK/alonzo.tx

# SUBMIT $WORK/alonzo.tx containing the correct redeemer

echo "Submit the tx with plutus script and wait 5 seconds..."
$CARDANO_CLI transaction submit --tx-file $WORK/alonzo.tx --testnet-magic "$TESTNET_MAGIC"
sleep 5
echo ""
echo "Querying UTxO at $dummyaddress. If there is ADA at the address the Plutus script successfully executed!"
echo ""
$CARDANO_CLI query utxo --address "$dummyaddress" --testnet-magic "$TESTNET_MAGIC" \
| tee "$RESULT_FILE"
Loading

0 comments on commit b112a60

Please sign in to comment.