Skip to content

Commit f5542b4

Browse files
committed
Change plutus example to inline datum and inline script
1 parent eabd613 commit f5542b4

File tree

3 files changed

+93
-67
lines changed

3 files changed

+93
-67
lines changed

examples/plutus/forty_two/README.md

+54-21
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,64 @@
11
# FortyTwo
22

3-
This example implements the off-chain code of forty-two, a sample program in week2 of Plutus-Pioneer-Program.
4-
The original Plutus script cound be found [here](https://github.com/input-output-hk/plutus-pioneer-program/blob/6be7484d4b8cffaef4faae30588c7fb826bcf5a3/code/week02/src/Week02/Typed.hs).
5-
The compiled Plutus core cbor hex is stored in file [fortytwo.plutus](fortytwo.plutus) in this folder.
3+
This example implements the off-chain code of forty-two v2 in Plutus.
64

75
FortyTwo is a simple smart contract that could be unlocked only by a redeemer of Integer value 42.
8-
[forty_two.py](forty_two.py) contains the code of two transactions: 1) a giver sending 10 ADA to a script address,
9-
and 2) a taker spend the ADA locked in that script address.
10-
11-
Below is the visualization of the lifecycle of UTxOs involved:
6+
[forty_two.py](forty_two.py) contains the code of three transactions:
7+
1) a giver creates an inline script and send it to herself, which cannot be spent by anybody else
8+
2) the giver send some ADA to script address
9+
3) the taker spend the script address with a redeemer of 42 and a reference to the inline script
1210

11+
Below is the visualization of the lifecycle of UTxOs involved. The entity enclosed in the parenthesis is the owner of the UTxO.
1312

1413
```
15-
16-
Giver Tx Taker Tx
17-
┌-----------┐ ┌-----------------------------┐
18-
| | | |
19-
| Spend | | Spend with Redeemer (42) |
20-
UTxO (X ADA) ━━━━━━━┳━━━━━━━━━ Script UTxO (10 ADA) ━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━ UTxO (5 ADA)
21-
| ┃ | | ┃ |
22-
| ┗━━━━━━━━━ Change UTxO (X-10 ADA) | ┗━━━━━━━━━━━━━━ Change UTxO (~4.7 ADA)
23-
| Tx Fee | | |
24-
|(~0.16 ADA)| | |
25-
| | Taker's Collateral ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ Taker's Collateral
26-
└-----------┘ UTxO (5 ADA) | | UTxO (5 ADA)
27-
| Tx fee (~0.3 ADA) |
28-
└-----------------------------┘
2914
15+
┌─────────────────────────────────────────────────────────────────────────┐
16+
│ │
17+
│ ┌─────────────────────────┐ ┌─────────────────────────┐ │
18+
│ │ │ │ │ │
19+
│ │ Initial UTxO │ │ Change UTxO │ │
20+
│ │ ├───────┤ │ │
21+
│ │ (Giver) │ │ (Giver) │ │
22+
│ │ │ │ │ │
23+
│ └────────────┬────────────┘ └─────────────────────────┘ │
24+
│ │ │
25+
│ │ │
26+
│ │ ┌─────────────────────────┐ │
27+
│ │ │ │ │
28+
│ │ │ Inline script UTxO │ │
29+
│ └────────────────────┤ ├────────┐ │
30+
│ │ (Giver) │ │ │
31+
│ │ │ │ │
32+
│ Tx1 └─────────────────────────┘ │ │
33+
│ │ │
34+
└───────────────────────────────────────────────────────────────────────┼─┘
35+
36+
┌────────────────────────────────────────────────────────────────┐ │
37+
│ │ │
38+
│ ┌─────────────────────────┐ ┌─────────────────────────┐ │ │
39+
│ │ │ │ │ │ │
40+
│ │ Give UTxO │ │ Locked UTxO │ │ │
41+
│ │ ├───────┤ │ │ │
42+
│ │ (Giver) │ │ (Script) │ │ │
43+
│ │ │ │ │ │ │
44+
│ └─────────────────────────┘ └─────────────┬───────────┘ │ │
45+
│ │ │ │
46+
│ Tx2 │ │ │
47+
└──────────────────────────────────────────────────┼─────────────┘ │
48+
│ │
49+
┌────────────────┼────────────────────┼─────────────────┐
50+
│ │ │ │
51+
│ ┌─────────────┴───────────┐ │ │
52+
│ │ │ │ │
53+
│ │ Taken UTxO │ │ │
54+
│ │ │◄───────┘ │
55+
│ │ (Taker) │ │
56+
│ │ │ Refer to script UTxO │
57+
│ └─────────────────────────┘ │
58+
│ │
59+
│ │
60+
│ Tx3 │
61+
│ │
62+
└───────────────────────────────────────────────────────┘
3063
3164
```

examples/plutus/forty_two/forty_two.py

+38-46
Original file line numberDiff line numberDiff line change
@@ -47,82 +47,74 @@ def submit_tx(tx):
4747
wait_for_tx(str(tx.id))
4848

4949

50-
def find_collateral(target_address):
51-
for utxo in chain_context.utxos(str(target_address)):
52-
# A collateral should contain no multi asset
53-
if not utxo.output.amount.multi_asset:
54-
return utxo
55-
return None
50+
with open("fortytwoV2.plutus", "r") as f:
51+
script_hex = f.read()
52+
forty_two_script = PlutusV2Script(cbor2.loads(bytes.fromhex(script_hex)))
5653

5754

58-
def create_collateral(target_address, skey):
59-
collateral_builder = TransactionBuilder(chain_context)
55+
script_hash = plutus_script_hash(forty_two_script)
6056

61-
collateral_builder.add_input_address(target_address)
62-
collateral_builder.add_output(TransactionOutput(target_address, 5000000))
57+
script_address = Address(script_hash, network=NETWORK)
6358

64-
submit_tx(collateral_builder.build_and_sign([skey], target_address))
59+
giver_address = Address(payment_vkey.hash(), network=NETWORK)
6560

61+
builder = TransactionBuilder(chain_context)
62+
builder.add_input_address(giver_address)
63+
builder.add_output(TransactionOutput(giver_address, 50000000, script=forty_two_script))
6664

67-
# ----------- Giver sends 10 ADA to a script address ---------------
68-
with open("fortytwo.plutus", "r") as f:
69-
script_hex = f.read()
70-
forty_two_script = cbor2.loads(bytes.fromhex(script_hex))
65+
signed_tx = builder.build_and_sign([payment_skey], giver_address)
7166

72-
script_hash = plutus_script_hash(PlutusV1Script(forty_two_script))
67+
print("############### Transaction created ###############")
68+
print(signed_tx)
69+
print("############### Submitting transaction ###############")
70+
submit_tx(signed_tx)
7371

74-
script_address = Address(script_hash, network=NETWORK)
7572

76-
giver_address = Address(payment_vkey.hash(), network=NETWORK)
73+
# ----------- Send ADA to the script address ---------------
7774

7875
builder = TransactionBuilder(chain_context)
7976
builder.add_input_address(giver_address)
80-
datum = PlutusData() # A Unit type "()" in Haskell
81-
builder.add_output(
82-
TransactionOutput(script_address, 10000000, datum_hash=datum_hash(datum))
83-
)
77+
datum = 42
78+
builder.add_output(TransactionOutput(script_address, 50000000, datum=datum))
8479

8580
signed_tx = builder.build_and_sign([payment_skey], giver_address)
8681

82+
print("############### Transaction created ###############")
83+
print(signed_tx)
84+
print("############### Submitting transaction ###############")
8785
submit_tx(signed_tx)
8886

89-
# ----------- Taker takes 10 ADA from the script address ---------------
90-
91-
# taker_address could be any address. In this example, we will use the same address as giver.
92-
taker_address = giver_address
87+
# ----------- Taker take ---------------
9388

94-
# Notice that transaction builder will automatically estimate execution units (num steps & memory) for a redeemer if
95-
# no execution units are provided in the constructor of Redeemer.
96-
# Put integer 42 (the secret that unlocks the fund) in the redeemer.
9789
redeemer = Redeemer(42)
9890

9991
utxo_to_spend = None
92+
93+
# Spend the utxo with datum 42 sitting at the script address
10094
for utxo in chain_context.utxos(str(script_address)):
101-
if utxo.output.datum_hash == datum_hash(datum):
95+
print(utxo)
96+
if utxo.output.datum:
10297
utxo_to_spend = utxo
10398
break
10499

105-
if utxo_to_spend is None:
106-
raise Exception("Can't find utxo to spend! Please try again later.")
100+
# Find the reference script utxo
101+
reference_script_utxo = None
102+
for utxo in chain_context.utxos(str(giver_address)):
103+
if utxo.output.script and utxo.output.script == forty_two_script:
104+
reference_script_utxo = utxo
105+
break
107106

108-
builder = TransactionBuilder(chain_context)
107+
taker_address = Address(payment_vkey.hash(), network=NETWORK)
109108

110-
builder.add_script_input(
111-
utxo_to_spend, PlutusV1Script(forty_two_script), datum, redeemer
112-
)
109+
builder = TransactionBuilder(chain_context)
113110

114-
# Send 5 ADA to taker address. The remaining ADA (~4.7) will be sent as change.
115-
take_output = TransactionOutput(taker_address, 5000000)
111+
builder.add_script_input(utxo_to_spend, script=reference_script_utxo, redeemer=redeemer)
112+
take_output = TransactionOutput(taker_address, 25123456)
116113
builder.add_output(take_output)
117114

118-
non_nft_utxo = find_collateral(taker_address)
119-
120-
if non_nft_utxo is None:
121-
create_collateral(taker_address, payment_skey)
122-
non_nft_utxo = find_collateral(taker_address)
123-
124-
builder.collaterals.append(non_nft_utxo)
125-
126115
signed_tx = builder.build_and_sign([payment_skey], taker_address)
127116

117+
print("############### Transaction created ###############")
118+
print(signed_tx)
119+
print("############### Submitting transaction ###############")
128120
submit_tx(signed_tx)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
58775875010000323232322225335323253350021001100933320015007003332001500648150ccc8005401800ccc8005401520541004132632498cd5ce2491d496e636f727265637420646174756d2e2045787065637465642034322e0000412001123750002244666ae68cdd780100089100100189100081

0 commit comments

Comments
 (0)