Skip to content

Commit 4989531

Browse files
Merge branch 'main' into refactor-base
2 parents 345f62d + 69349fb commit 4989531

File tree

6 files changed

+102
-9
lines changed

6 files changed

+102
-9
lines changed

docs/source/guides/plutus.rst

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,3 +161,71 @@ Taker/Unlocker provides collateral. Collateral has been introduced in Alonzo tra
161161

162162
The funds locked in script address is successfully retrieved to the taker address.
163163

164+
-------------
165+
Vasil Upgrade
166+
-------------
167+
As part of the Basho phase of Cardano roadmap, the Vasil upgrade brings new capabilities on Plutus, namely reference inputs, inline datums, reference scripts, collateral output and Plutus V2 primitives.
168+
169+
- **Reference inputs** (`CIP-31 <https://cips.cardano.org/cips/cip31/>`_): This upgrade enables data sharing on-chain. Previously, datums were carried in transaction outputs; they stored and provided access to information on the blockchain. However, to access information in this datum, one had to spend the output that the datum was attached to. This required the re-creation of a spent output. The addition of reference inputs now allows developers to look at the datum without extra steps. This facilitates access to information stored on the blockchain without the need for spending and re-creating UTXOs. This can be useful for oracles and other use cases where state need to be inspected.
170+
171+
- **Inline datums** (`CIP-32 <https://cips.cardano.org/cips/cip32/>`_): Transaction datums were previously attached to outputs as hashes. With the implementation of inline datums, developers can now create scripts and attach datums directly to outputs instead of using their hashes. This simplifies how datums are used – a user can see the actual datum rather than supply it to match the given hash.
172+
173+
- **Reference scripts** (`CIP-33 <https://cips.cardano.org/cips/cip33/>`_): In Alonzo, when spending an output locked within a Plutus script, one had to include the script in the spending transaction. This increased the size of the script and caused certain delays in its processing. The reference scripts upgrade allows developers to reference a script without including it in each transaction. This significantly reduces transaction size, improves throughput, and reduces script execution costs (since the script only needs to be paid for once).
174+
175+
- **Explicit collateral output** (`CIP-40 <https://cips.cardano.org/cips/cip40/>`_): Transactions that call Plutus smart contracts are required to put up collateral to cover the potential cost of smart contract execution failure. If contract execution fails during phase 2 validation, all the funds stored in the chose UTXO for the collateral will be lost. After Vasil, user can specify a change address for the script collateral. If the script fails phase-2 validation, only the collateral amount will be taken, and the remaining funds will be sent to the change address.
176+
177+
- **Plutus V2 scripts**: The Vasil upgrade includes a new cost model that's lower than before, and developers will be able to see redeemers for all inputs rather than just the one being passed to the currently executing script.
178+
179+
Using the same FortyTwo example, now in Vasil, we show how reference scripts can be used. Reference script exists at a particular transaction output, and it can be used to witness UTxO at the corresponding script address::
180+
181+
>>> builder = TransactionBuilder(context)
182+
>>> builder.add_input_address(giver_address)
183+
>>> datum = 42
184+
>>> # Include scripts in the script address
185+
>>> builder.add_output(
186+
>>> TransactionOutput(script_address, 50000000, script=forty_two_script)
187+
>>> )
188+
189+
With reference script, actual script doesn't need to be included in the transaction anymore in order to spend UTxO sitting at script address::
190+
191+
>>> utxo_to_spend = None
192+
>>> # Spend the utxo that has datum/datum hash but no script
193+
>>> for utxo in chain_context.utxos(str(script_address)):
194+
>>> if not utxo.output.script and (
195+
>>> utxo.output.datum_hash == datum_hash(datum)
196+
>>> or utxo.output.datum == datum
197+
>>> ):
198+
>>> utxo_to_spend = utxo
199+
>>> break
200+
201+
>>> builder = TransactionBuilder(context)
202+
>>> builder.add_script_input(utxo_to_spend, datum=datum, redeemer=redeemer)
203+
>>> take_output = TransactionOutput(taker_address, 25123456)
204+
>>> builder.add_output(take_output)
205+
>>> signed_tx = builder.build_and_sign([extended_payment_skey], taker_address)
206+
207+
Again, with the same example, we show that you can send funds to script address with inline datums directly::
208+
209+
>>> builder = TransactionBuilder(context)
210+
>>> builder.add_input_address(giver_address)
211+
>>> datum = 42
212+
>>> builder.add_output(
213+
>>> TransactionOutput(script_address, 50000000, datum=datum, script=forty_two_script)
214+
>>> )
215+
216+
With inline datum, we no longer have to include a datum within our transaction for our plutus spending scripts. Instead we can specify the transaction output where our datum exists to be used in conjunction with our Plutus spending script. This reduces the overall size of our transaction::
217+
218+
>>> utxo_to_spend = None
219+
>>> # Speed the utxo that has both inline script and inline datum
220+
>>> for utxo in chain_context.utxos(str(script_address)):
221+
>>> if utxo.output.datum and utxo.output.script:
222+
>>> utxo_to_spend = utxo
223+
>>> break
224+
225+
>>> builder = TransactionBuilder(context)
226+
>>> builder.add_script_input(utxo_to_spend, redeemer=redeemer)
227+
>>> take_output = TransactionOutput(taker_address, 25123456)
228+
>>> builder.add_output(take_output)
229+
>>> signed_tx = builder.build_and_sign([extended_payment_skey], taker_address)
230+
231+

integration-test/docker-compose.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ services:
7373
max-file: "10"
7474

7575
kupo:
76-
image: cardanosolutions/kupo
76+
image: cardanosolutions/kupo:v2.1.0
7777
environment:
7878
NETWORK: "${NETWORK:-local}"
7979

integration-test/test/base.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,9 @@ class TestBase:
2121

2222
OGMIOS_WS = "ws://localhost:1337"
2323

24-
KUPO_URL = "http://localhost:1442/v1/matches"
24+
KUPO_URL = "http://localhost:1442"
2525

26-
chain_context = OgmiosChainContext(OGMIOS_WS, Network.TESTNET)
26+
chain_context = OgmiosChainContext(OGMIOS_WS, Network.TESTNET, kupo_url=KUPO_URL)
2727

2828
check_chain_context(chain_context)
2929

integration-test/test/test_plutus.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -293,7 +293,7 @@ def test_plutus_v2_ref_script(self):
293293
for utxo in self.chain_context.utxos(str(script_address)):
294294
if not utxo.output.script and (
295295
utxo.output.datum_hash == datum_hash(datum)
296-
or utxo.output.datum == datum
296+
or datum_hash(utxo.output.datum) == datum_hash(datum)
297297
):
298298
utxo_to_spend = utxo
299299
break

pycardano/backend/ogmios.py

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -260,8 +260,8 @@ def _utxos_kupo(self, address: str) -> List[UTxO]:
260260
"kupo_url object attribute has not been assigned properly."
261261
)
262262

263-
address_url = self._kupo_url + "/" + address
264-
results = requests.get(address_url).json()
263+
kupo_utxo_url = self._kupo_url + "/matches/" + address
264+
results = requests.get(kupo_utxo_url).json()
265265

266266
utxos = []
267267

@@ -278,17 +278,42 @@ def _utxos_kupo(self, address: str) -> List[UTxO]:
278278

279279
lovelace_amount = result["value"]["coins"]
280280

281+
script = None
282+
script_hash = result.get("script_hash", None)
283+
if script_hash:
284+
kupo_script_url = self._kupo_url + "/scripts/" + script_hash
285+
script = requests.get(kupo_script_url).json()
286+
if script["language"] == "plutus:v2":
287+
script = PlutusV2Script(
288+
cbor2.loads(bytes.fromhex(script["script"]))
289+
)
290+
elif script["language"] == "plutus:v1":
291+
script = PlutusV1Script(
292+
cbor2.loads(bytes.fromhex(script["script"]))
293+
)
294+
else:
295+
raise ValueError("Unknown plutus script type")
296+
297+
datum = None
281298
datum_hash = (
282299
DatumHash.from_primitive(result["datum_hash"])
283300
if result["datum_hash"]
284301
else None
285302
)
303+
if datum_hash:
304+
kupo_datum_url = self._kupo_url + "/datums/" + result["datum_hash"]
305+
datum_result = requests.get(kupo_datum_url).json()
306+
if datum_result and datum_result["datum"] != datum_hash:
307+
datum = RawCBOR(bytes.fromhex(datum_result["datum"]))
308+
datum_hash = None
286309

287310
if not result["value"]["assets"]:
288311
tx_out = TransactionOutput(
289312
Address.from_primitive(address),
290313
amount=lovelace_amount,
291314
datum_hash=datum_hash,
315+
datum=datum,
316+
script=script,
292317
)
293318
else:
294319
multi_assets = MultiAsset()
@@ -305,6 +330,8 @@ def _utxos_kupo(self, address: str) -> List[UTxO]:
305330
Address.from_primitive(address),
306331
amount=Value(lovelace_amount, multi_assets),
307332
datum_hash=datum_hash,
333+
datum=datum,
334+
script=script,
308335
)
309336
utxos.append(UTxO(tx_in, tx_out))
310337
else:

pycardano/key.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -193,10 +193,8 @@ def from_hdwallet(cls, hdwallet: HDWallet) -> ExtendedSigningKey:
193193
"The hdwallet doesn't contain extended private key or chain code info."
194194
)
195195

196-
return Key(
196+
return ExtendedSigningKey(
197197
payload=hdwallet.xprivate_key + hdwallet.public_key + hdwallet.chain_code,
198-
type="PaymentExtendedSigningKeyShelley_ed25519_bip32",
199-
description="Payment Signing Key",
200198
)
201199

202200

0 commit comments

Comments
 (0)