Advertisement
Guest User

Untitled

a guest
May 24th, 2019
117
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.96 KB | None | 0 0
  1. -- | A game with two players. Player 1 thinks of a secret word
  2. -- and uses its hash, and the game validator script, to lock
  3. -- some funds (the prize) in a pay-to-script transaction output.
  4. -- Player 2 guesses the word by attempting to spend the transaction
  5. -- output. If the guess is correct, the validator script releases the funds.
  6. -- If it isn't, the funds stay locked.
  7. import qualified Language.PlutusTx as PlutusTx
  8. import qualified Language.PlutusTx.Prelude as P
  9. import Ledger
  10. import qualified Ledger.Value as Value
  11. import Ledger.Value (Value)
  12. import Ledger.Validation
  13. import Wallet
  14. import Playground.Contract
  15.  
  16. import qualified Data.ByteString.Lazy.Char8 as C
  17.  
  18. data HashedString = HashedString P.ByteString
  19.  
  20. PlutusTx.makeLift ''HashedString
  21.  
  22. -- create a data script for the guessing game by hashing the string
  23. -- and lifting the hash to its on-chain representation
  24. mkDataScript :: String -> DataScript
  25. mkDataScript word =
  26. let hashedWord = plcSHA2_256 (C.pack word)
  27. in DataScript (Ledger.lifted (HashedString hashedWord))
  28.  
  29. data ClearString = ClearString P.ByteString
  30.  
  31. PlutusTx.makeLift ''ClearString
  32.  
  33. -- create a redeemer script for the guessing game by lifting the
  34. -- string to its on-chain representation
  35. mkRedeemerScript :: String -> RedeemerScript
  36. mkRedeemerScript word =
  37. let clearWord = C.pack word
  38. in RedeemerScript (Ledger.lifted (ClearString clearWord))
  39.  
  40. -- | The validator script of the game.
  41. gameValidator :: ValidatorScript
  42. gameValidator = ValidatorScript ($$(Ledger.compileScript [||
  43. -- The code between the '[||' and '||]' quotes is on-chain code.
  44. \(HashedString actual) (ClearString guess) (p :: PendingTx) ->
  45.  
  46. -- inside the on-chain code we can write $$(P.xxx) to use functions
  47. -- from the PlutusTx Prelude (imported qualified at the top of the
  48. -- module)
  49. if $$(P.equalsByteString) actual ($$(P.sha2_256) guess)
  50. then ()
  51. else ($$(P.error) ($$(P.traceH) "WRONG!" ()))
  52.  
  53. ||]))
  54.  
  55. -- | The address of the game (the hash of its validator script)
  56. gameAddress :: Address
  57. gameAddress = Ledger.scriptAddress gameValidator
  58.  
  59. -- | The "lock" contract endpoint. See note [Contract endpoints]
  60. lock :: MonadWallet m => String -> Value -> m ()
  61. lock word value =
  62. -- 'payToScript_' is a function of the wallet API. It takes a script
  63. -- address, a currency value and a data script, and submits a transaction
  64. -- that pays the value to the address, using the data script.
  65. --
  66. -- The underscore at the end of the name indicates that 'payToScript_'
  67. -- discards its result. If you want to hold on to the transaction you can
  68. -- use 'payToScript'.
  69. payToScript_ defaultSlotRange gameAddress value (mkDataScript word)
  70.  
  71. -- | The "guess" contract endpoint. See note [Contract endpoints]
  72. guess :: MonadWallet m => String -> m ()
  73. guess word =
  74. -- 'collectFromScript' is a function of the wallet API. It consumes the
  75. -- unspent transaction outputs at a script address and pays them to a
  76. -- public key address owned by this wallet. It takes the validator script
  77. -- and the redeemer scripts as arguments.
  78. --
  79. -- Note that before we can use 'collectFromScript', we need to tell the
  80. -- wallet to start watching the address for transaction outputs (because
  81. -- the wallet does not keep track of the UTXO set of the entire chain).
  82. collectFromScript defaultSlotRange gameValidator (mkRedeemerScript word)
  83.  
  84. -- | The "startGame" contract endpoint, telling the wallet to start watching
  85. -- the address of the game script. See note [Contract endpoints]
  86. startGame :: MonadWallet m => m ()
  87. startGame =
  88. -- 'startWatching' is a function of the wallet API. It instructs the wallet
  89. -- to keep track of all outputs at the address. Player 2 needs to call
  90. -- 'startGame' before Player 1 uses the 'lock' endpoint, to ensure that
  91. -- Player 2's wallet is aware of the game address.
  92. startWatching gameAddress
  93.  
  94. $(mkFunctions ['lock, 'guess, 'startGame])
  95.  
  96. {- Note [Contract endpoints]
  97.  
  98. A contract endpoint is a function that uses the wallet API to interact with the
  99. blockchain. We can look at contract endpoints from two different points of view.
  100.  
  101. 1. Contract users
  102.  
  103. Contract endpoints are the visible interface of the contract. They provide a
  104. UI (HTML form) for entering the parameters of the actions we may take as part
  105. of the contract.
  106.  
  107. 2. Contract authors
  108.  
  109. As contract authors we define endpoints as functions that return a value of
  110. type 'MockWallet ()'. This type indicates that the function uses the wallet API
  111. to produce and spend transaction outputs on the blockchain.
  112.  
  113. Endpoints can have any number of parameters: 'lock' has two
  114. parameters, 'guess' has one and 'startGame' has none. For each endpoint we
  115. include a call to 'mkFunction' at the end of the contract definition. This
  116. causes the Haskell compiler to generate a schema for the endpoint. The Plutus
  117. Playground then uses this schema to present an HTML form to the user where the
  118. parameters can be entered.
  119.  
  120. -}
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement