Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Move plutus-example from cardano-node to plutus-apps #322

Merged
merged 11 commits into from
Mar 1, 2022
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ node.sock
**/node?/db
.pre-commit-config.yaml
secrets/*/.gpg-id
generated-plutus-scripts/
ghcid.txt
plutus-pab/test-node/testnet/db
plutus-pab/test-node/testnet/restore-wallet.json
Expand Down
27 changes: 27 additions & 0 deletions cabal.project
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ packages: doc
plutus-chain-index
plutus-chain-index-core
plutus-contract
plutus-example
plutus-ledger
plutus-ledger-constraints
plutus-pab
Expand All @@ -16,6 +17,7 @@ packages: doc
quickcheck-dynamic
web-ghc


-- We never, ever, want this.
write-ghc-environment-files: never

Expand Down Expand Up @@ -71,6 +73,9 @@ source-repository-package
iohk-monitoring
tracer-transformers
plugins/backend-ekg
plugins/backend-aggregation
plugins/backend-monitoring
plugins/backend-trace-forwarder

-- Direct dependency.
source-repository-package
Expand Down Expand Up @@ -134,6 +139,28 @@ source-repository-package
tag: 814df2c146f5d56f8c35a681fe75e85b905aed5d
subdir:
cardano-api
cardano-cli
cardano-node
cardano-testnet

source-repository-package
type: git
location: https://github.com/input-output-hk/cardano-config
tag: e9de7a2cf70796f6ff26eac9f9540184ded0e4e6
--sha256: 1wm1c99r5zvz22pdl8nhkp13falvqmj8dgkm8fxskwa9ydqz01ld

-- Using a fork until our patches can be merged upstream
source-repository-package
type: git
location: https://github.com/input-output-hk/optparse-applicative
tag: 7497a29cb998721a9068d5725d49461f2bba0e7a
--sha256: 1gvsrg925vynwgqwplgjmp53vj953qyh3wbdf34pw21c8r47w35r

source-repository-package
type: git
location: https://github.com/input-output-hk/hedgehog-extras
tag: edf6945007177a638fbeb8802397f3a6f4e47c14
--sha256: 0wc7qzkc7j4ns2rz562h6qrx2f8xyq7yjcb7zidnj7f6j0pcd0i9

-- Should follow cardano-wallet.
source-repository-package
Expand Down
1 change: 1 addition & 0 deletions doc/plutus/howtos/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,4 @@ How-to guides
handling-blockchain-events
analysing-scripts
profiling-scripts
plutus-spending-script-example
174 changes: 174 additions & 0 deletions doc/plutus/howtos/plutus-spending-script-example.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,174 @@
Plutus Scripts
==============

What is a Plutus spending script?
---------------------------------

This is a type of Plutus script that is required to validate the
spending of a tx output at its own script address. The tx output at the
Plutus script address *must* be associated with a datum hash, otherwise,
the tx output will be unspendable! The purpose of this datum hash is to
encode the state of the contract. A demonstration of this can be seen in
`lecture #7 <https://youtu.be/oJupInqvJUI>`__ of the Plutus Pioneers
Program. The Plutus spending script expects a datum and a redeemer in
order to successfully validate the spending of the tx output at its own
script address; note that the redeemer is considered to be the user
input. These are supplied in the transaction being submitted along with
the Plutus script itself and specified transaction execution units.

The transaction execution units are an upper bound or budget of what
will be spent to execute the Plutus script. If you don’t specify a high
enough value to cover script execution, your transaction will still be
successful (provided it is a valid tx) but you will lose your
collateral. The collateral is the transaction input(s) you specify to be
consumed if your script fails to execute. There is a protocol parameter
``collateralPercent`` that determines what percentage of your inputs you
must supply as collateral.

*Note that in order to use a tx input as collateral,
it*\ **cannot**\ *reside at a script address; it must reside at a
‘normal’ payment address and it cannot contain any multi-assets.*

NB: All variable assignments can be looked up in `cardano-node/scripts/plutus/example-txin-locking-plutus-script.sh <(https://github.com/input-output-hk/cardano-node/blob/master/scripts/plutus/example-txin-locking-plutus-script.sh>`_

An example of using a Plutus spending script
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Below is an example that shows how to use a Plutus spending script. This
is a step-by-step process involving:

- the creation of the ``AlwaysSucceeds`` Plutus txin script
- sending ADA to the Plutus script address
- spending ADA at the Plutus script address

In this example we will use the
`AlwaysSucceeds <../plutus-example/plutus-example/src/Cardano/PlutusExample/AlwaysSucceeds.hs>`__
Plutus spending script. In order to execute a Plutus spending script, we
require the following:

- Collateral tx input(s) - these are provided and are forfeited in the
event the Plutus script fails to execute.
- A Plutus tx output with accompanying datum hash. This is the tx
output that sits at the Plutus script address. It must have a datum
hash, otherwise, it is unspendable.
- The Plutus script serialized in the text envelope format.
``cardano-cli`` expects Plutus scripts to be serialized in the text
envelope format.

Creating the ``AlwaysSucceeds`` Plutus spending script
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

The plutus-example executable will automagically generate several Plutus
scripts in the CLI-compatiable text envelope format.

Run the following commands:

.. code:: bash

cd plutus-example

cabal run exe:plutus-example

This will output ``always-succeeds-txin.plutus`` in the
``generated-plutus-scripts`` dir.
Jimbo4350 marked this conversation as resolved.
Show resolved Hide resolved

Setting up a local Alonzo node cluster
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

There is a convenient script that will set up an Alonzo cluster
immediately on your local machine.

Run the following command:

.. code:: bash

cabal install cardano-cli
cabal install cardano-node
./cardano-node/scripts/byron-to-alonzo/mkfiles.sh alonzo

Follow the instructions displayed in the terminal to start your Alonzo
cluster.

Sending ADA to the script address
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

In order to require a Plutus script to validate the spending of a tx
ouput, we must put the tx output at the script address of the said
Plutus script. However, before we do that, we must create a datum hash:

.. code:: bash

> cardano-cli transaction hash-script-data --script-data-value 42
> 9e1199a988ba72ffd6e9c269cadb3b53b5f360ff99f112d9b2ee30c4d74ad88b

In this example, the script we are using always succeeds so we can use
any datum hash. We calculate the script address as follows:

.. code:: bash

> cabal run exe:plutus-example
> cardano-cli address build --payment-script-file generated-plutus-scripts/always-succeeds-txin.plutus --testnet-magic 42
> addr_test1wzeqkp6ne3xm6gz39l874va4ujgl4kr0e46pf3ey8xsu3jsgkpcj2

Now, we should create the tx that will send ADA to the script address of
our ``AlwaysSucceeds`` script:

.. code:: bash

cardano-cli transaction build-raw \
--alonzo-era \
--fee 0 \
--tx-in $txin \
--tx-out "addr_test1wzeqkp6ne3xm6gz39l874va4ujgl4kr0e46pf3ey8xsu3jsgkpcj2+$lovelace" \
--tx-out-datum-hash 9e1199a988ba72ffd6e9c269cadb3b53b5f360ff99f112d9b2ee30c4d74ad88b \
--out-file create-datum-output.body
Jimbo4350 marked this conversation as resolved.
Show resolved Hide resolved

cardano-cli transaction sign \
--tx-body-file create-datum-output.body \
--testnet-magic 42 \
--signing-key-file $UTXO_SKEY \
--out-file create-datum-output.tx

Spending ADA at the script address
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Now that there is ADA at our script address, we must construct the
appropriate transaction in order to spend it.

``$plutusutxotxin`` - This is the tx input that sits at the Plutus
script address (NB: It has a datum hash). ``$plutusrequiredtime`` and
``$plutusrequiredspace`` - These make up the Plutus script execution
budget and are part of the ``$txfee`` ``tx-in-redeemer-value`` - We must
also supply a redeemer value even though the Plutus script will succeed
regardless of the redeemer.

.. code:: bash

cardano-cli transaction build-raw \
--alonzo-era \
--fee "$txfee" \
--tx-in $plutusutxotxin \
--tx-in-collateral $txinCollateral \
--tx-out "$dummyaddress+$spendable" \
--tx-in-script-file $plutusscriptinuse \
--tx-in-datum-value 42 \
--protocol-params-file pparams.json\
--tx-in-redeemer-value 42 \
--tx-in-execution-units "($plutusrequiredtime, $plutusrequiredspace)" \
--out-file test-alonzo.body

cardano-cli transaction sign \
--tx-body-file test-alonzo.body \
--testnet-magic 42 \
--signing-key-file "${UTXO_SKEY}" \
--out-file alonzo.tx

If there is ADA at ``$dummyaddress`` then the Plutus script was
successfully executed. Conversely, if the Plutus script failed, the
collateral input would have been consumed.

You can use the
`example-txin-locking-plutus-script.sh <../../../scripts/plutus/example-txin-locking-plutus-script.sh>`__
in conjunction with `mkfiles.sh
alonzo <../../../scripts/byron-to-alonzo/mkfiles.sh>`__ script to
automagically run the ``AlwaysSucceeds`` script.
8 changes: 8 additions & 0 deletions nix/pkgs/haskell/haskell.nix
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,9 @@ let
"https://github.com/input-output-hk/cardano-addresses"."71006f9eb956b0004022e80aadd4ad50d837b621" = "11dl3fmq7ry5wdmz8kw07ji8yvrxnrsf7pgilw5q9mi4aqyvnaqk";
"https://github.com/input-output-hk/goblins"."cde90a2b27f79187ca8310b6549331e59595e7ba" = "17c88rbva3iw82yg9srlxjv2ia5wjb9cyqw44hik565f5v9svnyg";
"https://github.com/input-output-hk/Win32-network"."3825d3abf75f83f406c1f7161883c438dac7277d" = "19wahfv726fa3mqajpqdqhnl9ica3xmf68i254q45iyjcpj1psqx";
"https://github.com/input-output-hk/cardano-config"."e9de7a2cf70796f6ff26eac9f9540184ded0e4e6" = "1wm1c99r5zvz22pdl8nhkp13falvqmj8dgkm8fxskwa9ydqz01ld";
"https://github.com/input-output-hk/optparse-applicative"."7497a29cb998721a9068d5725d49461f2bba0e7a" = "1gvsrg925vynwgqwplgjmp53vj953qyh3wbdf34pw21c8r47w35r";
"https://github.com/input-output-hk/hedgehog-extras"."edf6945007177a638fbeb8802397f3a6f4e47c14" = "0wc7qzkc7j4ns2rz562h6qrx2f8xyq7yjcb7zidnj7f6j0pcd0i9";
};
# Configuration settings needed for cabal configure to work when cross compiling
# for windows. We can't use `modules` for these as `modules` are only applied
Expand Down Expand Up @@ -85,6 +88,7 @@ let
plutus-playground-server.package.buildable = false; # Would also require libpq
plutus-tx-plugin.package.buildable = false;
plutus-use-cases.package.buildable = false;
plutus-example.package.buildable = false;
web-ghc.package.buildable = false;
# These need R
plutus-core.components.benchmarks.cost-model-test.buildable = lib.mkForce false;
Expand Down Expand Up @@ -133,6 +137,9 @@ let
plutus-ledger.doHaddock = deferPluginErrors;
plutus-ledger.flags.defer-plugin-errors = deferPluginErrors;

plutus-example.doHaddock = deferPluginErrors;
plutus-example.flags.defer-plugin-errors = deferPluginErrors;

# FIXME: Haddock mysteriously gives a spurious missing-home-modules warning
plutus-tx-plugin.doHaddock = false;

Expand All @@ -158,6 +165,7 @@ let
plutus-pab-executables.ghcOptions = [ "-Werror" ];
plutus-doc.ghcOptions = [ "-Werror" ];
plutus-use-cases.ghcOptions = [ "-Werror" ];
plutus-example.ghcOptions = [ "-Werror" ];

# Honestly not sure why we need this, it has a mysterious unused dependency on "m"
# This will go away when we upgrade nixpkgs and things use ieee754 anyway.
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading