Skip to content

Commit 1bc9894

Browse files
authored
Update Plutus gift example to use Plutus V3 from opshin (#470)
1 parent 02296b7 commit 1bc9894

File tree

1 file changed

+18
-33
lines changed

1 file changed

+18
-33
lines changed

docs/source/guides/plutus.rst

Lines changed: 18 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ We demonstrate how these concepts come into play using a simple example from `op
120120
A user can lock funds together with a public key hash.
121121
The contract will make sure that only the owner of the matching private key can redeem the gift.
122122

123-
We will first compile the contract locally. For this, you will need to have installed python3.8.
123+
We will first compile the contract locally. For this, you will need to have installed python3.9 or higher.
124124

125125
Step 1
126126

@@ -129,16 +129,17 @@ Open a file called ``gift.py`` and fill it with the following code:::
129129
from opshin.prelude import *
130130

131131
@dataclass()
132-
class CancelDatum(PlutusData):
132+
class WithdrawDatum(PlutusData):
133133
pubkeyhash: bytes
134134

135135

136-
def validator(datum: CancelDatum, redeemer: None, context: ScriptContext) -> None:
136+
def validator(context: ScriptContext) -> None:
137+
datum: WithdrawDatum = own_datum_unsafe(context)
137138
sig_present = False
138-
for s in context.tx_info.signatories:
139+
for s in context.transaction.signatories:
139140
if datum.pubkeyhash == s:
140141
sig_present = True
141-
assert sig_present
142+
assert sig_present, "Required signature missing"
142143

143144

144145
Step 2
@@ -147,12 +148,12 @@ Install the python package ``opshin``. We can then build the contract.
147148

148149
.. code:: bash
149150

150-
$ python3.8 -m venv venv
151+
$ python3 -m venv venv
151152
$ source venv/bin/activate
152153
$ pip install opshin
153154
$ opshin build gift.py
154155

155-
This is it! You will now find all relevant artifacts for proceeding in the folder ``gift/``.
156+
This is it! You will now find all relevant artifacts for proceeding in the folder ``build/gift``.
156157

157158
Step 3
158159

@@ -176,25 +177,23 @@ Create script address::
176177
... Transaction,
177178
... TransactionBuilder,
178179
... TransactionOutput,
179-
... PlutusData,
180+
... Unit,
180181
... Redeemer,
181-
... PlutusV2Script,
182+
... PlutusV3Script,
182183
... Network,
183184
... datum_hash,
184185
... )
185186

186-
>>> # This artifact was generated in step 2
187-
>>> with open("gift/script.cbor", "r") as f:
188-
>>> script_hex = f.read()
189-
>>> gift_script = PlutusV2Script(bytes.fromhex(script_hex))
187+
>>> # This artifact was generated in step 2. By default, opshin will generate Plutus V3 scripts, so we need to load the script as a `PlutusV3Script`.
188+
>>> gift_script = PlutusV3Script.load("build/gift/script.plutus")
190189

191190
>>> script_hash = plutus_script_hash(gift_script)
192191
>>> network = Network.TESTNET
193192
>>> script_address = Address(script_hash, network=network)
194193

195194
Step 5
196195

197-
Giver/Locker sends funds to script address.
196+
Giver/Locker sends funds to script address. Both giver and taker need to have some ADA in their addresses to pay for the transaction fees and collateral.
198197
We will attach the public key hash of a receiver address as datum to the utxo.
199198
Note that we will just use the datatype defined in the contract, as it also uses ``PlutusData``.
200199

@@ -211,8 +210,8 @@ Note that we will just use the datatype defined in the contract, as it also uses
211210
>>> builder = TransactionBuilder(context)
212211
>>> builder.add_input_address(giver_address)
213212

214-
>>> from gift import CancelDatum
215-
>>> datum = CancelDatum(payment_vkey_2.hash().to_primitive())
213+
>>> from gift import WithdrawDatum
214+
>>> datum = WithdrawDatum(payment_vkey_2.hash().to_primitive())
216215
>>> builder.add_output(
217216
>>> TransactionOutput(script_address, 50000000, datum_hash=datum_hash(datum))
218217
>>> )
@@ -226,7 +225,7 @@ Step 6
226225

227226
Taker/Unlocker sends transaction to consume funds. Here we specify the redeemer tag as spend and pass in no special redeemer, as it is being ignored by the contract.::
228227

229-
>>> redeemer = Redeemer(PlutusData()) # The plutus equivalent of None
228+
>>> redeemer = Redeemer(Unit()) # The plutus equivalent of None
230229

231230
>>> utxo_to_spend = context.utxos(str(script_address))[0]
232231

@@ -238,26 +237,12 @@ Add info on the UTxO to spend, Plutus script, actual datum and the redeemer. Spe
238237
>>> take_output = TransactionOutput(taker_address, 25123456)
239238
>>> builder.add_output(take_output)
240239

241-
Taker/Unlocker provides collateral. Collateral has been introduced in Alonzo transactions to cover the cost of the validating node executing a failing script. In this scenario, the provided UTXO is consumed instead of the fees. A UTXO provided for collateral must only have ada, no other native assets::
242-
243-
>>> non_nft_utxo = None
244-
>>> for utxo in context.utxos(str(taker_address)):
245-
>>> # multi_asset should be empty for collateral utxo
246-
>>> if not utxo.output.amount.multi_asset:
247-
>>> non_nft_utxo = utxo
248-
>>> break
249-
250-
>>> builder.collaterals.append(non_nft_utxo)
251-
252-
>>> signed_tx = builder.build_and_sign([payment_skey_2], taker_address)
253-
254-
255-
Uh oh! That failed. We forgot to add the taker as a `required` signer, so that the contract knows
240+
It is important to note that we need to add the taker as a `required` signer, so that the contract knows
256241
that they will sign the transaction::
257242

258243
>>> builder.required_signers = [payment_vkey_2.hash()]
259244

260-
Now lets try to resubmit this::
245+
Now lets try to submit this::
261246

262247
>>> signed_tx = builder.build_and_sign([payment_skey_2], taker_address)
263248

0 commit comments

Comments
 (0)