w0708d_notify asnap
20220824
Running a simple Marlowe contract (without the backend)
This page describes how to use the asnap utility to generate cardano-cli / marlowe-cli scripts. More about asnap can be found on its gitlab repo: gitlab.com/wmoco/asnap
The execution of contract here is close to the one described on w0708c_notify, but it is fully automated, and will keep on running (creating a new contract, initializing, funding… etc.) until the balance drops below a certain value.
Only the noteworthy changes are mentioned.
The new script 50_loop.sh iterates over the other scripts like this:
forever
do
08_create_contract.sh
10_prepare_initialization.sh
12_execute_initialization.sh
14_prepare_fund.sh
16_execute_fund.sh
18_prepare_notify.sh
20_execute_notify.sh
22_withdraw.sh
BALANCE=`echo '«printf "%.f" .AggregateAda»' | asnap - actor.address`
.. exit if BALANCE < x ADA ..
done
The scripts
All scripts can be found in this zip-file: scripts_708d.zip. You also find the log file ‘example_tx.log’ of a run of 181 iterations, to show that it doesn’t just break after 3 iterations.
00 Set env
Changes:
- environment variable POLICY_ID is read from file ‘policy_id.txt’ (file created in step 06_mint_tokens.sh)
- same for CONTRACT_ADDRESS and PAYOUT_ADDRESS (files contract.address and payout.address are created in step 10_prepare_initialization.sh)
06 Mint the tokens
Script: 06_mint_tokens.sh is mostly the same, except for how the policy_id gets looked up, it’s now a query via asnap:
10 Prepare the initialization
Different way of picking up the contract and payout address, using jq :
12 Execute initialization
Pick up the actor’s transaction which has the greatest amount of pure ADA (no token nor datumhash):
16 Execute fund
Asnap template used to list the parameters for –tx-in-collateral, –tx-in-marlowe and –tx-in
Note ‘EOTX’ is in single quotes, so that the dollar-variables don’t get expanded in this here-document.
The «range ..» loops are pretty self-explanatory except maybe the --tx-in-marlowe which could do with a bit more explanation. Here is that bit of template code put separately:
«range .Alias2AddressMap.actor.TxixList»
«$actorTx := .Tx»
«range $.Alias2AddressMap.contract.TxixList»
«if .DatumHash»«if eq $actorTx .Tx» --tx-in-marlowe «.Txix» \
«end»
«end»
«end»
To make sure that we talk about the same thing:
- a Txix is this “104a836fe33a3d6d44d1328b8ec1f8edf6c8bda2bb915c1b4e6ffc761966fc57#2”
- its Tx is “104a836fe33a3d6d44d1328b8ec1f8edf6c8bda2bb915c1b4e6ffc761966fc57”
- its Ix is “2”
To find the marlowe-txix we loop over the actor.txix’s, and in a nested loop go over the contract’s txix’s to find the common .tx. Extra condition: the contract’s txix must have a datumhash.
18 Prepare notify
No change.
20 Execute notify
cat <<'EOTX' | asnap - actor.address contract.address > execute_tx.sh
. ./00_setenv.sh
marlowe-cli run execute --submit=600 \
--marlowe-in-file 15_marlowe.json \
--marlowe-out-file 19_marlowe.json \
--required-signer actor.skey \
«range .Alias2AddressMap.actor.TxixList»«if .FlagGreatestPureAda» --tx-in-collateral «.Txix» \
«end»«end»«range .Alias2AddressMap.actor.TxixList»«if gt .AggregateTokenQuantity 0»«$actorTx := .Tx»«range $.Alias2AddressMap.contract.TxixList»«if .DatumHash»«if eq $actorTx .Tx» --tx-in-marlowe «.Txix» \
«end»«end»«end»«end»«end»«range .Alias2AddressMap.actor.TxixList» --tx-in «.Txix» \
«end» --tx-out "$ACTOR_ADDRESS+$MINIMUM_ADA+1 $ACTOR_TOKEN" \
--change-address "$ACTOR_ADDRESS" \
--out-file 21_raw.json \
--print-stats
EOTX
22 Withdraw
cat <<EOTX | asnap - actor.address payout.address > execute_tx.sh
. ./00_setenv.sh
marlowe-cli run withdraw --submit=600 \
--marlowe-file 19_marlowe.json \
--role-name "$ACTOR_ROLE" \
--required-signer actor.skey \
«range .Alias2AddressMap.actor.TxixList»«if .FlagGreatestPureAda» --tx-in-collateral «.Txix» \
«end»«end»«range .Alias2AddressMap.payout.TxixList» --tx-in «.Txix» \
«end»«range .Alias2AddressMap.actor.TxixList» --tx-in «.Txix» \
«end» --tx-out "$ACTOR_ADDRESS+$MINIMUM_ADA+1 $ACTOR_TOKEN" \
--change-address "$ACTOR_ADDRESS" \
--out-file 23_raw.json \
--print-stats
EOTX
50 The loop
A new script is this loop, as mentioned at the beginning of this page.
#!/bin/bash
rm contract.address payout.address amount.txt
for (( i=1; i <= 1000 ; i=i+1 ))
do
echo >> tx.log
echo "Start of iteration : $i ---- `date '+%Y%m%d-%Hh%M'`" | tee -a tx.log
echo "--- 08_create_contract.sh -------------------------------------------" | tee -a tx.log
bash 08_create_contract.sh
echo "--- 10_prepare_initialization.sh ------------------------------------" | tee -a tx.log
bash 10_prepare_initialization.sh
asnap actor.address contract.address payout.address | tee -a tx.log
echo "--- 12_execute_initialization.sh ------------------------------------" | tee -a tx.log
bash 12_execute_initialization.sh
sleep 60
asnap actor.address contract.address payout.address | tee -a tx.log
echo "--- 14_prepare_fund.sh ----------------------------------------------" | tee -a tx.log
bash 14_prepare_fund.sh
echo "--- 16_execute_fund.sh ----------------------------------------------" | tee -a tx.log
bash 16_execute_fund.sh
sleep 60
asnap actor.address contract.address payout.address | tee -a tx.log
echo "--- 18_prepare_notify.sh --------------------------------------------" | tee -a tx.log
bash 18_prepare_notify.sh
echo "--- 20_execute_notify.sh --------------------------------------------" | tee -a tx.log
bash 20_execute_notify.sh
sleep 60
asnap actor.address contract.address payout.address | tee -a tx.log
echo "--- 22_withdraw.sh --------------------------------------------------" | tee -a tx.log
bash 22_withdraw.sh
sleep 60
asnap actor.address contract.address payout.address | tee -a tx.log
BALANCE=`echo '«printf "%.f" .AggregateAda»' | asnap - actor.address`
echo "End of iteration $i ---- `date '+%Y%m%d-%Hh%M'` -- balance=$BALANCE " | tee -a tx.log
echo >> tx.log
if [ $BALANCE -lt 20 ]
then
echo "Bailing out after $i iterations, balance = $BALANCE"
exit 0
fi
# next amount to use is a third of the balance (just for reasons of variety)
echo $(( $BALANCE / 3 ))"000000" > amount.txt
done
|