Skip to content
Permalink
Browse files

Review comments

  • Loading branch information...
j-mueller committed Apr 13, 2019
1 parent 047499b commit ac3c110062850700c25238ef49255cb2c6280e75
@@ -7,9 +7,6 @@
module Language.PlutusTx.Coordination.Contracts.Currency(
Currency(..)
, curValidator
, curDataScript
, curRedeemer
, curAddress
-- * Actions etc
, forge
, forgedValue
@@ -62,7 +59,9 @@ curValidator cur =
let validate :: Currency -> () -> () -> V.PendingTx -> ()
validate (Currency (refHash, refIdx) amt token) () () p =
let
-- see note [Obtaining the currency symbol]
ownSymbol = $$(V.ownCurrencySymbol) p

forged = $$(V.valueForged) p
expected = $$(Value.singleton) ownSymbol token amt

@@ -86,29 +85,33 @@ curValidator cur =
validate
||]))

-- | Currency data script (unit value).
curDataScript :: DataScript
curDataScript = DataScript $ Ledger.lifted ()
{- note [Obtaining the currency symbol]
The currency symbol is the address (hash) of the validator. That is why
we can use 'Ledger.scriptAddress' here to get the symbol in off-chain code,
for example in 'forgedValue'.
-- | Currency redeemer (unit value).
curRedeemer :: RedeemerScript
curRedeemer = RedeemerScript $ Ledger.lifted ()
Inside the validator script (on-chain) we can't use 'Ledger.scriptAddress',
because at that point we don't know the hash of the script yet. That
is why we use 'V.ownCurrencySymbol', which obtains the hash from the
'PendingTx' value.
-- | The address of a 'Currency' contract.
curAddress :: Currency -> Address
curAddress = Ledger.scriptAddress . curValidator
-}

-- | The 'Value' forged by the 'curValidator' contract
forgedValue :: Currency -> Value
forgedValue cur =
let a = plcCurrencySymbol (curAddress cur)
let
-- see note [Obtaining the currency symbol]
a = plcCurrencySymbol (Ledger.scriptAddress (curValidator cur))

t = curRefTokenName cur
i = curRefAmount cur
in
$$(Value.singleton) a t i

-- | @forge c n@ forges @n@ units of a currency called @c@ and
-- pays them to a public key address owned by the wallet.
-- | @forge c n@ forges @n@ units of a currency with one type of token called
-- @c@ and pays them to a public key address owned by the wallet.
forge :: (WalletAPI m, WalletDiagnostics m) => String -> Int -> m Currency
forge nm amount = do
pk <- WAPI.ownPubKey
@@ -121,9 +124,10 @@ forge nm amount = do
(refAddr, refTxIn) <- PK.lock pk (Ada.adaValueOf 1)

let

-- With that we can define the currency
theCurrency = mkCurrency (txInRef refTxIn) amount nm
curAddr = curAddress theCurrency
curAddr = Ledger.scriptAddress (curValidator theCurrency)
forgedVal = forgedValue theCurrency
oneOrMore = WAPI.intervalFrom $ Ada.adaValueOf 1

@@ -142,7 +146,7 @@ forge nm amount = do
am <- WAPI.watchedAddresses

let inputs' = am ^. at curAddr . to (Map.toList . fromMaybe Map.empty)
con (r, _) = scriptTxIn r (curValidator theCurrency) curRedeemer
con (r, _) = scriptTxIn r (curValidator theCurrency) (RedeemerScript $ Ledger.lifted ())
ins = con <$> inputs'

let tx = Ledger.Tx
@@ -165,7 +169,7 @@ forge nm amount = do
-- 3. When trg1 fires we submit a transaction that creates a
-- pay-to-script output locked by the monetary policy
registerOnce trg1 (EventHandler $ const $ do
payToScript_ defaultSlotRange (curAddress theCurrency) (Ada.adaValueOf 1) curDataScript)
payToScript_ defaultSlotRange curAddr (Ada.adaValueOf 1) (DataScript $ Ledger.lifted ()))

-- Return the currency definition so that we can use the symbol
-- in other places
@@ -9,13 +9,7 @@
-- contract. This is useful if you need something that behaves like
-- a pay-to-pubkey output, but is not (easily) identified by wallets
-- as one.
module Language.PlutusTx.Coordination.Contracts.PubKey(
pkValidator
, pkRedeemer
, pkDataScript
, lock
, spend
) where
module Language.PlutusTx.Coordination.Contracts.PubKey(lock) where

import Data.Maybe (listToMaybe)
import qualified Data.Map as Map
@@ -40,23 +34,14 @@ pkValidator pk =
in validate
||]))

-- | PayToPubKey data script (unit value).
pkDataScript :: DataScript
pkDataScript = DataScript $ Ledger.lifted ()

-- | PayToPubKey redeemer (unit value).
pkRedeemer :: RedeemerScript
pkRedeemer = RedeemerScript $ Ledger.lifted ()

-- | The address of a 'PayToPubKey' contract.
pkAddress :: PubKey -> Address
pkAddress = Ledger.scriptAddress . pkValidator

-- | Lock some funds in a 'PayToPubKey' contract, returning the output's address
-- and a 'TxIn' transaction input that can spend it.
lock :: (WalletAPI m, WalletDiagnostics m) => PubKey -> Value -> m (Address, TxIn)
lock pk vl = getRef =<< payToScript defaultSlotRange addr vl pkDataScript where
addr = pkAddress pk
addr = Ledger.scriptAddress (pkValidator pk)
pkDataScript = DataScript $ Ledger.lifted ()
pkRedeemer = RedeemerScript $ Ledger.lifted ()

getRef tx = do
let scriptOuts = listToMaybe
$ fmap fst
@@ -72,8 +57,3 @@ lock pk vl = getRef =<< payToScript defaultSlotRange addr vl pkDataScript where
Just o -> pure (scriptTxIn o (pkValidator pk) pkRedeemer)

pure (addr, txin)

-- | Make a 'TxIn' that spends a pay-to-script transaction output locked
-- by the
spend :: TxOutRef -> PubKey -> TxIn
spend ref pk = Ledger.scriptTxIn ref (pkValidator pk) pkRedeemer
@@ -323,7 +323,10 @@ eqTx = [|| \(TxHash l) (TxHash r) -> Builtins.equalsByteString l r ||]

-- | Get the hash of the validator script that is currently being validated.
ownHash :: Q (TExp (PendingTx -> ValidatorHash))
ownHash = [|| \(PendingTx _ _ _ _ i _ _ _) -> let PendingTxIn _ (Just (h, _)) _ = i in h ||]
ownHash = [|| \(PendingTx _ _ _ _ i _ _ _) ->
case i of
PendingTxIn _ (Just (h, _)) _ -> h
_ -> $$(P.error) () ||]

-- | Convert a 'CurrencySymbol' to a 'ValidatorHash'
fromSymbol :: CurrencySymbol -> ValidatorHash
@@ -360,6 +363,7 @@ valueForged :: Q (TExp (PendingTx -> Value))
valueForged = [||
let valueForged' :: PendingTx -> Value
valueForged' (PendingTx _ _ _ forge _ _ _ _) = forge
valueForged' _ = $$(P.error) ()
in valueForged'
||]

@@ -263,13 +263,16 @@ class WalletAPI m where
createPaymentWithChange :: Value -> m (Set.Set TxIn, Maybe TxOut)

{- |
Register a 'EventHandler' in @m ()@ to be run when condition is true.
Register a 'EventHandler' in @m ()@ to be run a single time when the
condition is true.
* The action will be run once for each block where the condition holds.
For example, @register (slotRangeT (Interval 3 6)) a@ causes @a@ to be run at blocks 3, 4, and 5.
* The action will be run when the condition holds for the first time.
For example, @registerOnce (slotRangeT (Interval 3 6)) a@ causes @a@ to
be run at block 3. See 'register' for a variant that runs the action
multiple times.
* Each time the wallet is notified of a new block, all triggers are checked
and the matching ones are run in an unspecified order.
and the matching ones are run in an unspecified order and then deleted.
* The wallet will only watch "known" addresses. There are two ways an
address can become a known address.
@@ -304,6 +307,9 @@ throwInsufficientFundsError = throwError . InsufficientFunds
throwOtherError :: MonadError WalletAPIError m => Text -> m a
throwOtherError = throwError . OtherError

-- | A variant of 'register' that registers the trigger again immediately after
-- running the action. This is useful if you want to run the same action every
-- time the condition holds, instead of only the first time.
register :: (WalletAPI m, Monad m) => EventTrigger -> EventHandler m -> m ()
register t h = registerOnce t h' where
h' = h <> (EventHandler $ \_ -> register t h)

0 comments on commit ac3c110

Please sign in to comment.
You can’t perform that action at this time.