Executive Summary
This example demonstrates conducting a raffle using Marlowe. The contract contains a list of addresses of participants who have entered the raffle, and a random oracle selects and pays one of them. The Blockly diagram below shows a simple raffle with three participants. For large numbers of participants, multiple nested When
statements are used to hierarchically decompose the search for the winner, so that the Plutus execution budget is not exceeded by the Marlowe contract. Instead of awarding to specific addresses, this example could trivially be modified to award to the holders of a sequence of role tokens.
A video demonstration of this example is available.
Create a Haskell program that will generate a contract for the given participants..
The program outputs the file contract.json.
cat << EOI > contract.hs
{-# LANGUAGE NumericUnderscores #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE Trustworthy #-}
module Main (
-- * Entry point
main
-- * Contracts
, makeContract
) where
import Data.Aeson ((.=), encodeFile)
import Data.List.Split (chunksOf)
import Data.Maybe (fromJust)
import Data.String (fromString)
import Data.Text (pack)
import Language.Marlowe.Core.V1.Semantics.Types
import Language.Marlowe.Core.V1.Semantics.Types.Address (deserialiseAddressBech32)
import Plutus.V2.Ledger.Api (POSIXTime(..), TokenName(..))
import System.Environment (getArgs)
-- | Print the contract.
main :: IO ()
main =
do
size : sponsor : oracle : amount : deposit : select : payout : parties <- getArgs
let
readAddress = uncurry Address . fromJust . deserialiseAddressBech32 . pack
contract =
makeContract
(readAddress sponsor)
(readAddress oracle)
(read amount)
(read size)
(zip [1..] $ readAddress <$> parties)
(fromInteger $ read deposit)
(fromInteger $ read select)
(fromInteger $ read payout)
encodeFile "contract.json" contract
makeContract
:: Party
-> Party
-> Integer
-> Int
-> [(Integer, Party)]
-> POSIXTime
-> POSIXTime
-> POSIXTime
-> Contract
makeContract sponsor oracle amount size parties deposit select payout =
makeDeposit sponsor amount deposit
$ selectWinner oracle (toInteger $ length parties) select
$ payWinner sponsor oracle amount size parties payout
ada :: Token
ada = Token "" ""
makeDeposit
:: Party
-> Integer
-> POSIXTime
-> Contract
-> Contract
makeDeposit sponsor amount deadline contract =
When
[Case (Deposit sponsor sponsor ada (Constant amount)) contract]
deadline
Close
selectWinner
:: Party
-> Integer
-> POSIXTime
-> Contract
-> Contract
selectWinner oracle count deadline contract =
When
[Case (Choice (ChoiceId "Random" oracle) [Bound 1 count]) contract]
deadline
Close
payWinner
:: Party
-> Party
-> Integer
-> Int
-> [(Integer, Party)]
-> POSIXTime
-> Contract
payWinner sponsor oracle amount size parties deadline
| length parties <= size = When
[
Case (Notify (ValueEQ (ChoiceValue (ChoiceId "Random" oracle)) (Constant i)))
$ Pay sponsor (Party party) ada (Constant amount) Close
|
(i, party) <- parties
]
deadline
Close
| otherwise = When
[
Case (Notify (ValueLE (ChoiceValue (ChoiceId "Random" oracle)) (Constant . fst $ last parties')))
$ payWinner sponsor oracle amount size parties' deadline
|
let chunks k xs = chunksOf (div (length xs + k - 1) k) xs
, parties' <- chunks size parties
]
deadline
Close
EOI
It is convenient to define serveral constants.
ADA=1000000
SECOND=1000
MINUTE=$((60 * SECOND))
HOUR=$((60 * MINUTE))
Use the preproduction network.
export CARDANO_NODE_SOCKET_PATH=/extra/iohk/networks/preprod/node.socket
export CARDANO_TESTNET_MAGIC=1
Set the signing keys and addresses for parties to the contract.
The Sponsor provides the funds for the raffle.
SPONSOR_NAME=c.marlowe
SPONSOR_SKEY=../keys/$SPONSOR_NAME.skey
SPONSOR_ADDR=$(cat ../keys/$SPONSOR_NAME.testnet.address)
echo "$SPONSOR_NAME "@" $SPONSOR_ADDR"
c.marlowe @ addr_test1vrtntkszteptml4e9ce9l3fsmgavwv4ywunvdnhxv6nw5ksq6737a
The Oracle provides the random number for the raffle.
ORACLE_NAME=f.beaumont
ORACLE_SKEY=../keys/$ORACLE_NAME.skey
ORACLE_ADDR=$(cat ../keys/$ORACLE_NAME.testnet.address)
echo "$ORACLE_NAME" @ "$ORACLE_ADDR"
f.beaumont @ addr_test1vqhqudxtwqcpjqesns79hqgqq2q0xx5q0hnzz5es9492yaqpxltpy
Normally, the list of addresses for the Participants would be provided. Here, for convenience, we just derive each participants's address from the same root private key.
ROOT_PRV=../keys/william-shakespeare.root.prv
Also for convenience, the scholars will share the same stake key.
cardano-wallet key child 1852H/1815H/0H/2/0 < "$ROOT_PRV" \
| cardano-cli key convert-cardano-address-key --shelley-stake-key --signing-key-file /dev/stdin --out-file /dev/stdout \
| cardano-cli key verification-key --signing-key-file /dev/stdin --verification-key-file /dev/stdout \
| cardano-cli key non-extended-key --extended-verification-key-file /dev/stdin --verification-key-file ../keys/william-shakespeare.stake.vkey
STAKE_ADDR=`cardano-cli stake-address build --testnet-magic "$CARDANO_TESTNET_MAGIC" --stake-verification-key-file ../keys/william-shakespeare.stake.vkey`
echo "Stake address = $STAKE_ADDR"
Stake address = stake_test1urplvp2a7dythh6yxutd0qlzzkncr3gy5ftvxj02d3etafqjugc5h
Set the number of scholars.
NUMBER_OF_PARTICIPANTS=125
Compute the addresses of the scholars.
for j in `seq 1 $NUMBER_OF_PARTICIPANTS`
do
PARTICIPANT_SKEY[$j]=../keys/scholar-$j.skey
PARTICIPANT_ADDR[$j]=$(
cardano-wallet key child 1852H/1815H/0H/0/$j < "$ROOT_PRV" \
| cardano-cli key convert-cardano-address-key --shelley-payment-key --signing-key-file /dev/stdin --out-file "${PARTICIPANT_SKEY[$j]}"
cardano-cli key verification-key --signing-key-file "${PARTICIPANT_SKEY[$j]}" --verification-key-file /dev/stdout \
| cardano-cli address build --testnet-magic "$CARDANO_TESTNET_MAGIC" --payment-verification-key-file /dev/stdin --stake-verification-key-file ../keys/william-shakespeare.stake.vkey \
)
echo "Participant $j" = 1852H/1815H/0H/0/"$((1 + j))" = "${PARTICIPANT_ADDR[$j]}"
done
Participant 1 = 1852H/1815H/0H/0/2 = addr_test1qzenwj7elwatk3mmc368mwnv067fqnuk3x7u4nqw5dezg8wr7cz4mu6gh005gdck67p7y9d8s8zsfgjkcdy75mrjh6jqf6k36p Participant 2 = 1852H/1815H/0H/0/3 = addr_test1qraxynufcduk7ak7nke2jm6pnc32vn7wsmm7ml30cutfgg7r7cz4mu6gh005gdck67p7y9d8s8zsfgjkcdy75mrjh6jq77wfgp Participant 3 = 1852H/1815H/0H/0/4 = addr_test1qzlwepx5u26a8w94kfrkfem6njlam22emyhjscu0lxqrce7r7cz4mu6gh005gdck67p7y9d8s8zsfgjkcdy75mrjh6jq5jnrn3 Participant 4 = 1852H/1815H/0H/0/5 = addr_test1qqjrjfslev50d5jn6qdeztxsqvuaaefq6e4hu55n59grjj7r7cz4mu6gh005gdck67p7y9d8s8zsfgjkcdy75mrjh6jqwhulyr Participant 5 = 1852H/1815H/0H/0/6 = addr_test1qqxrzfv0v8l0lahyc5qsgpug66dafp8njl278g0pter7e3xr7cz4mu6gh005gdck67p7y9d8s8zsfgjkcdy75mrjh6jqcjuuw0 Participant 6 = 1852H/1815H/0H/0/7 = addr_test1qqqfzyuqkvrr7ajgk887sqac8lgzatc6el9uxke4x5g5dg7r7cz4mu6gh005gdck67p7y9d8s8zsfgjkcdy75mrjh6jqkmrpwu Participant 7 = 1852H/1815H/0H/0/8 = addr_test1qp77epd4gy5hrt8pnh6h73se4durwrrkes3u0vj6tycwsq7r7cz4mu6gh005gdck67p7y9d8s8zsfgjkcdy75mrjh6jq7kyfpt Participant 8 = 1852H/1815H/0H/0/9 = addr_test1qqau5f983jd4p5jxx7uxek4axcuuyqgc3q20d9el33ydg4kr7cz4mu6gh005gdck67p7y9d8s8zsfgjkcdy75mrjh6jqvdshe7 Participant 9 = 1852H/1815H/0H/0/10 = addr_test1qry8r8w64h8t6luv4gcvny3snjzmytvrge5euj0ydqchh3wr7cz4mu6gh005gdck67p7y9d8s8zsfgjkcdy75mrjh6jq8f955r Participant 10 = 1852H/1815H/0H/0/11 = addr_test1qzf7zduewu3zjw586mv8r0cxtctwsccsydk7d2hxdcad2s7r7cz4mu6gh005gdck67p7y9d8s8zsfgjkcdy75mrjh6jql02nhc Participant 11 = 1852H/1815H/0H/0/12 = addr_test1qz5acr3p66e5jzts96jhlgh8nhuurydw5364xs9u2kdwlg7r7cz4mu6gh005gdck67p7y9d8s8zsfgjkcdy75mrjh6jqrudtl4 Participant 12 = 1852H/1815H/0H/0/13 = addr_test1qp85hggjkyjzq32m9hk6yfwp8xdz0j6kq7g8j4f2akfl9ckr7cz4mu6gh005gdck67p7y9d8s8zsfgjkcdy75mrjh6jq8xh40m Participant 13 = 1852H/1815H/0H/0/14 = addr_test1qp5uceg0yhxgra7a8emm0d4k8v6qqm4g3tg65ywtqkhcaawr7cz4mu6gh005gdck67p7y9d8s8zsfgjkcdy75mrjh6jqyctq4d Participant 14 = 1852H/1815H/0H/0/15 = addr_test1qqs5whf8xtzdn9myltr7svnug89g5hr48u4zl3lugcrxr67r7cz4mu6gh005gdck67p7y9d8s8zsfgjkcdy75mrjh6jqruqfn5 Participant 15 = 1852H/1815H/0H/0/16 = addr_test1qrj49qkfmr72mgmt3lsktde0havnv72yp9qsvsq6365dyp7r7cz4mu6gh005gdck67p7y9d8s8zsfgjkcdy75mrjh6jqnpl2rv Participant 16 = 1852H/1815H/0H/0/17 = addr_test1qqgdvj84rncnlm754fwttn3py73hp85454tzxzll9sk98rkr7cz4mu6gh005gdck67p7y9d8s8zsfgjkcdy75mrjh6jqj6jhze Participant 17 = 1852H/1815H/0H/0/18 = addr_test1qrjk5w2t35r7qpuc0mlxcuazvta0e4d8wsn7mq6wpq4fa2kr7cz4mu6gh005gdck67p7y9d8s8zsfgjkcdy75mrjh6jq0zqdga Participant 18 = 1852H/1815H/0H/0/19 = addr_test1qrnartu48wqykfavssdsgsz6vvgqxgv9s43tgpzrauh6ugwr7cz4mu6gh005gdck67p7y9d8s8zsfgjkcdy75mrjh6jqwu7lzs Participant 19 = 1852H/1815H/0H/0/20 = addr_test1qpftg7deaxswzauukv2hqsegtrr4q680ayd6683k3rg8gkkr7cz4mu6gh005gdck67p7y9d8s8zsfgjkcdy75mrjh6jqv7jm9y Participant 20 = 1852H/1815H/0H/0/21 = addr_test1qzx9gsxhj09ne3vz73jzg25calq9skl3fxwedxdfu6y7gdkr7cz4mu6gh005gdck67p7y9d8s8zsfgjkcdy75mrjh6jqvt6lj0 Participant 21 = 1852H/1815H/0H/0/22 = addr_test1qzlv9amdympgu47t6tu4ec5lz6uhu2qnq8ulwk9caasm7f7r7cz4mu6gh005gdck67p7y9d8s8zsfgjkcdy75mrjh6jqulv0pl Participant 22 = 1852H/1815H/0H/0/23 = addr_test1qq6nzgz24yj8u2fy45psnrn4emdwh7scjh29j43z3pv5rckr7cz4mu6gh005gdck67p7y9d8s8zsfgjkcdy75mrjh6jq7h6t4e Participant 23 = 1852H/1815H/0H/0/24 = addr_test1qrhpp4kv5vxpr0kqerx5stkyfqghf8pjltmcucdscuzvg57r7cz4mu6gh005gdck67p7y9d8s8zsfgjkcdy75mrjh6jqkeka27 Participant 24 = 1852H/1815H/0H/0/25 = addr_test1qzlweggfq6ara5tytufktkcyjv7j29garuhyufz5ryzxnqwr7cz4mu6gh005gdck67p7y9d8s8zsfgjkcdy75mrjh6jq2lh7qe Participant 25 = 1852H/1815H/0H/0/26 = addr_test1qp0t92r5ep5suj08mpk8mcy7phfuq3607wmksp8z407z6kkr7cz4mu6gh005gdck67p7y9d8s8zsfgjkcdy75mrjh6jq2xwugk Participant 26 = 1852H/1815H/0H/0/27 = addr_test1qzhdl8anw4ssr75uguffuem6227ay9rh3wp855pq6scjc5xr7cz4mu6gh005gdck67p7y9d8s8zsfgjkcdy75mrjh6jqe2smw4 Participant 27 = 1852H/1815H/0H/0/28 = addr_test1qzg57krydk30ydzd39ltjvs9wqd3jsf2er5e8asr4faycfxr7cz4mu6gh005gdck67p7y9d8s8zsfgjkcdy75mrjh6jqmzupaz Participant 28 = 1852H/1815H/0H/0/29 = addr_test1qpcfw8xjj9vk7889m45mpw4lnmt5ackful200xxp6q3r98wr7cz4mu6gh005gdck67p7y9d8s8zsfgjkcdy75mrjh6jqez5l32 Participant 29 = 1852H/1815H/0H/0/30 = addr_test1qzyp0dv2hq77jvhk4kh3y45g63tfx759ufwcsu892ukvegkr7cz4mu6gh005gdck67p7y9d8s8zsfgjkcdy75mrjh6jqqun809 Participant 30 = 1852H/1815H/0H/0/31 = addr_test1qp5g75sm5esea8alu07e8c5k63ywns5tq74lvh8ursr48s7r7cz4mu6gh005gdck67p7y9d8s8zsfgjkcdy75mrjh6jqjpx5tl Participant 31 = 1852H/1815H/0H/0/32 = addr_test1qpy8fx7kasu376v3c9pskxckj5stk6ejy2nswnq0requ45kr7cz4mu6gh005gdck67p7y9d8s8zsfgjkcdy75mrjh6jqm0r9l6 Participant 32 = 1852H/1815H/0H/0/33 = addr_test1qpazh38gxxnt6yxafz8vf0ryrdc8n8tyc4xlv97c7f8qqfwr7cz4mu6gh005gdck67p7y9d8s8zsfgjkcdy75mrjh6jq5zqhdp Participant 33 = 1852H/1815H/0H/0/34 = addr_test1qpf5pakhjntq8fyxmtc6gv6wf8c5dz8k9dv3nk06dk423awr7cz4mu6gh005gdck67p7y9d8s8zsfgjkcdy75mrjh6jq4kdl8u Participant 34 = 1852H/1815H/0H/0/35 = addr_test1qpfhfug63l0ys2a2vm0wldmxjjlaqgk4u280m4pmk6f8cp7r7cz4mu6gh005gdck67p7y9d8s8zsfgjkcdy75mrjh6jqpdfphd Participant 35 = 1852H/1815H/0H/0/36 = addr_test1qrpjhy8rnc9h50vusd4tsh2nfep9w6n7qutdzs2gpjqfh6xr7cz4mu6gh005gdck67p7y9d8s8zsfgjkcdy75mrjh6jqffy4uy Participant 36 = 1852H/1815H/0H/0/37 = addr_test1qpdsderx7fdh3vx42sx8j4kjcxj3k2d58fgsd5ptya5ulywr7cz4mu6gh005gdck67p7y9d8s8zsfgjkcdy75mrjh6jq2ruk85 Participant 37 = 1852H/1815H/0H/0/38 = addr_test1qq4fsl04nuu03njzwh6n89uhgu63x9ypjeg84q4pdzvqttkr7cz4mu6gh005gdck67p7y9d8s8zsfgjkcdy75mrjh6jq7ywduq Participant 38 = 1852H/1815H/0H/0/39 = addr_test1qq5gmdhh65mxm3pje855vwsgfrj90wye43grnq3zzu9ug0wr7cz4mu6gh005gdck67p7y9d8s8zsfgjkcdy75mrjh6jql9ku83 Participant 39 = 1852H/1815H/0H/0/40 = addr_test1qpummduqr4zq3vkxmjxqwvatrfm2wgeefn23p3y5us2rxpkr7cz4mu6gh005gdck67p7y9d8s8zsfgjkcdy75mrjh6jqntpetu Participant 40 = 1852H/1815H/0H/0/41 = addr_test1qzwxx7va22maycmt0wfhzw4q6zy885658swh3yzvxq5860wr7cz4mu6gh005gdck67p7y9d8s8zsfgjkcdy75mrjh6jqez9c58 Participant 41 = 1852H/1815H/0H/0/42 = addr_test1qp7sp0w8ljvmau95rsscmg8zegmem4cya6hmyr276hr3c7kr7cz4mu6gh005gdck67p7y9d8s8zsfgjkcdy75mrjh6jqpm58rl Participant 42 = 1852H/1815H/0H/0/43 = addr_test1qzwsqegmud7dcr8prnslmhh97war84dh4z9t7v5xgh8jh2xr7cz4mu6gh005gdck67p7y9d8s8zsfgjkcdy75mrjh6jqnq9x0k Participant 43 = 1852H/1815H/0H/0/44 = addr_test1qz2nmcnwdrxrksk4fvfw9x3myrxndcwhqwkxe5f9lw2azyxr7cz4mu6gh005gdck67p7y9d8s8zsfgjkcdy75mrjh6jqtxn85r Participant 44 = 1852H/1815H/0H/0/45 = addr_test1qpek6vrkj00g5vcvzxs74xrzt6clfwc964puu2k32f76hk7r7cz4mu6gh005gdck67p7y9d8s8zsfgjkcdy75mrjh6jqv26z8x Participant 45 = 1852H/1815H/0H/0/46 = addr_test1qq8ses7vgfl9rmj0tjtzvt3r7twpku4cv3c7naxtltlwwqwr7cz4mu6gh005gdck67p7y9d8s8zsfgjkcdy75mrjh6jq34fkvd Participant 46 = 1852H/1815H/0H/0/47 = addr_test1qpggkalsqjuc4t2pj7arzf66he2u7eultqpq3vc7xexunl7r7cz4mu6gh005gdck67p7y9d8s8zsfgjkcdy75mrjh6jqw03sf5 Participant 47 = 1852H/1815H/0H/0/48 = addr_test1qzpjuk3pjy47s5pt7danm0d2765e9w8ana9jms38xd0ghfxr7cz4mu6gh005gdck67p7y9d8s8zsfgjkcdy75mrjh6jqs6uqev Participant 48 = 1852H/1815H/0H/0/49 = addr_test1qpevx0exxesd4yz5xl0zsuf5rnlg30gkm9l6xtph3ajed2wr7cz4mu6gh005gdck67p7y9d8s8zsfgjkcdy75mrjh6jqpd5pd8 Participant 49 = 1852H/1815H/0H/0/50 = addr_test1qqvtgtjgsqcr96wv0xw4cgpjz0qatr7r0g3hfk2tu2xvlhwr7cz4mu6gh005gdck67p7y9d8s8zsfgjkcdy75mrjh6jq54hatp Participant 50 = 1852H/1815H/0H/0/51 = addr_test1qq2hewgkma04wx6udewv6heh3rdvw2agp3gtwa96cz9k4kkr7cz4mu6gh005gdck67p7y9d8s8zsfgjkcdy75mrjh6jqa6sxxs Participant 51 = 1852H/1815H/0H/0/52 = addr_test1qr5zm006w3nd3etsmttwyk298pu65jwwuk4wc8s2zhsv59kr7cz4mu6gh005gdck67p7y9d8s8zsfgjkcdy75mrjh6jq9zk0w9 Participant 52 = 1852H/1815H/0H/0/53 = addr_test1qp9p3fh0jh49ypts970970zve2e7lwx3x2wqdgurmumwz5xr7cz4mu6gh005gdck67p7y9d8s8zsfgjkcdy75mrjh6jqkrrxts Participant 53 = 1852H/1815H/0H/0/54 = addr_test1qp4rwv6whephyqm8l4esavujwnfdhenqqnxwdvtdp7zampxr7cz4mu6gh005gdck67p7y9d8s8zsfgjkcdy75mrjh6jq5q7hz7 Participant 54 = 1852H/1815H/0H/0/55 = addr_test1qze89as8wq67p63gpcj0ycg8rgrs4d5gfykkgq463py404xr7cz4mu6gh005gdck67p7y9d8s8zsfgjkcdy75mrjh6jqwy6dex Participant 55 = 1852H/1815H/0H/0/56 = addr_test1qza96yahn4m8awmzpqwk6d07z6lxfyphqcwvar6e23pj27xr7cz4mu6gh005gdck67p7y9d8s8zsfgjkcdy75mrjh6jq6yduup Participant 56 = 1852H/1815H/0H/0/57 = addr_test1qp37f8ysp9ez3wmfnr5vh3hl4z2670fvs2exln2w0zgs3cxr7cz4mu6gh005gdck67p7y9d8s8zsfgjkcdy75mrjh6jqv49m2k Participant 57 = 1852H/1815H/0H/0/58 = addr_test1qrsgyj9wcl9jjqkl0nm8rf28m4gs54grycup9a5krezaqcxr7cz4mu6gh005gdck67p7y9d8s8zsfgjkcdy75mrjh6jqfjkpp8 Participant 58 = 1852H/1815H/0H/0/59 = addr_test1qzn4wvyj6mvdyaxnj8yhpujxa9m6amp3t5gaevw8etmd9a7r7cz4mu6gh005gdck67p7y9d8s8zsfgjkcdy75mrjh6jqw7gjta Participant 59 = 1852H/1815H/0H/0/60 = addr_test1qz3gznr4hw3jg3t4llp0pezdrwqsjz5ngjx7vsq9pklqwwwr7cz4mu6gh005gdck67p7y9d8s8zsfgjkcdy75mrjh6jq3j4820 Participant 60 = 1852H/1815H/0H/0/61 = addr_test1qq588p04pqus2358226a0fjcvcxq22u4zc0edal0fw3m77wr7cz4mu6gh005gdck67p7y9d8s8zsfgjkcdy75mrjh6jqp9h4tq Participant 61 = 1852H/1815H/0H/0/62 = addr_test1qq84w78q9lvfp7jart6nl2qckwzmuww37q2yja8cpqp5607r7cz4mu6gh005gdck67p7y9d8s8zsfgjkcdy75mrjh6jq8z60t9 Participant 62 = 1852H/1815H/0H/0/63 = addr_test1qrl98h2rr2ltcrhsnsh5n3z5ywnhnx6gtnp90t5gugqel5xr7cz4mu6gh005gdck67p7y9d8s8zsfgjkcdy75mrjh6jqtvxcrm Participant 63 = 1852H/1815H/0H/0/64 = addr_test1qr0zwzyd6tu9jgzztwcnf3d5s7uupggplxdr8n3h88lzc6xr7cz4mu6gh005gdck67p7y9d8s8zsfgjkcdy75mrjh6jqq543s5 Participant 64 = 1852H/1815H/0H/0/65 = addr_test1qrwd8caaqtnjd4xgv3e8j2nhggxh65fq83uwddvky5xvzdkr7cz4mu6gh005gdck67p7y9d8s8zsfgjkcdy75mrjh6jqnan585 Participant 65 = 1852H/1815H/0H/0/66 = addr_test1qzeaxy5zazmp0edr007qq86w59t5l4s4pp0w4er2aumx73xr7cz4mu6gh005gdck67p7y9d8s8zsfgjkcdy75mrjh6jqn67xqz Participant 66 = 1852H/1815H/0H/0/67 = addr_test1qq9tsjye0cjs9rjs0xydxjcq5la729ltvzw7t6lqpvj28gxr7cz4mu6gh005gdck67p7y9d8s8zsfgjkcdy75mrjh6jqjfd45w Participant 67 = 1852H/1815H/0H/0/68 = addr_test1qq3vmljj6xr6qsng04uq40ltjjank8y2wtqavgkk582fg0xr7cz4mu6gh005gdck67p7y9d8s8zsfgjkcdy75mrjh6jq36vy6p Participant 68 = 1852H/1815H/0H/0/69 = addr_test1qz08fqe3n2pglztx8rhh5xa3slh5xtufy7c5c44u49ar6mxr7cz4mu6gh005gdck67p7y9d8s8zsfgjkcdy75mrjh6jqgj4hyp Participant 69 = 1852H/1815H/0H/0/70 = addr_test1qzg75fn3gzefd5x4fj9396d7l898hjsc5de0hfcehy90epxr7cz4mu6gh005gdck67p7y9d8s8zsfgjkcdy75mrjh6jq7u0w62 Participant 70 = 1852H/1815H/0H/0/71 = addr_test1qr7l63r8dg25mzdrarckv0zh9m855mn6he53ha2jtdjd8swr7cz4mu6gh005gdck67p7y9d8s8zsfgjkcdy75mrjh6jqpxcwxy Participant 71 = 1852H/1815H/0H/0/72 = addr_test1qrvkc8v843ap7svs650v7ykarmy8az6l58j8gyvlyx9ng4wr7cz4mu6gh005gdck67p7y9d8s8zsfgjkcdy75mrjh6jqm7cf4s Participant 72 = 1852H/1815H/0H/0/73 = addr_test1qzu0znj2cn7x3rvt0zaq3cjuz4j39h978s0czw0xajux3jkr7cz4mu6gh005gdck67p7y9d8s8zsfgjkcdy75mrjh6jqlw8fme Participant 73 = 1852H/1815H/0H/0/74 = addr_test1qzh92un69kg06t7rtfu4nfjz4xttc4hunwsz7htpqqpfh9kr7cz4mu6gh005gdck67p7y9d8s8zsfgjkcdy75mrjh6jq5egcn6 Participant 74 = 1852H/1815H/0H/0/75 = addr_test1qpym6sp643shhfgdqz2t0krc5vldw5hwlrcj9l6qndn8npkr7cz4mu6gh005gdck67p7y9d8s8zsfgjkcdy75mrjh6jqqknlf8 Participant 75 = 1852H/1815H/0H/0/76 = addr_test1qz0sraafpmnzj0ujahuxljjacg36hxeq4lwdxnhfm9uddnxr7cz4mu6gh005gdck67p7y9d8s8zsfgjkcdy75mrjh6jqwjz4kw Participant 76 = 1852H/1815H/0H/0/77 = addr_test1qqlvsfdqcl8hxkn065m3m0v24k5kpuc0n26a3h5kdedtly7r7cz4mu6gh005gdck67p7y9d8s8zsfgjkcdy75mrjh6jqqz6rz2 Participant 77 = 1852H/1815H/0H/0/78 = addr_test1qrqwjg5jvm7898kem96c3gev2pxytzkcfh5cea0epxhhqtkr7cz4mu6gh005gdck67p7y9d8s8zsfgjkcdy75mrjh6jq3r845y Participant 78 = 1852H/1815H/0H/0/79 = addr_test1qzuqkw9453mm2wqt9x33aduxc2tpjq9czxlq9pxx5tgx8pxr7cz4mu6gh005gdck67p7y9d8s8zsfgjkcdy75mrjh6jqfkn0j3 Participant 79 = 1852H/1815H/0H/0/80 = addr_test1qruhds8vv5w4nd6nlkjewa7aqu9pzff22m8xj0a4aq8myuxr7cz4mu6gh005gdck67p7y9d8s8zsfgjkcdy75mrjh6jqxy85qu Participant 80 = 1852H/1815H/0H/0/81 = addr_test1qrg45zfejwqx9grrzx3aw0nweym5sjyjkgku2cfzs60u7dwr7cz4mu6gh005gdck67p7y9d8s8zsfgjkcdy75mrjh6jqv0j247 Participant 81 = 1852H/1815H/0H/0/82 = addr_test1qphc67n5pw0drrr8r7xdjeckk4l4pyusddvvruaqz78296xr7cz4mu6gh005gdck67p7y9d8s8zsfgjkcdy75mrjh6jqp2xh7y Participant 82 = 1852H/1815H/0H/0/83 = addr_test1qp4gr0dhkvv999madce0dhez4x367wkznahkdmtvjv8yz27r7cz4mu6gh005gdck67p7y9d8s8zsfgjkcdy75mrjh6jqhl28aq Participant 83 = 1852H/1815H/0H/0/84 = addr_test1qpqnnaatl3yr3fc3aw66d8026mjfddmpqzdgql99yxgfyvwr7cz4mu6gh005gdck67p7y9d8s8zsfgjkcdy75mrjh6jqazk3gh Participant 84 = 1852H/1815H/0H/0/85 = addr_test1qzqsv0q9js4udx89yrnadnvdd7nuwv750zz2938sg4fa83wr7cz4mu6gh005gdck67p7y9d8s8zsfgjkcdy75mrjh6jq2efdee Participant 85 = 1852H/1815H/0H/0/86 = addr_test1qrcnznq5m5srjasmxrpkdqc7x4mh02vsru0ws8m82v667hxr7cz4mu6gh005gdck67p7y9d8s8zsfgjkcdy75mrjh6jq8wje78 Participant 86 = 1852H/1815H/0H/0/87 = addr_test1qzamldrpyf6rfneflv2jvh4q03m6gug8amp5hce5ww04l7kr7cz4mu6gh005gdck67p7y9d8s8zsfgjkcdy75mrjh6jq8aa8k9 Participant 87 = 1852H/1815H/0H/0/88 = addr_test1qprs6cc7p6xkuyedjrgg3w8g6r82jmvp8hq7zv8lhlshf07r7cz4mu6gh005gdck67p7y9d8s8zsfgjkcdy75mrjh6jqkplwl4 Participant 88 = 1852H/1815H/0H/0/89 = addr_test1qprks5kj24y2r2hdvav6rkdwef2m757epr54xnjc2tr398wr7cz4mu6gh005gdck67p7y9d8s8zsfgjkcdy75mrjh6jqla8ngy Participant 89 = 1852H/1815H/0H/0/90 = addr_test1qzz0xx5cz6su3kh6gldu7wzp2mhcffytwv0upg43hdkc0nxr7cz4mu6gh005gdck67p7y9d8s8zsfgjkcdy75mrjh6jqhw08as Participant 90 = 1852H/1815H/0H/0/91 = addr_test1qrjwq07mqh4lhwamstx3gy69meqsvn7pylxtmhfadf7ut6kr7cz4mu6gh005gdck67p7y9d8s8zsfgjkcdy75mrjh6jqp6e7ud Participant 91 = 1852H/1815H/0H/0/92 = addr_test1qq6peyeak7ftpdwq7lgahssj4s5sslhcgcfd4wfgxtf52xkr7cz4mu6gh005gdck67p7y9d8s8zsfgjkcdy75mrjh6jqwzhdsg Participant 92 = 1852H/1815H/0H/0/93 = addr_test1qzmwzfavsycupvv35xjchq7w4q6yqxz67r5plrwglqsnve7r7cz4mu6gh005gdck67p7y9d8s8zsfgjkcdy75mrjh6jqkktlxy Participant 93 = 1852H/1815H/0H/0/94 = addr_test1qzd3z04g5wlkgztjchdqkgg9j6hysmgk6xsgxf3m37glfl7r7cz4mu6gh005gdck67p7y9d8s8zsfgjkcdy75mrjh6jqnaeh54 Participant 94 = 1852H/1815H/0H/0/95 = addr_test1qqg3rrcvdvz2lrvayeakmt2ahlgv84y29ggjyhya7p80a67r7cz4mu6gh005gdck67p7y9d8s8zsfgjkcdy75mrjh6jquj2zsf Participant 95 = 1852H/1815H/0H/0/96 = addr_test1qq3k3mxh25zclz5hg95rzskf2k5m2z5qwr2ejcyant43evwr7cz4mu6gh005gdck67p7y9d8s8zsfgjkcdy75mrjh6jqqpmnnz Participant 96 = 1852H/1815H/0H/0/97 = addr_test1qzeexmvhgklvm0sm5a93has8la8xzkalnghulxq07zs84q7r7cz4mu6gh005gdck67p7y9d8s8zsfgjkcdy75mrjh6jqadklvz Participant 97 = 1852H/1815H/0H/0/98 = addr_test1qz0djqvxvfg7xmpzr98jgmlzv870jg80qctaemrzhx7rx6kr7cz4mu6gh005gdck67p7y9d8s8zsfgjkcdy75mrjh6jqdqcucz Participant 98 = 1852H/1815H/0H/0/99 = addr_test1qpjsldudrtytstlgkfmy7z6dymu4yra9uperq2chmu9xaukr7cz4mu6gh005gdck67p7y9d8s8zsfgjkcdy75mrjh6jq00l0a0 Participant 99 = 1852H/1815H/0H/0/100 = addr_test1qzs2warxngdak4jdtmg0q7j2n3yc6gtrmhqwvq4gaq602lxr7cz4mu6gh005gdck67p7y9d8s8zsfgjkcdy75mrjh6jqjxlpdl Participant 100 = 1852H/1815H/0H/0/101 = addr_test1qqtdfkwpjq7amgjvka4czt7cqvxa4zhe3jmaa8jaqpjxfhkr7cz4mu6gh005gdck67p7y9d8s8zsfgjkcdy75mrjh6jq6hmtxv Participant 101 = 1852H/1815H/0H/0/102 = addr_test1qpuqse785jwx6cyrkr83g6q2a528kqruwzrdcwquum7qz6kr7cz4mu6gh005gdck67p7y9d8s8zsfgjkcdy75mrjh6jqnh22p9 Participant 102 = 1852H/1815H/0H/0/103 = addr_test1qqztp3j2j43acu3scu7hwscsgsq2xx90dfdxcf50tl08l47r7cz4mu6gh005gdck67p7y9d8s8zsfgjkcdy75mrjh6jqfvns3t Participant 103 = 1852H/1815H/0H/0/104 = addr_test1qpt72nadqr805aqvfry3u2s38v0hdtjtr74r0023fsr4zvxr7cz4mu6gh005gdck67p7y9d8s8zsfgjkcdy75mrjh6jqhf8n46 Participant 104 = 1852H/1815H/0H/0/105 = addr_test1qruevfw9n99qk2q6ernw2n65qcagq88yk265mretfcu4g2wr7cz4mu6gh005gdck67p7y9d8s8zsfgjkcdy75mrjh6jqj8twmy Participant 105 = 1852H/1815H/0H/0/106 = addr_test1qrs3rg737vy3gnsu4mp8qxuytzqjhyt8g6jxfr5a06lac0xr7cz4mu6gh005gdck67p7y9d8s8zsfgjkcdy75mrjh6jqfsnj0u Participant 106 = 1852H/1815H/0H/0/107 = addr_test1qq8t9rd2fsky50j0yspjdqptunnwjh275jl03uhx8r7hsw7r7cz4mu6gh005gdck67p7y9d8s8zsfgjkcdy75mrjh6jqa29ek7 Participant 107 = 1852H/1815H/0H/0/108 = addr_test1qqsaemxqnw6h3m3vxudk9utms4p7jzmw2g0m53mnqy75chkr7cz4mu6gh005gdck67p7y9d8s8zsfgjkcdy75mrjh6jq2sl26u Participant 108 = 1852H/1815H/0H/0/109 = addr_test1qraukfjgvvfyctgv904l3umuxergjpqxsnwcwpcx5gvww0kr7cz4mu6gh005gdck67p7y9d8s8zsfgjkcdy75mrjh6jqajqgjt Participant 109 = 1852H/1815H/0H/0/110 = addr_test1qzjj5cr97f8pagqad0fgh24qpvmmagnmuzzt228x3rfc5zkr7cz4mu6gh005gdck67p7y9d8s8zsfgjkcdy75mrjh6jqx8mm60 Participant 110 = 1852H/1815H/0H/0/111 = addr_test1qrq0p9xvedjjpknruvq9p3staswefl92rll8spzq3lch0hxr7cz4mu6gh005gdck67p7y9d8s8zsfgjkcdy75mrjh6jqulk76y Participant 111 = 1852H/1815H/0H/0/112 = addr_test1qzhwep7fau3w2y9cru072aamwakclwkaeqr3gd4ee2x7g2xr7cz4mu6gh005gdck67p7y9d8s8zsfgjkcdy75mrjh6jqleafk3 Participant 112 = 1852H/1815H/0H/0/113 = addr_test1qzjlfngyh2q9vvcm3kn2wmysw24yrp46ywyxupec24xnc4kr7cz4mu6gh005gdck67p7y9d8s8zsfgjkcdy75mrjh6jqwnmz5x Participant 113 = 1852H/1815H/0H/0/114 = addr_test1qrqxwcuyg2pzy8kawmk76ry2y3c4taggnks3yjyf8gfamxkr7cz4mu6gh005gdck67p7y9d8s8zsfgjkcdy75mrjh6jqdqs9h6 Participant 114 = 1852H/1815H/0H/0/115 = addr_test1qp500fm2wxw7szkmnz9a0e5azcxg7dpzkdp09tqvez2en2xr7cz4mu6gh005gdck67p7y9d8s8zsfgjkcdy75mrjh6jquptalx Participant 115 = 1852H/1815H/0H/0/116 = addr_test1qzjmk05yd5g3anhaj6t5t4gtzz834x0ahpy25f90ud4nefxr7cz4mu6gh005gdck67p7y9d8s8zsfgjkcdy75mrjh6jq4y68e5 Participant 116 = 1852H/1815H/0H/0/117 = addr_test1qrve4lfj4x7umy85u8s7xcx6dc9sr60hk3epnsjkd2hxd9xr7cz4mu6gh005gdck67p7y9d8s8zsfgjkcdy75mrjh6jqtzmx35 Participant 117 = 1852H/1815H/0H/0/118 = addr_test1qq2espt3r5qvdqd4jfzlwsfdy6xedtcy4u7snvj59wxfajxr7cz4mu6gh005gdck67p7y9d8s8zsfgjkcdy75mrjh6jqn90dx2 Participant 118 = 1852H/1815H/0H/0/119 = addr_test1qrkwcf35ezgnt9tnzaacgrmjakkwjk8gnjcvd3lke7vk7vxr7cz4mu6gh005gdck67p7y9d8s8zsfgjkcdy75mrjh6jq6juq9g Participant 119 = 1852H/1815H/0H/0/120 = addr_test1qrflw25khkgf5suz65na39ytaqpdxycchlk482d8vvmv827r7cz4mu6gh005gdck67p7y9d8s8zsfgjkcdy75mrjh6jqdz8yn0 Participant 120 = 1852H/1815H/0H/0/121 = addr_test1qp7jwjqlhe4pc5cg8qv0zxea63l9eaq9dwaqz94cjlp2hzkr7cz4mu6gh005gdck67p7y9d8s8zsfgjkcdy75mrjh6jq2w50u6 Participant 121 = 1852H/1815H/0H/0/122 = addr_test1qpfpzhdkxsgf7x0nv49qp7rpexaf0zuf92quzzm0qxfh2nxr7cz4mu6gh005gdck67p7y9d8s8zsfgjkcdy75mrjh6jq8lhqey Participant 122 = 1852H/1815H/0H/0/123 = addr_test1qpu5pmlsr8qttzl6f3xt3zr92fu040g5qdq45w0240gdgv7r7cz4mu6gh005gdck67p7y9d8s8zsfgjkcdy75mrjh6jqscjqmc Participant 123 = 1852H/1815H/0H/0/124 = addr_test1qzpnj7gyz88txgnde68hcxcxvvx5wjvgpafk75ppx737eekr7cz4mu6gh005gdck67p7y9d8s8zsfgjkcdy75mrjh6jqu6jyu0 Participant 124 = 1852H/1815H/0H/0/125 = addr_test1qzl8mgpv46z02a5pnvltgg4j6zvwsr640ets9etmmlpsh3kr7cz4mu6gh005gdck67p7y9d8s8zsfgjkcdy75mrjh6jqzkfnsp Participant 125 = 1852H/1815H/0H/0/126 = addr_test1qrh7j6xzdt2e88grpcrslshk9slaq2pr6rh73dn8djun8xxr7cz4mu6gh005gdck67p7y9d8s8zsfgjkcdy75mrjh6jq6l4eps
Start the contract at the current time.
NOW=$((`date -u +%s` * 1000))
echo "NOW = $NOW" = "`date -d @$((NOW / 1000))`"
NOW = 1683600635000 = Mon May 8 08:50:35 PM MDT 2023
FUNDING_DEADLINE=$((`date -u +%s` * SECOND + 1 * HOUR))
echo "FUNDING_DEADLINE = $FUNDING_DEADLINE" = "`date -d @$((FUNDING_DEADLINE / 1000))`"
FUNDING_DEADLINE = 1683604238000 = Mon May 8 09:50:38 PM MDT 2023
SELECTION_DEADLINE=$((`date -u +%s` * SECOND + 2 * HOUR))
echo "SELECTION_DEADLINE = $SELECTION_DEADLINE" = "`date -d @$((SELECTION_DEADLINE / 1000))`"
SELECTION_DEADLINE = 1683607840000 = Mon May 8 10:50:40 PM MDT 2023
AWARD_DEADLINE=$((`date -u +%s` * SECOND + 3 * HOUR))
echo "AWARD_DEADLINE = $AWARD_DEADLINE" = "`date -d @$((AWARD_DEADLINE / 1000))`"
AWARD_DEADLINE = 1683611444000 = Mon May 8 11:50:44 PM MDT 2023
AWARD_AMOUNT=$((100 * ADA))
echo "AWARD_AMOUNT = $AWARD_AMOUNT lovelace"
AWARD_AMOUNT = 100000000 lovelace
Now run the Haskell program to generate the contract. We'll use a fivefold split to hierarchically search for the winner, so that the Plutus execution budget is not exceeded.
SIZE=5
echo "SIZE = $SIZE"
SIZE = 5
runhaskell contract.hs \
"$SIZE" \
"$SPONSOR_ADDR" \
"$ORACLE_ADDR" \
"$AWARD_AMOUNT" \
"$FUNDING_DEADLINE" \
"$SELECTION_DEADLINE" \
"$AWARD_DEADLINE" \
${PARTICIPANT_ADDR[@]}
We put 2 ada in the initial contract when it is created, in order to satisfy the ledger's minimum-UTxO rule.
MIN_LOVELACE=$((2 * ADA))
yaml2json << EOI > state.json
accounts:
- - - address: $SPONSOR_ADDR
- currency_symbol: ''
token_name: ''
- $MIN_LOVELACE
boundValues: []
choices: []
minTime: 1
EOI
cat state.json
{"accounts":[[[{"address":"addr_test1vrtntkszteptml4e9ce9l3fsmgavwv4ywunvdnhxv6nw5ksq6737a"},{"currency_symbol":"","token_name":""}],2000000]],"boundValues":[],"choices":[],"minTime":1}
Merkleize the contract when we initialize it.
marlowe-cli run initialize \
--contract-file contract.json \
--state-file state.json \
--out-file marlowe-1.json \
--merkleize \
--permanently-without-staking
The sponsor submits the creation transaction.
TX[1]=$(
/extra/iohk/bin/marlowe-cli run auto-execute \
--marlowe-out-file marlowe-1.json \
--change-address "$SPONSOR_ADDR" \
--required-signer "$SPONSOR_SKEY" \
--out-file /dev/null \
--submit 600 \
--print-stats \
| sed -e 's/^TxId "\(.*\)"$/\1/' \
)
echo "TX[1] = ${TX[1]}"
echo 'https://preprod.cardanoscan.io/transaction/'"${TX[1]}"'?tab=utxo'
Fee: Lovelace 196081 Size: 579 / 16384 = 3% Execution units: Memory: 0 / 14000000 = 0% Steps: 0 / 10000000000 = 0% TX[1] = c5f1307a4f2d12b419b1ed381a8ccefcf4c2a019c9e2f663da24cb3a91258206 https://preprod.cardanoscan.io/transaction/c5f1307a4f2d12b419b1ed381a8ccefcf4c2a019c9e2f663da24cb3a91258206?tab=utxo
The sponsor prepares the transaction to deposit the funds.
marlowe-cli run prepare \
--deposit-account "$SPONSOR_ADDR" \
--deposit-party "$SPONSOR_ADDR" \
--deposit-amount "$AWARD_AMOUNT" \
--invalid-before "$((($(date -u +%s) - 1 * 60) * 1000))" \
--invalid-hereafter "$((($(date -u +%s) + 5 * 60) * 1000))" \
--marlowe-file marlowe-1.json \
--out-file marlowe-2.json \
2> /dev/null
TransactionInput {txInterval = (POSIXTime {getPOSIXTime = 1683600666000},POSIXTime {getPOSIXTime = 1683601026999}), txInputs = [NormalInput (IDeposit "\"addr_test1vrtntkszteptml4e9ce9l3fsmgavwv4ywunvdnhxv6nw5ksq6737a\"" "\"addr_test1vrtntkszteptml4e9ce9l3fsmgavwv4ywunvdnhxv6nw5ksq6737a\"" (Token "" "") 100000000)]}
Submit the transaction and await its confirmation.
TX[2]=$(
/extra/iohk/bin/marlowe-cli run auto-execute \
--tx-in-marlowe "${TX[1]}#1" \
--marlowe-in-file marlowe-1.json \
--marlowe-out-file marlowe-2.json \
--change-address "$SPONSOR_ADDR" \
--required-signer "$SPONSOR_SKEY" \
--out-file /dev/null \
--submit 600 \
--print-stats \
| sed -e 's/^TxId "\(.*\)"$/\1/' \
)
echo "TX[2] = ${TX[2]}"
echo 'https://preprod.cardanoscan.io/transaction/'"${TX[2]}"'?tab=utxo'
Fee: Lovelace 625267 Size: 1250 / 16384 = 7% Execution units: Memory: 5168716 / 14000000 = 36% Steps: 1405524214 / 10000000000 = 14% TX[2] = 3c832480473eedcbb911855be6e9f434d31ccb91daa087ee162c6a5c9d8b28c3 https://preprod.cardanoscan.io/transaction/3c832480473eedcbb911855be6e9f434d31ccb91daa087ee162c6a5c9d8b28c3?tab=utxo
The oracle fetches a truly random integer from RANDOM.ORG.
SELECTION=$(curl -sS "https://www.random.org/integers/?num=1&min=1&max="$NUMBER_OF_PARTICIPANTS"&col=1&base=10&format=plain&rnd=new")
echo "SELECTION = $SELECTION"
SELECTION = 85
The oracle prepares the transaction with this random choice.
marlowe-cli run prepare \
--choice-name Random \
--choice-party "$ORACLE_ADDR" \
--choice-number "$SELECTION" \
--invalid-before "$((($(date -u +%s) - 1 * 60) * 1000))" \
--invalid-hereafter "$((($(date -u +%s) + 5 * 60) * 1000))" \
--marlowe-file marlowe-2.json \
--out-file marlowe-3.json \
2> /dev/null
TransactionInput {txInterval = (POSIXTime {getPOSIXTime = 1683600721000},POSIXTime {getPOSIXTime = 1683601081999}), txInputs = [NormalInput (IChoice (ChoiceId "Random" "\"addr_test1vqhqudxtwqcpjqesns79hqgqq2q0xx5q0hnzz5es9492yaqpxltpy\"") 85)]}
The oracle submits the transaction and awaits confirmation.
TX[3]=$(
/extra/iohk/bin/marlowe-cli run auto-execute \
--tx-in-marlowe "${TX[2]}#1" \
--marlowe-in-file marlowe-2.json \
--marlowe-out-file marlowe-3.json \
--change-address "$ORACLE_ADDR" \
--required-signer "$ORACLE_SKEY" \
--out-file /dev/null \
--submit 600 \
--print-stats \
| sed -e 's/^TxId "\(.*\)"$/\1/' \
)
echo "TX[3] = ${TX[3]}"
echo 'https://preprod.cardanoscan.io/transaction/'"${TX[3]}"'?tab=utxo'
Fee: Lovelace 833385 Size: 2172 / 16384 = 13% Execution units: Memory: 7171896 / 14000000 = 51% Steps: 2123841881 / 10000000000 = 21% TX[3] = 4d0f2f250203ca39074859ced409f1e4d8b6a2ef81f780c1f21b6920a4d156e4 https://preprod.cardanoscan.io/transaction/4d0f2f250203ca39074859ced409f1e4d8b6a2ef81f780c1f21b6920a4d156e4?tab=utxo
Because the search for the winner has been hierarchically split, we'll need several INotify
actions to walk the hierarchy to the winner. The number of notifications is the logarithm of the number of participants, rounded upwards to the nearest whole number.
DEPTH=$(printf "%.0f" `echo l"($NUMBER_OF_PARTICIPANTS)" / "l($SIZE)" | ~/.nix-profile/bin/bc -l`)
echo "DEPTH = $DEPTH"
DEPTH = 3
Anyone can prepare and submit the notifications, but for convenience the sponsor does so here.
for i in `seq 1 $DEPTH`
do
n=$((i+3))
echo
echo "----- Notify $i -----"
echo
marlowe-cli run prepare \
--notify \
--invalid-before "$((($(date -u +%s) - 1 * 60) * 1000))" \
--invalid-hereafter "$((($(date -u +%s) + 5 * 60) * 1000))" \
--marlowe-file marlowe-$((n-1)).json \
--out-file marlowe-$n.json \
2> /dev/null
TX[$n]=$(
/extra/iohk/bin/marlowe-cli run auto-execute \
--tx-in-marlowe "${TX[$((n-1))]}#1" \
--marlowe-in-file marlowe-$((n-1)).json \
--marlowe-out-file marlowe-$n.json \
--change-address "$SPONSOR_ADDR" \
--required-signer "$SPONSOR_SKEY" \
--out-file /dev/null \
--submit 600 \
--print-stats \
| sed -e 's/^TxId "\(.*\)"$/\1/' \
)
echo "TX[$n] = ${TX[$n]}"
echo 'https://preprod.cardanoscan.io/transaction/'"${TX[$n]}"'?tab=utxo'
done
----- Notify 1 ----- TransactionInput {txInterval = (POSIXTime {getPOSIXTime = 1683600792000},POSIXTime {getPOSIXTime = 1683601152999}), txInputs = [NormalInput INotify]} Fee: Lovelace 913392 Size: 2654 / 16384 = 16% Execution units: Memory: 7896032 / 14000000 = 56% Steps: 2362301577 / 10000000000 = 23% TX[4] = 39981f87fabe70091285af176b8a97b234cc16c6ffde4b948fa39282070af861 https://preprod.cardanoscan.io/transaction/39981f87fabe70091285af176b8a97b234cc16c6ffde4b948fa39282070af861?tab=utxo ----- Notify 2 ----- TransactionInput {txInterval = (POSIXTime {getPOSIXTime = 1683600803000},POSIXTime {getPOSIXTime = 1683601163999}), txInputs = [NormalInput INotify]} Fee: Lovelace 896647 Size: 2654 / 16384 = 16% Execution units: Memory: 7679900 / 14000000 = 54% Steps: 2303018611 / 10000000000 = 23% TX[5] = 39ee58ea4d271c29f7c529e0730c8b22acd69fba58f2bd819b1c3ae310b1e4fc https://preprod.cardanoscan.io/transaction/39ee58ea4d271c29f7c529e0730c8b22acd69fba58f2bd819b1c3ae310b1e4fc?tab=utxo ----- Notify 3 ----- TransactionInput {txInterval = (POSIXTime {getPOSIXTime = 1683600839000},POSIXTime {getPOSIXTime = 1683601199999}), txInputs = [NormalInput INotify]} Payment 1 Acccount: "\"addr_test1vrtntkszteptml4e9ce9l3fsmgavwv4ywunvdnhxv6nw5ksq6737a\"" Payee: Party "\"addr_test1qrcnznq5m5srjasmxrpkdqc7x4mh02vsru0ws8m82v667hxr7cz4mu6gh005gdck67p7y9d8s8zsfgjkcdy75mrjh6jq8wje78\"" Ada: Lovelace {getLovelace = 100000000} Payment 2 Acccount: "\"addr_test1vrtntkszteptml4e9ce9l3fsmgavwv4ywunvdnhxv6nw5ksq6737a\"" Payee: Party "\"addr_test1vrtntkszteptml4e9ce9l3fsmgavwv4ywunvdnhxv6nw5ksq6737a\"" Ada: Lovelace {getLovelace = 2000000} Fee: Lovelace 712216 Size: 1490 / 16384 = 9% Execution units: Memory: 6153780 / 14000000 = 43% Steps: 1676694305 / 10000000000 = 16% TX[6] = 296d39e690bf0e8d6bf65075b8fe4ce0efd7b1acc2471edd1c32b3b906d5f824 https://preprod.cardanoscan.io/transaction/296d39e690bf0e8d6bf65075b8fe4ce0efd7b1acc2471edd1c32b3b906d5f824?tab=utxo
The last notification triggered the payment to the winner and a reimbursement of the sponsor's minimum-UTxO value from creating the contract.
echo "Winner = ${PARTICIPANT_ADDR[$SELECTION]}"
Winner = addr_test1qrcnznq5m5srjasmxrpkdqc7x4mh02vsru0ws8m82v667hxr7cz4mu6gh005gdck67p7y9d8s8zsfgjkcdy75mrjh6jq8wje78
Here is the UTxO with the winnings.
cardano-cli query utxo --testnet-magic "$CARDANO_TESTNET_MAGIC" --address "${PARTICIPANT_ADDR[$SELECTION]}"
TxHash TxIx Amount -------------------------------------------------------------------------------------- 296d39e690bf0e8d6bf65075b8fe4ce0efd7b1acc2471edd1c32b3b906d5f824 2 100000000 lovelace + TxOutDatumNone