Skip to content

Commit

Permalink
Project can now be build incrementally with Nix+Cabal. Added instruct…
Browse files Browse the repository at this point in the history
…ions to README how to do so. Added release.nix for Hydra CI and github action. Updated plutus version.
  • Loading branch information
koslambrou committed Jun 9, 2021
1 parent 77dfcfb commit 6fce2d6
Show file tree
Hide file tree
Showing 18 changed files with 715 additions and 24 deletions.
13 changes: 13 additions & 0 deletions .github/workflows/test.yml
@@ -0,0 +1,13 @@
name: "Tests"
on:
pull_request:
jobs:
nix-instantiate:
strategy:
matrix:
os: [ubuntu-latest]
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v2.3.4
- uses: nixbuild/nix-quick-install-action@v5
- run: nix-instantiate release.nix --restrict-eval -I . --allowed-uris 'https://github.com/NixOS/nixpkgs https://github.com/input-output-hk https://github.com/NixOS/nixpkgs-channels' --option trusted-public-keys "hydra.iohk.io:f/Ea+s+dFdN+3Y/G+FDgSq+a5NEWhJGzdjvKNGv0/EQ= iohk.cachix.org-1:DpRUyj7h7V830dp/i6Nti+NEO2/nhblbov/8MW7Rqoo= cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY=" --option substituters "https://hydra.iohk.io https://iohk.cachix.org https://cache.nixos.org/" --show-trace
3 changes: 3 additions & 0 deletions .gitignore
Expand Up @@ -21,3 +21,6 @@ cabal.project.local
cabal.project.local~
.HTF/
.ghc.environment.*
result*
.envrc
.vim
37 changes: 34 additions & 3 deletions README.md
Expand Up @@ -4,7 +4,9 @@ This project gives a simple starter project for using the Plutus Platform.

## Setting up

For now, the only supported tooling setup is to use the provided VSCode devcontainer to get an environment with the correct tools set up.
### VSCode devcontainer

Use the provided VSCode devcontainer to get an environment with the correct tools set up.

- Install Docker
- Install VSCode
Expand All @@ -19,10 +21,38 @@ For now, the only supported tooling setup is to use the provided VSCode devconta
Note: This uses the [plutus-starter-devcontainer image on dockerhub](https://hub.docker.com/r/inputoutput/plutus-starter-devcontainer), if
you wish to build the image yourself, you can do so as follows:
- Clone https://github.com/input-output-hk/plutus ,
- Set up your machine to build things with Nix, following the Plutus README (make sure to set up the binary cache!),
- Set up your machine to build things with Nix, following the [Plutus README](https://github.com/input-output-hk/plutus/blob/master/README.adoc) (make sure to set up the binary cache!),
- Build and load the docker container: `docker load < $(nix-build default.nix -A devcontainer)`,
- Adjust the `.devcontainer/devcontainer.json` file to point to your local image.

### Cabal+Nix build

Alternatively, use the Cabal+Nix build if you want to develop with incremental builds, but also have it automatically download all dependencies.

Set up your machine to build things with `Nix`, following the [Plutus README](https://github.com/input-output-hk/plutus/blob/master/README.adoc) (make sure to set up the binary cache!).

To enter a development environment, simply open a terminal on the project's root and use `nix-shell` to get a bash shell:

```
$ nix-shell
```

Otherwise, you can use [direnv](https://github.com/direnv/direnv) which allows you to use your preferred shell. Once installed, just run:

```
$ echo "use nix" > .envrc # Or manually add "use nix" in .envrc if you already have one
$ direnv allow
```

and you'll have a working development environment for now and the future whenever you enter this directory.

The build should not take too long if you correctly set up the binary cache. If it starts building GHC, stop and setup the binary cache.

Afterwards, the command `cabal build` from the terminal should work (if `cabal` couldn't resolve the dependencies, run `cabal update` and then `cabal build`).

Also included in the environment is a working [Haskell Language Server](https://github.com/haskell/haskell-language-server) you can integrate with your editor.
See [here](https://github.com/haskell/haskell-language-server#configuring-your-editor) for instructions.

## The Plutus Application Backend (PAB) example

We have provided an example PAB application in `./pab`. With the PAB we can serve and interact
Expand Down Expand Up @@ -145,8 +175,9 @@ didn't validate.
As an exercise, you can now spin up another instance for Wallet 2 and make a correct guess, and
confirm that the transaction validates and the Ada is transferred into the right wallet.

Note that you can verify the balances by looking at the log of `plutus-starter-pab`
Note that you can verify the balances by looking at the log of `plutus-starter-pab`
when exiting it by pressing return.

Finally, also node that the PAB also exposes a websocket, which you can read about in
the general [PAB Architecture documentation](https://github.com/input-output-hk/plutus/blob/master/plutus-pab/ARCHITECTURE.adoc).

16 changes: 12 additions & 4 deletions cabal.project
@@ -1,4 +1,4 @@
index-state: 2021-02-24T00:00:00Z
index-state: 2021-04-13T00:00:00Z

packages: ./.

Expand All @@ -9,6 +9,7 @@ write-ghc-environment-files: never
tests: true
benchmarks: true

-- Plutus revision from 2021/06/04
source-repository-package
type: git
location: https://github.com/input-output-hk/plutus.git
Expand All @@ -25,15 +26,18 @@ source-repository-package
plutus-use-cases
prettyprinter-configurable
quickcheck-dynamic
tag: 97437286b8df2bcafa665785a724eec0d2dcff7f
word-array
tag: 514f059a7aabc4b03ca80343d29cf0736f9ea498

-- The following sections are copied from the 'plutus' repository cabal.project at the revision
-- given above.
-- This is necessary because the 'plutus' libraries depend on a number of other libraries which are
-- not on Hackage, and so need to be pulled in as `source-repository-package`s themselves. Make sure to
-- re-update this section from the template when you do an upgrade.

-- This is also needed so evenful-sql-common will build with a newer version of persistent.
package eventful-sql-common
ghc-options: -XDerivingStrategies -XStandaloneDeriving -XUndecidableInstances -XDataKinds -XFlexibleInstances
ghc-options: -XDerivingStrategies -XStandaloneDeriving -XUndecidableInstances -XDataKinds -XFlexibleInstances -XMultiParamTypeClasses

allow-newer:
-- Has a commit to allow newer aeson, not on Hackage yet
Expand All @@ -53,7 +57,11 @@ constraints:
-- breaks eventful even more than it already was
, persistent-template < 2.12

extra-packages: ieee, filemanip
-- Drops an instance breaking our code. Should be released to Hackage eventually.
source-repository-package
type: git
location: https://github.com/Quid2/flat.git
tag: 95e5d7488451e43062ca84d5376b3adcc465f1cd

-- Needs some patches, but upstream seems to be fairly dead (no activity in > 1 year)
source-repository-package
Expand Down
10 changes: 10 additions & 0 deletions default.nix
@@ -0,0 +1,10 @@
let
packages = import ./nix;
inherit (packages) pkgs plutus-starter;
project = plutus-starter.haskell.project;
in
{
inherit pkgs plutus-starter;

inherit project;
}
29 changes: 14 additions & 15 deletions examples/src/Plutus/Contracts/Game.hs
Expand Up @@ -40,7 +40,7 @@ module Plutus.Contracts.Game
import Control.Monad (void)
import Data.Aeson (FromJSON, ToJSON)
import GHC.Generics (Generic)
import Ledger (Address, Validator, ScriptContext, Value, Datum(Datum), TxOutTx)
import Ledger (Address, Datum(Datum), ScriptContext, TxOutTx, Validator, Value)
import qualified Ledger
import qualified Ledger.Ada as Ada
import Ledger.AddressMap (UtxoMap)
Expand All @@ -56,7 +56,6 @@ import qualified Data.Map as Map
import Schema (ToArgument, ToSchema)
import Wallet.Emulator (Wallet (..))


import qualified Data.ByteString.Char8 as C
import qualified Prelude
import Data.Maybe (catMaybes)
Expand All @@ -65,13 +64,13 @@ import qualified Control.Monad.Freer.Extras.Log as Extras

newtype HashedString = HashedString ByteString
deriving newtype PlutusTx.IsData
deriving Show
deriving Prelude.Show

PlutusTx.makeLift ''HashedString

newtype ClearString = ClearString ByteString
deriving newtype PlutusTx.IsData
deriving Show
deriving Prelude.Show

PlutusTx.makeLift ''ClearString

Expand Down Expand Up @@ -106,12 +105,12 @@ gameInstance = Scripts.validator @Game

-- create a data script for the guessing game by hashing the string
-- and lifting the hash to its on-chain representation
hashString :: String -> HashedString
hashString :: Prelude.String -> HashedString
hashString = HashedString . sha2_256 . C.pack

-- create a redeemer script for the guessing game by lifting the
-- string to its on-chain representation
clearString :: String -> ClearString
clearString :: Prelude.String -> ClearString
clearString = ClearString . C.pack

-- | The address of the game (the hash of its validator script)
Expand All @@ -120,15 +119,15 @@ gameAddress = Ledger.scriptAddress gameValidator

-- | Parameters for the "lock" endpoint
data LockParams = LockParams
{ secretWord :: String
{ secretWord :: Prelude.String
, amount :: Value
}
deriving stock (Prelude.Eq, Prelude.Show, Generic)
deriving anyclass (FromJSON, ToJSON, ToSchema, ToArgument)

-- | Parameters for the "guess" endpoint
newtype GuessParams = GuessParams
{ guessWord :: String
{ guessWord :: Prelude.String
}
deriving stock (Prelude.Eq, Prelude.Show, Generic)
deriving anyclass (FromJSON, ToJSON, ToSchema, ToArgument)
Expand All @@ -139,19 +138,19 @@ game = do

lock :: (AsContractError e) => Contract () GameSchema e ()
lock = do
logInfo @String "Waiting for lock endpoint..."
logInfo @Prelude.String "Waiting for lock endpoint..."
LockParams secret amt <- endpoint @"lock" @LockParams
logInfo @String $ "Pay " <> show amt <> " to the script"
logInfo @Prelude.String $ "Pay " <> Prelude.show amt <> " to the script"
let tx = Constraints.mustPayToTheScript (hashString secret) amt
void (submitTxConstraints gameInstance tx)

guess :: (AsContractError e) => Contract () GameSchema e ()
guess = do
-- Wait for script to have a UTxO of a least 1 lovelace
logInfo @String "Waiting for script to have a UTxO of at least 1 lovelace"
logInfo @Prelude.String "Waiting for script to have a UTxO of at least 1 lovelace"
utxos <- fundsAtAddressGeq gameAddress (Ada.lovelaceValueOf 1)
-- Wait for a call on the guess endpoint
logInfo @String "Waiting for guess endpoint..."
logInfo @Prelude.String "Waiting for guess endpoint..."
GuessParams theGuess <- endpoint @"guess" @GuessParams

let redeemer = clearString theGuess
Expand All @@ -167,7 +166,7 @@ guess = do
-- This is only for test purposes to have a possible failing transaction.
-- In a real use-case, we would not submit the transaction if the guess is
-- wrong.
logInfo @String "Submitting transaction to guess the secret word"
logInfo @Prelude.String "Submitting transaction to guess the secret word"
void (submitTxConstraintsSpending gameInstance utxos tx)

-- | Find the secret word in the Datum of the UTxOs
Expand All @@ -182,14 +181,14 @@ secretWordValue o = do
Datum d <- Map.lookup dh $ Ledger.txData $ Ledger.txOutTxTx o
PlutusTx.fromData d

lockTrace :: Wallet -> String -> EmulatorTrace ()
lockTrace :: Wallet -> Prelude.String -> EmulatorTrace ()
lockTrace wallet secretWord = do
hdl <- Trace.activateContractWallet wallet (lock @ContractError)
void $ Trace.waitNSlots 1
Trace.callEndpoint @"lock" hdl (LockParams secretWord (Ada.adaValueOf 10))
void $ Trace.waitNSlots 1

guessTrace :: Wallet -> String -> EmulatorTrace ()
guessTrace :: Wallet -> Prelude.String -> EmulatorTrace ()
guessTrace wallet guessWord = do
hdl <- Trace.activateContractWallet wallet (guess @ContractError)
void $ Trace.waitNSlots 1
Expand Down
2 changes: 1 addition & 1 deletion examples/test/Spec/Game.hs
Expand Up @@ -59,7 +59,7 @@ tests = testGroup "game"
guessTrace w2 "secret"

, checkPredicate "guess wrong"
(walletFundsChange w2 (Ada.lovelaceValueOf (-99999990))
(walletFundsChange w2 (Ada.lovelaceValueOf 0)
.&&. walletFundsChange w1 (Ada.adaValueOf (-10)))
$ do
lockTrace w1 "secret"
Expand Down
16 changes: 16 additions & 0 deletions nix/default.nix
@@ -0,0 +1,16 @@
let
sources = import ./sources.nix { inherit pkgs; };

plutus = import sources.plutus {};
pkgs = plutus.pkgs;

haskell-nix = pkgs.haskell-nix;

plutus-starter = import ./pkgs {
inherit pkgs haskell-nix sources plutus;
};

in
{
inherit pkgs plutus plutus-starter;
}

0 comments on commit 6fce2d6

Please sign in to comment.