Skip to content

Commit

Permalink
Monetary policy/forging policy -> minting policy (IntersectMBO#3403)
Browse files Browse the repository at this point in the history
* Rename 1

* Rename 2

* Rename 3

* Rename 5

* RST

* Revert some mistakes

* More

* More RST

* Move

* Revert txInfoForge for now

* Add todo

* fix client

* Update PIR output
  • Loading branch information
michaelpj authored Jun 19, 2021
1 parent 9e4d0bf commit f4aef5c
Show file tree
Hide file tree
Showing 65 changed files with 1,582 additions and 1,581 deletions.
4 changes: 2 additions & 2 deletions doc/marlowe/tutorials/marlowe-model.rst
Original file line number Diff line number Diff line change
Expand Up @@ -158,8 +158,8 @@ interchangeable with other tokens), and more exotic mixed cases:
- Mixed tokens are those with several ``TokenName``\ s *and* quantities
greater than one.

Cardano provides a simple way to introduce a new currency by *forging*
it using *monetary policy scripts*. This effectively embeds Ethereum
Cardano provides a simple way to introduce a new currency by *minting*
it using *minting policy scripts*. This effectively embeds Ethereum
ERC-20/ERC-721 standards as primitive values in Cardano. We use custom
tokens to represent participants in Marlowe contracts executing on
chain.
Expand Down
10 changes: 5 additions & 5 deletions doc/plutus/tutorials/BasicPolicies.hs
Original file line number Diff line number Diff line change
Expand Up @@ -27,16 +27,16 @@ oneAtATimePolicy _ ctx =
-- from the context
let ownSymbol = ownCurrencySymbol ctx
txinfo = scriptContextTxInfo ctx
forged = txInfoForge txinfo
minted = txInfoForge txinfo
-- Here we're looking at some specific token name, which we
-- will assume we've got from elsewhere for now.
in valueOf forged ownSymbol tname == 1
in valueOf minted ownSymbol tname == 1

-- We can use 'compile' to turn a forging policy into a compiled Plutus Core program,
-- just as for validator scripts. We also provide a 'wrapMonetaryPolicy' function
-- We can use 'compile' to turn a minting policy into a compiled Plutus Core program,
-- just as for validator scripts. We also provide a 'wrapMintingPolicy' function
-- to handle the boilerplate.
oneAtATimeCompiled :: CompiledCode (Data -> Data -> ())
oneAtATimeCompiled = $$(compile [|| wrapMonetaryPolicy oneAtATimePolicy ||])
oneAtATimeCompiled = $$(compile [|| wrapMintingPolicy oneAtATimePolicy ||])
-- BLOCK2
singleSignerPolicy :: ScriptContext -> Bool
singleSignerPolicy ctx = txSignedBy (scriptContextTxInfo ctx) key
Expand Down
8 changes: 4 additions & 4 deletions doc/plutus/tutorials/GameModel.hs
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ instance ContractModel GameModel where
hasToken $= Just w
currentSecret $= secret
gameValue $= val
forge gameTokenVal
mint gameTokenVal
deposit w gameTokenVal
withdraw w $ Ada.lovelaceValueOf val
wait 2
Expand Down Expand Up @@ -300,7 +300,7 @@ wallets = [w1, w2, w3]
-- START gameTokenVal
gameTokenVal :: Value
gameTokenVal =
let sym = Scripts.forwardingMonetaryPolicyHash G.typedValidator
let sym = Scripts.forwardingMintingPolicyHash G.typedValidator
in G.token sym "guess"
-- END gameTokenVal

Expand Down Expand Up @@ -354,7 +354,7 @@ v1_model = ()
hasToken $= Just w
currentSecret $= secret
gameValue $= val
forge gameTokenVal
mint gameTokenVal
deposit w gameTokenVal
withdraw w $ Ada.lovelaceValueOf val
-- END nextState Lock v1
Expand Down Expand Up @@ -410,7 +410,7 @@ v2_model = ()
hasToken $= Just w
currentSecret $= secret
gameValue $= val
forge gameTokenVal
mint gameTokenVal
deposit w gameTokenVal
withdraw w $ Ada.lovelaceValueOf val
wait 2
Expand Down
51 changes: 0 additions & 51 deletions doc/plutus/tutorials/basic-forging-policies.rst

This file was deleted.

51 changes: 51 additions & 0 deletions doc/plutus/tutorials/basic-minting-policies.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
.. highlight:: haskell
.. _basic_minting_policies_tutorial:

Writing basic minting policies
==============================

:term:`Minting policy scripts<minting policy script>` are the programs that can be used to control the minting of new assets on the chain.
Minting policy scripts are much like :term:`validator scripts<validator script>`, and they are written similarly, so check out the :ref:`basic validators tutorial<basic_validators_tutorial>` before reading this one .

Minting policy arguments
------------------------

Minting policies, like validators, receive some information from the validating node:

- The :term:`redeemer`, which is some script-specific data specified by the party performing the minting.
- The :term:`minting context`, which contains a representation of the spending transaction, as well as the hash of the minting policy which is currently being run.

The minting policy is a function which receives these two inputs as *arguments*.
The validating node is responsible for passing them in and running the minting policy.
As with validator scripts, the arguments are passed encoded as :hsobj:`PlutusTx.Data.Data`.

Using the minting context
-------------------------

..
TODO: pin down the naming: minting vs policy context
Validators have access to the :term:`minting context` as their second argument.
This will always be a value of type ``Ledger.Validation.PolicyCtx`` encoded as ``Data``.

The minting context is very similar to the :term:`validation context`, and allows access to all the same features of the transaction.
Minting policies tend to be particularly interested in the ``mint`` field, since the point of a minting policy is to control which tokens are minted.

It is also important for a minting policy to look at the tokens in the ``mint`` field that are part of its own asset group.
This requires the policy to refer to its own hash -- fortunately this is provided for us in the minting context.

Here is an example that puts this together to make a simple policy that allows anyone to mint the token so long as they do it one token at a time.

.. literalinclude:: BasicPolicies.hs
:start-after: BLOCK1
:end-before: BLOCK2

Probably the simplest useful policy is one that requires a specific key to have signed the transaction in order to do any minting.
This gives the key holder total control over the supply, but this is often sufficient for asset types where there is a centralized authority.

.. literalinclude:: BasicPolicies.hs
:start-after: BLOCK2
:end-before: BLOCK3

.. note::
We don't need to check that this transaction actually mints any of our asset type: the ledger rules ensure that the minting policy will only be run if some of that asset is being minted.
24 changes: 12 additions & 12 deletions doc/plutus/tutorials/contract-testing.rst
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,9 @@ The game is played as follows:
changes.

As an extra wrinkle, when the first player locks the prize, a new
:term:`token` is also forged. Only the player currently holding the :term:`token` is
:term:`token` is also minted. Only the player currently holding the :term:`token` is
allowed to make a guess--which gives us an opportunity to illustrate
forging and passing around :term:`tokens<token>`.
minting and passing around :term:`tokens<token>`.

The generated tests will exercise the contract by locking the prize,
then moving the game :term:`token` and making guesses at random, checking that
Expand Down Expand Up @@ -87,7 +87,7 @@ We will also need a game :term:`token`. After importing the ``Scripts`` module
:start-after: START import Scripts
:end-before: END import Scripts

we can define it as follows, applying a monetary policy defined in the code under test (imported as module ``G``):
we can define it as follows, applying a minting policy defined in the code under test (imported as module ``G``):

.. literalinclude:: GameModel.hs
:start-after: START import Game
Expand All @@ -113,13 +113,13 @@ We can even construct a ``Value`` containing an Ada and a game :term:`token`:
If you inspect the output closely, you will see that a ``Value``
contains maps nested within another ``Map``. The outer ``Map`` is
indexed by hashes of monetary policy :term:`scripts<script>`, so each inner ``Map``
indexed by hashes of minting policy :term:`scripts<script>`, so each inner ``Map``
contains a bag of :term:`tokens<token>` managed by the same policy. :term:`Token<token>` names can
be chosen freely, and each policy can manage any number of its own
:term:`token` types. In this case the game :term:`token` is called a "guess", and the
:term:`script` managing game :term:`tokens<token>` has the hash f687... A little confusingly,
the Ada :term:`token` name is displayed as an empty string, as is the hash of
the corresponding monetary policy.
the corresponding minting policy.

Introducing contract models
---------------------------
Expand Down Expand Up @@ -351,7 +351,7 @@ and defines the expected effect of each operation.

The ``Lock`` operation creates the contract, initializing the model
contract state (using :hsobj:`Plutus.Contract.Test.ContractModel.$=` and generated ``Lens`` operations),
forges the game :term:`token` (using :hsobj:`Plutus.Contract.Test.ContractModel.forge`), deposits it in the creator's
mints the game :term:`token` (using :hsobj:`Plutus.Contract.Test.ContractModel.mint`), deposits it in the creator's
wallet, and withdraws the Ada locked in the contract (using :hsobj:`Plutus.Contract.Test.ContractModel.deposit`
and :hsobj:`Plutus.Contract.Test.ContractModel.withdraw`):

Expand All @@ -362,9 +362,9 @@ and :hsobj:`Plutus.Contract.Test.ContractModel.withdraw`):
A :hsobj:`Plutus.Contract.Test.ContractModel.ContractModel` actually tracks not only the contract model state (in
our case the ``GameModel`` type), but also the quantities of :term:`tokens<token>`
expected to be in each wallet, which are checked at the end of each
test. It is these expectations that are manipulated by :hsobj:`Plutus.Contract.Test.ContractModel.forge`,
test. It is these expectations that are manipulated by :hsobj:`Plutus.Contract.Test.ContractModel.mint`,
:hsobj:`Plutus.Contract.Test.ContractModel.deposit`, etc... don't confuse them with operations that *actually*
forge or move :term:`tokens<token>` in the implementation. The :hsobj:`Plutus.Contract.Test.ContractModel.ModelState` type
mint or move :term:`tokens<token>` in the implementation. The :hsobj:`Plutus.Contract.Test.ContractModel.ModelState` type
contains all of this information.


Expand Down Expand Up @@ -405,7 +405,7 @@ the real contract. Doing so immediately reveals a problem:
Looking at the last two lines, we see the generated test sequence, and
the problem is evident: we generated a test *that only gives the game
:term:`token`* to wallet 1, but this makes no sense because the game :term:`token` has
not yet been forged--so the ``fromJust`` in the :hsobj:`Plutus.Contract.Test.ContractModel.nextState` function
not yet been minted--so the ``fromJust`` in the :hsobj:`Plutus.Contract.Test.ContractModel.nextState` function
fails. We will see how to prevent this in the next section.

Restricting test cases with preconditions
Expand All @@ -417,7 +417,7 @@ this is *not* the same as restricting tests to 'the happy path': we
*want* to test unexpected sequences of actions, and indeed, this is
part of the strength of property-based testing. But there are some
actions--like trying to give the game :term:`token` to a wallet before it has been
forged--that are not even interesting to test. These are the cases
minted--that are not even interesting to test. These are the cases
that we rule out by defining preconditions for actions; the effect is
to prevent such test cases ever being generated.

Expand Down Expand Up @@ -643,7 +643,7 @@ happen. To understand why, we need to study the emulator log. Here are the relev
outputs:
- Value (Map []) addressed to
ScriptAddress: d1e1...
forge: Value (Map [(f687...,Map [(guess,1)])])
mint: Value (Map [(f687...,Map [(guess,1)])])
...
[INFO] Slot 2: W1: TxSubmit: 2d66...
Expand All @@ -652,7 +652,7 @@ Here we see the :term:`endpoint` call to ``lock`` being received during slot
to the contract :term:`script`. The transaction is balanced (which has no
effect in this case), submitted, and validated by the emulator at
slot 2. Then another transaction, ``1eba...``, is created, which
forges the game :term:`token`. This transaction is in turn balanced (resulting
mints the game :term:`token`. This transaction is in turn balanced (resulting
in a new hash, ``2d66...``), and submitted without error--but although
no errors are reported, *this transaction is not validated*.

Expand Down
2 changes: 1 addition & 1 deletion doc/plutus/tutorials/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,5 @@ Tutorials
basic-apps
plutus-tx
basic-validators
basic-forging-policies
basic-minting-policies
contract-testing
20 changes: 10 additions & 10 deletions doc/reference/glossary.rst
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,9 @@ Glossary
actually distributed to users and run by the PAB.

currency
A class of token whose forging is controlled by a particular monetary
A class of token whose minting is controlled by a particular monetary
policy script. On the Cardano ledger there is a special currency
called Ada which can never be forged and which is controlled
called Ada which can never be minted and which is controlled
separately.

datum
Expand All @@ -57,18 +57,18 @@ Glossary

See :ref:`what_is_a_ledger`.

forging
A transaction which forges tokens creates new tokens, providing that
the corresponding monetary policy script is satisfied. The amount
forged can be negative, in which case the tokens will be destroyed
minting
A transaction which mints tokens creates new tokens, providing that
the corresponding minting policy script is satisfied. The amount
minted can be negative, in which case the tokens will be destroyed
instead of created.

forging context
minting context
A data structure containing a summary of the transaction being
validated, and the current forging policy which is being run.
validated, and the current minting policy which is being run.

forging policy script
A script which must be satisfied in order for a transaction to forge
minting policy script
A script which must be satisfied in order for a transaction to mint
tokens of the corresponding currency.

Hydra
Expand Down
2 changes: 1 addition & 1 deletion marlowe/src/Language/Marlowe/Client.hs
Original file line number Diff line number Diff line change
Expand Up @@ -361,7 +361,7 @@ setupMarloweParams owners contract = mapError (review _MarloweError) $ do
else if roles `Set.isSubsetOf` Set.fromList (AssocMap.keys owners)
then do
let tokens = fmap (\role -> (role, 1)) $ Set.toList roles
cur <- mapError RolesCurrencyError $ Currency.forgeContract creator tokens
cur <- mapError RolesCurrencyError $ Currency.mintContract creator tokens
let rolesSymbol = Currency.currencySymbol cur
let giveToParty (role, pkh) = Constraints.mustPayToPubKey pkh (Val.singleton rolesSymbol role 1)
let distributeRoleTokens = foldMap giveToParty (AssocMap.toList owners)
Expand Down
8 changes: 4 additions & 4 deletions notes/model/UTxO.hsproj/Ledger.hs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ data Tx
= Tx
{ inputsTX :: [TxIn]
, outputsTX :: [TxOut]
, forgeTX :: Value
, mintTX :: Value
, feeTX :: Value
}
deriving (Show)
Expand All @@ -42,7 +42,7 @@ data TxStripped
= TxStripped
{ inputsTXS :: Set TxOutRef
, outputsTXS :: [TxOut]
, forgeTXS :: Value
, mintTXS :: Value
, feeTXS :: Value
}
deriving (Show)
Expand All @@ -53,7 +53,7 @@ stripTx Tx{..}
where
inputsTXS = Set.fromList . map refTI $ inputsTX
outputsTXS = outputsTX
forgeTXS = forgeTX
mintTXS = mintTX
feeTXS = feeTX

-- |Hash (double) the given transaction *without* witnesses.
Expand All @@ -70,7 +70,7 @@ preHashTx tx = hash (stripTx tx)
--
validValuesTx :: Tx -> Bool
validValuesTx Tx{..}
= all ((>= 0) . valueTO) outputsTX && forgeTX >= 0 && feeTX >= 0
= all ((>= 0) . valueTO) outputsTX && mintTX >= 0 && feeTX >= 0

data TxOutRef
= TxOutRef
Expand Down
2 changes: 1 addition & 1 deletion notes/model/UTxO.hsproj/UTxO.hs
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ validTx :: Tx -> Ledger -> Bool
validTx t ledger = inputsAreValid && valueIsPreserved && validValuesTx t
where
inputsAreValid = all (`validatesIn` unspentOutputs ledger) (inputsTX t)
valueIsPreserved = forgeTX t + sum (map (fromJust . value ledger) (map refTI $ inputsTX t))
valueIsPreserved = mintTX t + sum (map (fromJust . value ledger) (map refTI $ inputsTX t))
== feeTX t + sum (map valueTO (outputsTX t))
-- NB: the 'fromMaybe' is safe as 'inputsAreUnspent' holds if we get here

Expand Down
Loading

0 comments on commit f4aef5c

Please sign in to comment.