From 1d5887b34b6c24d15659d1308bb852d68a31fff8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrei=20B=C4=83ncioiu?= Date: Fri, 14 Jun 2024 17:07:53 +0300 Subject: [PATCH 1/9] Cookbook data files. --- examples/contracts/adder.abi.json | 48 ++++++++++++++++++++++++++++++ examples/contracts/adder.wasm | Bin 0 -> 687 bytes examples/data/counter.wasm | Bin 335 -> 0 bytes 3 files changed, 48 insertions(+) create mode 100644 examples/contracts/adder.abi.json create mode 100755 examples/contracts/adder.wasm delete mode 100755 examples/data/counter.wasm diff --git a/examples/contracts/adder.abi.json b/examples/contracts/adder.abi.json new file mode 100644 index 00000000..4772ced4 --- /dev/null +++ b/examples/contracts/adder.abi.json @@ -0,0 +1,48 @@ +{ + "name": "Adder", + "constructor": { + "inputs": [ + { + "name": "initial_value", + "type": "BigUint" + } + ], + "outputs": [] + }, + "upgradeConstructor": { + "inputs": [ + { + "name": "initial_value", + "type": "BigUint" + } + ], + "outputs": [] + }, + "endpoints": [ + { + "name": "getSum", + "mutability": "readonly", + "inputs": [], + "outputs": [ + { + "type": "BigUint" + } + ] + }, + { + "docs": ["Add desired amount to the storage variable."], + "name": "add", + "mutability": "mutable", + "inputs": [ + { + "name": "value", + "type": "BigUint" + } + ], + "outputs": [] + } + ], + "esdtAttributes": [], + "hasCallback": false, + "types": {} +} diff --git a/examples/contracts/adder.wasm b/examples/contracts/adder.wasm new file mode 100755 index 0000000000000000000000000000000000000000..77ce7e234a7c0110114e1527bd49705ec98ecf88 GIT binary patch literal 687 zcmZuvO>dh(5S`g2n6M3OW2=>;9w?{w)LYNNQXNIAqDpDcur_OK*+8{GBA@V2$hA@q z{XP9t?k?a+m3m-z=e;*?J_Lv=M*zT&P6Chswh3w5{)7ZuNNC%|<}v`b@8ztkbSl%c(}A6dtEGU|MAyrVW0x|qbRizhX24mLq@p$|T(}Jio literal 0 HcmV?d00001 diff --git a/examples/data/counter.wasm b/examples/data/counter.wasm deleted file mode 100755 index 4f31dbb4b4199cd1d4c3a906ec86a710182ff30d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 335 zcmaKly-UPE6vSutBbRdvBcg?s_y=es_KDbuf**Z?x1K4INU{imWTVw#<)7?EFJd81 zGmqcQdk;ld5de2oF1_#RbKyPvoIP?tWK!DtX{)T=$#LhJwpiNhU=|p8@|&MG#R43$ z`NH>QU3L!;QY#sxG#^Q7Nr)(>XZo>HW_F~b%2rMLETF=IgPfQ3U27{_JE-}>PP3Lv z>kw_cQ*9$1R>OdFmN6NEuxAd*exj2nuVa?+ Date: Fri, 14 Jun 2024 17:24:06 +0300 Subject: [PATCH 2/9] Additional exports. --- multiversx_sdk/abi/__init__.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/multiversx_sdk/abi/__init__.py b/multiversx_sdk/abi/__init__.py index 19e3f234..28986b79 100644 --- a/multiversx_sdk/abi/__init__.py +++ b/multiversx_sdk/abi/__init__.py @@ -1,3 +1,5 @@ +from multiversx_sdk.abi.abi import Abi +from multiversx_sdk.abi.abi_definition import AbiDefinition from multiversx_sdk.abi.address_value import AddressValue from multiversx_sdk.abi.bigint_value import BigIntValue from multiversx_sdk.abi.biguint_value import BigUIntValue @@ -20,6 +22,9 @@ from multiversx_sdk.abi.variadic_values import VariadicValues __all__ = [ + "Abi", + "AbiDefinition", + "AddressValue", "BigIntValue", "BigUIntValue", @@ -42,6 +47,7 @@ "StructValue", "TokenIdentifierValue", "TupleValue", + "MultiValue", "OptionalValue", "VariadicValues", From 4386a6956e998f746bba8be9e456bda88c9b32db Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrei=20B=C4=83ncioiu?= Date: Fri, 14 Jun 2024 17:24:26 +0300 Subject: [PATCH 3/9] ABI: allow missing constructor definition. --- multiversx_sdk/abi/abi_definition.py | 34 ++++++++++++++++++++++++---- 1 file changed, 30 insertions(+), 4 deletions(-) diff --git a/multiversx_sdk/abi/abi_definition.py b/multiversx_sdk/abi/abi_definition.py index c1fb3032..a18c2a31 100644 --- a/multiversx_sdk/abi/abi_definition.py +++ b/multiversx_sdk/abi/abi_definition.py @@ -16,10 +16,10 @@ def __init__(self, @classmethod def from_dict(cls, data: Dict[str, Any]) -> "AbiDefinition": - constructor = EndpointDefinition.from_dict(data["constructor"]) + constructor = cls._get_definition_for_constructor(data) constructor.name = "constructor" - upgrade_constructor = cls._get_endpoint_for_upgrade(data) + upgrade_constructor = cls._get_definition_for_upgrade(data) upgrade_constructor.name = "upgrade_constructor" endpoints = [EndpointDefinition.from_dict(item) for item in data["endpoints"]] if "endpoints" in data else [] @@ -33,7 +33,14 @@ def from_dict(cls, data: Dict[str, Any]) -> "AbiDefinition": ) @classmethod - def _get_endpoint_for_upgrade(cls, data: Dict[str, Any]) -> "EndpointDefinition": + def _get_definition_for_constructor(cls, data: Dict[str, Any]): + if "constructor" in data: + return EndpointDefinition.from_dict(data["constructor"]) + + return NullEndpointDefinition() + + @classmethod + def _get_definition_for_upgrade(cls, data: Dict[str, Any]) -> "EndpointDefinition": if "upgradeConstructor" in data: return EndpointDefinition.from_dict(data["upgradeConstructor"]) @@ -42,7 +49,10 @@ def _get_endpoint_for_upgrade(cls, data: Dict[str, Any]) -> "EndpointDefinition" return EndpointDefinition.from_dict(data["endpoints"]["upgrade"]) # Fallback for contracts written using an old Rust framework: - return EndpointDefinition.from_dict(data["constructor"]) + if "constructor" in data: + EndpointDefinition.from_dict(data["constructor"]) + + return NullEndpointDefinition() @classmethod def load(cls, path: Path) -> "AbiDefinition": @@ -87,6 +97,22 @@ def __repr__(self): return f"EndpointDefinition(name={self.name})" +class NullEndpointDefinition(EndpointDefinition): + def __init__(self) -> None: + super().__init__( + name="", + docs="", + mutability="", + inputs=[], + outputs=[], + payable_in_tokens=[], + only_owner=False + ) + + def __repr__(self): + return "NullEndpointDefinition()" + + class ParameterDefinition: def __init__(self, name: str, type: str) -> None: self.name = name From 3e39341bbfa3e5ca1d140980667146de02de02cf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrei=20B=C4=83ncioiu?= Date: Mon, 17 Jun 2024 11:57:18 +0300 Subject: [PATCH 4/9] Update cookbook. --- examples/Cookbook.ipynb | 655 +++++++++++++++++++++++++++++++++------- 1 file changed, 548 insertions(+), 107 deletions(-) diff --git a/examples/Cookbook.ipynb b/examples/Cookbook.ipynb index 03908aee..cf95c9a7 100644 --- a/examples/Cookbook.ipynb +++ b/examples/Cookbook.ipynb @@ -2,7 +2,7 @@ "cells": [ { "cell_type": "code", - "execution_count": 2, + "execution_count": 102, "metadata": {}, "outputs": [], "source": [ @@ -26,7 +26,7 @@ }, { "cell_type": "code", - "execution_count": 3, + "execution_count": 103, "metadata": {}, "outputs": [ { @@ -58,7 +58,7 @@ }, { "cell_type": "code", - "execution_count": 4, + "execution_count": 104, "metadata": {}, "outputs": [], "source": [ @@ -74,7 +74,7 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": 105, "metadata": {}, "outputs": [], "source": [ @@ -91,7 +91,7 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 106, "metadata": {}, "outputs": [], "source": [ @@ -113,7 +113,7 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 107, "metadata": {}, "outputs": [ { @@ -139,7 +139,7 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": 108, "metadata": {}, "outputs": [ { @@ -166,7 +166,7 @@ }, { "cell_type": "code", - "execution_count": 9, + "execution_count": 109, "metadata": {}, "outputs": [ { @@ -199,7 +199,7 @@ }, { "cell_type": "code", - "execution_count": 10, + "execution_count": 110, "metadata": {}, "outputs": [ { @@ -249,7 +249,7 @@ }, { "cell_type": "code", - "execution_count": 11, + "execution_count": 111, "metadata": {}, "outputs": [ { @@ -283,7 +283,7 @@ }, { "cell_type": "code", - "execution_count": 12, + "execution_count": 112, "metadata": {}, "outputs": [], "source": [ @@ -301,7 +301,7 @@ }, { "cell_type": "code", - "execution_count": 13, + "execution_count": 113, "metadata": {}, "outputs": [ { @@ -341,7 +341,7 @@ }, { "cell_type": "code", - "execution_count": 14, + "execution_count": 114, "metadata": {}, "outputs": [ { @@ -380,7 +380,7 @@ }, { "cell_type": "code", - "execution_count": 15, + "execution_count": 115, "metadata": {}, "outputs": [ { @@ -415,7 +415,7 @@ }, { "cell_type": "code", - "execution_count": 16, + "execution_count": 116, "metadata": {}, "outputs": [ { @@ -450,7 +450,7 @@ }, { "cell_type": "code", - "execution_count": 17, + "execution_count": 117, "metadata": {}, "outputs": [ { @@ -497,7 +497,7 @@ }, { "cell_type": "code", - "execution_count": 18, + "execution_count": 118, "metadata": {}, "outputs": [ { @@ -536,7 +536,7 @@ }, { "cell_type": "code", - "execution_count": 19, + "execution_count": 119, "metadata": {}, "outputs": [], "source": [ @@ -555,7 +555,7 @@ }, { "cell_type": "code", - "execution_count": 20, + "execution_count": 120, "metadata": {}, "outputs": [ { @@ -608,16 +608,9 @@ }, { "cell_type": "code", - "execution_count": 21, + "execution_count": 121, "metadata": {}, "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "The `serialize()` method is deprecated and will soon be removed\n" - ] - }, { "name": "stdout", "output_type": "stream", @@ -665,42 +658,213 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "## Contract deployments and interactions" + "## Contract ABIs\n", + "\n", + "A contract's ABI describes the endpoints, data structure and events that a contract exposes. While contract interactions are possible without the ABI, they are easier to implement when the definitions are available." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Load the ABI from a file" + ] + }, + { + "cell_type": "code", + "execution_count": 122, + "metadata": {}, + "outputs": [], + "source": [ + "from multiversx_sdk.abi import Abi, AbiDefinition\n", + "\n", + "abi_definition = AbiDefinition.load(Path(\"./contracts/adder.abi.json\"))\n", + "abi = Abi(abi_definition)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Or even simpler:" + ] + }, + { + "cell_type": "code", + "execution_count": 123, + "metadata": {}, + "outputs": [], + "source": [ + "abi = Abi.load(Path(\"./contracts/adder.abi.json\"))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Manually construct the ABI" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "If an ABI file isn't directly available, but you do have knowledge of the contract's endpoints and types, you can manually construct the ABI. Let's see a simple example:" + ] + }, + { + "cell_type": "code", + "execution_count": 124, + "metadata": {}, + "outputs": [], + "source": [ + "abi_definition = AbiDefinition.from_dict({\n", + " \"endpoints\": [{\n", + " \"name\": \"add\",\n", + " \"inputs\": [\n", + " {\n", + " \"name\": \"value\",\n", + " \"type\": \"BigUint\"\n", + " }\n", + " ],\n", + " \"outputs\": []\n", + " }]\n", + "})" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "An endpoint with both inputs and outputs:" + ] + }, + { + "cell_type": "code", + "execution_count": 125, + "metadata": {}, + "outputs": [], + "source": [ + "abi_definition = AbiDefinition.from_dict({\n", + " \"endpoints\": [\n", + " {\n", + " \"name\": \"foo\",\n", + " \"inputs\": [\n", + " { \"type\": \"BigUint\" },\n", + " { \"type\": \"u32\" },\n", + " { \"type\": \"Address\" }\n", + " ],\n", + " \"outputs\": [\n", + " { \"type\": \"u32\" }\n", + " ]\n", + " },\n", + " {\n", + " \"name\": \"bar\",\n", + " \"inputs\": [\n", + " { \"type\": \"counted-variadic\" },\n", + " { \"type\": \"variadic\" }\n", + " ],\n", + " \"outputs\": []\n", + " }\n", + " ]\n", + "})" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Contract deployments" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Load the bytecode from a file" + ] + }, + { + "cell_type": "code", + "execution_count": 126, + "metadata": {}, + "outputs": [], + "source": [ + "from pathlib import Path\n", + "\n", + "bytecode = Path(\"contracts/adder.wasm\").read_bytes()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Perform a contract deployment\n", + "\n", + "First, let's create a `SmartContractTransactionsFactory`:" + ] + }, + { + "cell_type": "code", + "execution_count": 127, + "metadata": {}, + "outputs": [], + "source": [ + "from multiversx_sdk import SmartContractTransactionsFactory\n", + "\n", + "factory = SmartContractTransactionsFactory(config)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "If the contract ABI is available, provide it to the factory:" + ] + }, + { + "cell_type": "code", + "execution_count": 128, + "metadata": {}, + "outputs": [], + "source": [ + "abi = Abi.load(Path(\"contracts/adder.abi.json\"))\n", + "factory = SmartContractTransactionsFactory(config, abi)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "Create a transaction to deploy a smart contract:" + "Now, prepare the deploy transaction:" ] }, { "cell_type": "code", - "execution_count": 22, + "execution_count": 129, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "Transaction: {'nonce': 0, 'value': '0', 'receiver': 'erd1qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq6gq4hu', 'sender': 'erd1qyu5wthldzr8wx5c9ucg8kjagg0jfs53s8nr3zpz3hypefsdd8ssycr6th', 'senderUsername': '', 'receiverUsername': '', 'gasPrice': 1000000000, 'gasLimit': 10000000, 'data': 'MDA2MTczNmQwMTAwMDAwMDAxMTUwNDYwMDM3ZjdmN2UwMTdmNjAwMjdmN2YwMTdlNjAwMTdlMDA2MDAwMDAwMjQyMDMwMzY1NmU3NjExNjk2ZTc0MzYzNDczNzQ2ZjcyNjE2NzY1NTM3NDZmNzI2NTAwMDAwMzY1NmU3NjEwNjk2ZTc0MzYzNDczNzQ2ZjcyNjE2NzY1NGM2ZjYxNjQwMDAxMDM2NTZlNzYwYjY5NmU3NDM2MzQ2NjY5NmU2OTczNjgwMDAyMDMwNTA0MDMwMzAzMDMwNDA1MDE3MDAxMDEwMTA1MDMwMTAwMDIwNjA4MDE3ZjAxNDE5MDg4MDQwYjA3MmYwNTA2NmQ2NTZkNmY3Mjc5MDIwMDA0Njk2ZTY5NzQwMDAzMDk2OTZlNjM3MjY1NmQ2NTZlNzQwMDA0MDk2NDY1NjM3MjY1NmQ2NTZlNzQwMDA1MDM2NzY1NzQwMDA2MGE4YTAxMDQxMzAwNDE4MDg4ODA4MDAwNDEwNzQyMDExMDgwODA4MDgwMDAxYTBiMmUwMTAxN2U0MTgwODg4MDgwMDA0MTA3NDE4MDg4ODA4MDAwNDEwNzEwODE4MDgwODAwMDQyMDE3YzIyMDAxMDgwODA4MDgwMDAxYTIwMDAxMDgyODA4MDgwMDAwYjJlMDEwMTdlNDE4MDg4ODA4MDAwNDEwNzQxODA4ODgwODAwMDQxMDcxMDgxODA4MDgwMDA0MjdmN2MyMjAwMTA4MDgwODA4MDAwMWEyMDAwMTA4MjgwODA4MDAwMGIxNjAwNDE4MDg4ODA4MDAwNDEwNzEwODE4MDgwODAwMDEwODI4MDgwODAwMDBiMGIwZjAxMDA0MTgwMDgwYjA4NDM0ZjU1NGU1NDQ1NTIwMEAwNTAwQDA1MDZAMmFANzQ2NTczNzQ=', 'chainID': 'D', 'version': 2, 'options': 0, 'guardian': '', 'signature': '', 'guardianSignature': ''}\n", - "Transaction data: 0061736d0100000001150460037f7f7e017f60027f7f017e60017e0060000002420303656e7611696e74363473746f7261676553746f7265000003656e7610696e74363473746f726167654c6f6164000103656e760b696e74363466696e6973680002030504030303030405017001010105030100020608017f01419088040b072f05066d656d6f7279020004696e6974000309696e6372656d656e7400040964656372656d656e7400050367657400060a8a01041300418088808000410742011080808080001a0b2e01017e4180888080004107418088808000410710818080800042017c22001080808080001a20001082808080000b2e01017e41808880800041074180888080004107108180808000427f7c22001080808080001a20001082808080000b160041808880800041071081808080001082808080000b0b0f01004180080b08434f554e54455200@0500@0506@2a@74657374\n" + "Transaction: {'nonce': 0, 'value': '0', 'receiver': 'erd1qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq6gq4hu', 'sender': 'erd1qyu5wthldzr8wx5c9ucg8kjagg0jfs53s8nr3zpz3hypefsdd8ssycr6th', 'senderUsername': '', 'receiverUsername': '', 'gasPrice': 1000000000, 'gasLimit': 10000000, 'data': 'MDA2MTczNmQwMTAwMDAwMDAxMjkwODYwMDAwMDYwMDAwMTdmNjAwMjdmN2YwMTdmNjAwMjdmN2YwMDYwMDE3ZjAwNjAwMzdmN2Y3ZjAxN2Y2MDAzN2Y3ZjdmMDA2MDAxN2YwMTdmMDI5MDAyMGIwMzY1NmU3NjE5NjI2OTY3NDk2ZTc0NDc2NTc0NTU2ZTczNjk2NzZlNjU2NDQxNzI2Nzc1NmQ2NTZlNzQwMDAzMDM2NTZlNzYwZjY3NjU3NDRlNzU2ZDQxNzI2Nzc1NmQ2NTZlNzQ3MzAwMDEwMzY1NmU3NjBiNzM2OTY3NmU2MTZjNDU3MjcyNmY3MjAwMDMwMzY1NmU3NjEyNmQ0Mjc1NjY2NjY1NzI1Mzc0NmY3MjYxNjc2NTRjNmY2MTY0MDAwMjAzNjU2ZTc2MTc2ZDQyNzU2NjY2NjU3MjU0NmY0MjY5Njc0OTZlNzQ1NTZlNzM2OTY3NmU2NTY0MDAwMjAzNjU2ZTc2MTk2ZDQyNzU2NjY2NjU3MjQ2NzI2ZjZkNDI2OTY3NDk2ZTc0NTU2ZTczNjk2NzZlNjU2NDAwMDIwMzY1NmU3NjEzNmQ0Mjc1NjY2NjY1NzI1Mzc0NmY3MjYxNjc2NTUzNzQ2ZjcyNjUwMDAyMDM2NTZlNzYwZjZkNDI3NTY2NjY2NTcyNTM2NTc0NDI3OTc0NjU3MzAwMDUwMzY1NmU3NjBlNjM2ODY1NjM2YjRlNmY1MDYxNzk2ZDY1NmU3NDAwMDAwMzY1NmU3NjE0NjI2OTY3NDk2ZTc0NDY2OTZlNjk3MzY4NTU2ZTczNjk2NzZlNjU2NDAwMDQwMzY1NmU3NjA5NjI2OTY3NDk2ZTc0NDE2NDY0MDAwNjAzMGIwYTAxMDEwNDA3MDMwMTAwMDAwMDAwMDUwMzAxMDAwMzA2MGYwMjdmMDA0MWEwODAwODBiN2YwMDQxYTA4MDA4MGIwNzQ2MDcwNjZkNjU2ZDZmNzI3OTAyMDAwNDY5NmU2OTc0MDAxMTA2Njc2NTc0NTM3NTZkMDAxMjAzNjE2NDY0MDAxMzA4NjM2MTZjNmM0MjYxNjM2YjAwMTQwYTVmNWY2NDYxNzQ2MTVmNjU2ZTY0MDMwMDBiNWY1ZjY4NjU2MTcwNWY2MjYxNzM2NTAzMDEwYWNhMDEwYTBlMDEwMTdmNDEwMDEwMGMyMjAwMTAwMDIwMDAwYjE5MDEwMTdmNDE5YzgwMDg0MTljODAwODI4MDIwMDQxMDE2YjIyMDAzNjAyMDAyMDAwMGIxNDAwMTAwMTIwMDA0NjA0NDAwZjBiNDE4MDgwMDg0MTE5MTAwMjAwMGIxNjAwMjAwMDEwMGMyMjAwMTAwMzFhMjAwMDEwMGMyMjAwMTAwNDFhMjAwMDBiMTQwMTAxN2YxMDBjMjIwMjIwMDExMDA1MWEyMDAwMjAwMjEwMDYxYTBiMTMwMTAxN2YxMDBjMjIwMDQxOTk4MDA4NDEwMzEwMDcxYTIwMDAwYjE0MDEwMTdmMTAwODQxMDExMDBkMTAwYjIxMDAxMDEwMjAwMDEwMGYwYjBlMDAxMDA4NDEwMDEwMGQxMDEwMTAwZTEwMDkwYjIyMDEwMzdmMTAwODQxMDExMDBkMTAwYjIxMDExMDEwMjIwMjEwMGUyMjAwMjAwMDIwMDExMDBhMjAwMjIwMDAxMDBmMGIwMzAwMDEwYjBiMmYwMjAwNDE4MDgwMDgwYjFjNzc3MjZmNmU2NzIwNmU3NTZkNjI2NTcyMjA2ZjY2MjA2MTcyNjc3NTZkNjU2ZTc0NzM3Mzc1NmQwMDQxOWM4MDA4MGIwNDljZmZmZmZmQDA1MDBAMDUwNkAyYQ==', 'chainID': 'D', 'version': 2, 'options': 0, 'guardian': '', 'signature': '', 'guardianSignature': ''}\n", + "Transaction data: 0061736d010000000129086000006000017f60027f7f017f60027f7f0060017f0060037f7f7f017f60037f7f7f0060017f017f0290020b03656e7619626967496e74476574556e7369676e6564417267756d656e74000303656e760f6765744e756d417267756d656e7473000103656e760b7369676e616c4572726f72000303656e76126d42756666657253746f726167654c6f6164000203656e76176d427566666572546f426967496e74556e7369676e6564000203656e76196d42756666657246726f6d426967496e74556e7369676e6564000203656e76136d42756666657253746f7261676553746f7265000203656e760f6d4275666665725365744279746573000503656e760e636865636b4e6f5061796d656e74000003656e7614626967496e7446696e697368556e7369676e6564000403656e7609626967496e744164640006030b0a010104070301000000000503010003060f027f0041a080080b7f0041a080080b074607066d656d6f7279020004696e697400110667657453756d00120361646400130863616c6c4261636b00140a5f5f646174615f656e6403000b5f5f686561705f6261736503010aca010a0e01017f4100100c2200100020000b1901017f419c8008419c800828020041016b220036020020000b1400100120004604400f0b4180800841191002000b16002000100c220010031a2000100c220010041a20000b1401017f100c2202200110051a2000200210061a0b1301017f100c220041998008410310071a20000b1401017f10084101100d100b210010102000100f0b0e0010084100100d1010100e10090b2201037f10084101100d100b210110102202100e220020002001100a20022000100f0b0300010b0b2f0200418080080b1c77726f6e67206e756d626572206f6620617267756d656e747373756d00419c80080b049cffffff@0500@0506@2a\n" ] } ], "source": [ - "from pathlib import Path\n", + "from multiversx_sdk.abi import U32Value\n", "\n", - "from multiversx_sdk import SmartContractTransactionsFactory\n", - "\n", - "sc_factory = SmartContractTransactionsFactory(config)\n", - "bytecode = Path(\"./data/counter.wasm\").read_bytes()\n", + "# For deploy arguments, use typed value objects if you haven't provided an ABI to the factory:\n", + "args = [U32Value(42)]\n", + "# Or use simple, plain Python values and objects if you have provided an ABI to the factory:\n", + "args = [42]\n", "\n", - "deploy_transaction = sc_factory.create_transaction_for_deploy(\n", + "deploy_transaction = factory.create_transaction_for_deploy(\n", " sender=alice,\n", " bytecode=bytecode,\n", - " arguments=[42, \"test\"],\n", + " arguments=args,\n", " gas_limit=10000000,\n", " is_upgradeable=True,\n", " is_readable=True,\n", @@ -716,33 +880,143 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "Create a transaction to upgrade an existing smart contract:" + ":::tip\n", + "When creating transactions using `SmartContractTransactionsFactory`, even if the ABI is available and provided,\n", + "you can still use _typed value_ objects as arguments for deployments and interactions.\n", + "\n", + "Even further, you can use a mix of _typed value_ objects and plain Python values and objects. For example:\n", + "```\n", + "args = [U32Value(42), \"hello\", { \"foo\": \"bar\" }, TokenIdentifierValue(\"TEST-abcdef\")];\n", + "```\n", + ":::" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + ":::note\n", + "Setting the transaction nonce, signing a transaction and broadcasting it are depicted in a later section.\n", + ":::" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Computing the contract address" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Even before broadcasting, at the moment you know the sender address and the nonce for your deployment transaction, you can (deterministically) compute the (upcoming) address of the contract:" + ] + }, + { + "cell_type": "code", + "execution_count": 130, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Contract address: erd1qqqqqqqqqqqqqpgqak8zt22wl2ph4tswtyc39namqx6ysa2sd8ss4xmlj3\n" + ] + } + ], + "source": [ + "from multiversx_sdk import AddressComputer\n", + "\n", + "address_computer = AddressComputer()\n", + "contract_address = address_computer.compute_contract_address(\n", + " deployer=Address.new_from_bech32(deploy_transaction.sender),\n", + " deployment_nonce=deploy_transaction.nonce\n", + ")\n", + "\n", + "print(\"Contract address:\", contract_address.to_bech32())" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Parsing transaction outcome" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "In the end, you can parse the results using a `SmartContractTransactionsOutcomeParser`. However, since the `parse_deploy` method requires a `TransactionOutcome` object as input, we need to first convert our `TransactionOnNetwork` object to a `TransactionOutcome`, by means of a `TransactionsConverter`." ] }, { "cell_type": "code", - "execution_count": 23, + "execution_count": 131, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "Transaction: {'nonce': 0, 'value': '0', 'receiver': 'erd1qqqqqqqqqqqqqpgquzmh78klkqwt0p4rjys0qtp3la07gz4d396qn50nnm', 'sender': 'erd1qyu5wthldzr8wx5c9ucg8kjagg0jfs53s8nr3zpz3hypefsdd8ssycr6th', 'senderUsername': '', 'receiverUsername': '', 'gasPrice': 1000000000, 'gasLimit': 10000000, 'data': 'dXBncmFkZUNvbnRyYWN0QDAwNjE3MzZkMDEwMDAwMDAwMTE1MDQ2MDAzN2Y3ZjdlMDE3ZjYwMDI3ZjdmMDE3ZTYwMDE3ZTAwNjAwMDAwMDI0MjAzMDM2NTZlNzYxMTY5NmU3NDM2MzQ3Mzc0NmY3MjYxNjc2NTUzNzQ2ZjcyNjUwMDAwMDM2NTZlNzYxMDY5NmU3NDM2MzQ3Mzc0NmY3MjYxNjc2NTRjNmY2MTY0MDAwMTAzNjU2ZTc2MGI2OTZlNzQzNjM0NjY2OTZlNjk3MzY4MDAwMjAzMDUwNDAzMDMwMzAzMDQwNTAxNzAwMTAxMDEwNTAzMDEwMDAyMDYwODAxN2YwMTQxOTA4ODA0MGIwNzJmMDUwNjZkNjU2ZDZmNzI3OTAyMDAwNDY5NmU2OTc0MDAwMzA5Njk2ZTYzNzI2NTZkNjU2ZTc0MDAwNDA5NjQ2NTYzNzI2NTZkNjU2ZTc0MDAwNTAzNjc2NTc0MDAwNjBhOGEwMTA0MTMwMDQxODA4ODgwODAwMDQxMDc0MjAxMTA4MDgwODA4MDAwMWEwYjJlMDEwMTdlNDE4MDg4ODA4MDAwNDEwNzQxODA4ODgwODAwMDQxMDcxMDgxODA4MDgwMDA0MjAxN2MyMjAwMTA4MDgwODA4MDAwMWEyMDAwMTA4MjgwODA4MDAwMGIyZTAxMDE3ZTQxODA4ODgwODAwMDQxMDc0MTgwODg4MDgwMDA0MTA3MTA4MTgwODA4MDAwNDI3ZjdjMjIwMDEwODA4MDgwODAwMDFhMjAwMDEwODI4MDgwODAwMDBiMTYwMDQxODA4ODgwODAwMDQxMDcxMDgxODA4MDgwMDAxMDgyODA4MDgwMDAwYjBiMGYwMTAwNDE4MDA4MGIwODQzNGY1NTRlNTQ0NTUyMDBAMDUwNkAyYUA3NDY1NzM3NA==', 'chainID': 'D', 'version': 2, 'options': 0, 'guardian': '', 'signature': '', 'guardianSignature': ''}\n", - "Transaction data: upgradeContract@0061736d0100000001150460037f7f7e017f60027f7f017e60017e0060000002420303656e7611696e74363473746f7261676553746f7265000003656e7610696e74363473746f726167654c6f6164000103656e760b696e74363466696e6973680002030504030303030405017001010105030100020608017f01419088040b072f05066d656d6f7279020004696e6974000309696e6372656d656e7400040964656372656d656e7400050367657400060a8a01041300418088808000410742011080808080001a0b2e01017e4180888080004107418088808000410710818080800042017c22001080808080001a20001082808080000b2e01017e41808880800041074180888080004107108180808000427f7c22001080808080001a20001082808080000b160041808880800041071081808080001082808080000b0b0f01004180080b08434f554e54455200@0506@2a@74657374\n" + "SmartContractDeployOutcome(return_code='', return_message='', contracts=[DeployedSmartContract(address='erd1qqqqqqqqqqqqqpgqws44xjx2t056nn79fn29q0rjwfrd3m43396ql35kxy', owner_address='erd1testnlersh4z0wsv8kjx39me4rmnvjkwu8dsaea7ukdvvc9z396qykv7z7', code_hash=b'8Kh\\r\\xf7\\xa9^\\xbc\\xec\\xa0/\\xfb>v\\n/\\xc2\\x88\\xde\\xa1\\xb8\\x02h^\\xf1]\\xf2*\\xe8\\x8b\\xa1[')])\n" + ] + } + ], + "source": [ + "from multiversx_sdk import SmartContractTransactionsOutcomeParser, TransactionsConverter\n", + "\n", + "converter = TransactionsConverter()\n", + "parser = SmartContractTransactionsOutcomeParser()\n", + "\n", + "transaction_on_network = proxy.get_transaction(\"0a7da74038244790b5bd4cd614c26cd5a6be76a6fcfcfb037974cc116b2ee9c6\")\n", + "transaction_outcome = converter.transaction_on_network_to_outcome(transaction_on_network)\n", + "parsed_outcome = parser.parse_deploy(transaction_outcome)\n", + "\n", + "print(parsed_outcome)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Contract upgrades" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Contract upgrade transactions are similar to deployment transactions, in the sense that they also require a contract bytecode. In this context, though, the contract address is already known." + ] + }, + { + "cell_type": "code", + "execution_count": 132, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Transaction: {'nonce': 0, 'value': '0', 'receiver': 'erd1qqqqqqqqqqqqqpgquzmh78klkqwt0p4rjys0qtp3la07gz4d396qn50nnm', 'sender': 'erd1qyu5wthldzr8wx5c9ucg8kjagg0jfs53s8nr3zpz3hypefsdd8ssycr6th', 'senderUsername': '', 'receiverUsername': '', 'gasPrice': 1000000000, 'gasLimit': 10000000, 'data': 'dXBncmFkZUNvbnRyYWN0QDAwNjE3MzZkMDEwMDAwMDAwMTI5MDg2MDAwMDA2MDAwMDE3ZjYwMDI3ZjdmMDE3ZjYwMDI3ZjdmMDA2MDAxN2YwMDYwMDM3ZjdmN2YwMTdmNjAwMzdmN2Y3ZjAwNjAwMTdmMDE3ZjAyOTAwMjBiMDM2NTZlNzYxOTYyNjk2NzQ5NmU3NDQ3NjU3NDU1NmU3MzY5Njc2ZTY1NjQ0MTcyNjc3NTZkNjU2ZTc0MDAwMzAzNjU2ZTc2MGY2NzY1NzQ0ZTc1NmQ0MTcyNjc3NTZkNjU2ZTc0NzMwMDAxMDM2NTZlNzYwYjczNjk2NzZlNjE2YzQ1NzI3MjZmNzIwMDAzMDM2NTZlNzYxMjZkNDI3NTY2NjY2NTcyNTM3NDZmNzI2MTY3NjU0YzZmNjE2NDAwMDIwMzY1NmU3NjE3NmQ0Mjc1NjY2NjY1NzI1NDZmNDI2OTY3NDk2ZTc0NTU2ZTczNjk2NzZlNjU2NDAwMDIwMzY1NmU3NjE5NmQ0Mjc1NjY2NjY1NzI0NjcyNmY2ZDQyNjk2NzQ5NmU3NDU1NmU3MzY5Njc2ZTY1NjQwMDAyMDM2NTZlNzYxMzZkNDI3NTY2NjY2NTcyNTM3NDZmNzI2MTY3NjU1Mzc0NmY3MjY1MDAwMjAzNjU2ZTc2MGY2ZDQyNzU2NjY2NjU3MjUzNjU3NDQyNzk3NDY1NzMwMDA1MDM2NTZlNzYwZTYzNjg2NTYzNmI0ZTZmNTA2MTc5NmQ2NTZlNzQwMDAwMDM2NTZlNzYxNDYyNjk2NzQ5NmU3NDQ2Njk2ZTY5NzM2ODU1NmU3MzY5Njc2ZTY1NjQwMDA0MDM2NTZlNzYwOTYyNjk2NzQ5NmU3NDQxNjQ2NDAwMDYwMzBiMGEwMTAxMDQwNzAzMDEwMDAwMDAwMDA1MDMwMTAwMDMwNjBmMDI3ZjAwNDFhMDgwMDgwYjdmMDA0MWEwODAwODBiMDc0NjA3MDY2ZDY1NmQ2ZjcyNzkwMjAwMDQ2OTZlNjk3NDAwMTEwNjY3NjU3NDUzNzU2ZDAwMTIwMzYxNjQ2NDAwMTMwODYzNjE2YzZjNDI2MTYzNmIwMDE0MGE1ZjVmNjQ2MTc0NjE1ZjY1NmU2NDAzMDAwYjVmNWY2ODY1NjE3MDVmNjI2MTczNjUwMzAxMGFjYTAxMGEwZTAxMDE3ZjQxMDAxMDBjMjIwMDEwMDAyMDAwMGIxOTAxMDE3ZjQxOWM4MDA4NDE5YzgwMDgyODAyMDA0MTAxNmIyMjAwMzYwMjAwMjAwMDBiMTQwMDEwMDEyMDAwNDYwNDQwMGYwYjQxODA4MDA4NDExOTEwMDIwMDBiMTYwMDIwMDAxMDBjMjIwMDEwMDMxYTIwMDAxMDBjMjIwMDEwMDQxYTIwMDAwYjE0MDEwMTdmMTAwYzIyMDIyMDAxMTAwNTFhMjAwMDIwMDIxMDA2MWEwYjEzMDEwMTdmMTAwYzIyMDA0MTk5ODAwODQxMDMxMDA3MWEyMDAwMGIxNDAxMDE3ZjEwMDg0MTAxMTAwZDEwMGIyMTAwMTAxMDIwMDAxMDBmMGIwZTAwMTAwODQxMDAxMDBkMTAxMDEwMGUxMDA5MGIyMjAxMDM3ZjEwMDg0MTAxMTAwZDEwMGIyMTAxMTAxMDIyMDIxMDBlMjIwMDIwMDAyMDAxMTAwYTIwMDIyMDAwMTAwZjBiMDMwMDAxMGIwYjJmMDIwMDQxODA4MDA4MGIxYzc3NzI2ZjZlNjcyMDZlNzU2ZDYyNjU3MjIwNmY2NjIwNjE3MjY3NzU2ZDY1NmU3NDczNzM3NTZkMDA0MTljODAwODBiMDQ5Y2ZmZmZmZkAwNTA2QDJh', 'chainID': 'D', 'version': 2, 'options': 0, 'guardian': '', 'signature': '', 'guardianSignature': ''}\n", + "Transaction data: upgradeContract@0061736d010000000129086000006000017f60027f7f017f60027f7f0060017f0060037f7f7f017f60037f7f7f0060017f017f0290020b03656e7619626967496e74476574556e7369676e6564417267756d656e74000303656e760f6765744e756d417267756d656e7473000103656e760b7369676e616c4572726f72000303656e76126d42756666657253746f726167654c6f6164000203656e76176d427566666572546f426967496e74556e7369676e6564000203656e76196d42756666657246726f6d426967496e74556e7369676e6564000203656e76136d42756666657253746f7261676553746f7265000203656e760f6d4275666665725365744279746573000503656e760e636865636b4e6f5061796d656e74000003656e7614626967496e7446696e697368556e7369676e6564000403656e7609626967496e744164640006030b0a010104070301000000000503010003060f027f0041a080080b7f0041a080080b074607066d656d6f7279020004696e697400110667657453756d00120361646400130863616c6c4261636b00140a5f5f646174615f656e6403000b5f5f686561705f6261736503010aca010a0e01017f4100100c2200100020000b1901017f419c8008419c800828020041016b220036020020000b1400100120004604400f0b4180800841191002000b16002000100c220010031a2000100c220010041a20000b1401017f100c2202200110051a2000200210061a0b1301017f100c220041998008410310071a20000b1401017f10084101100d100b210010102000100f0b0e0010084100100d1010100e10090b2201037f10084101100d100b210110102202100e220020002001100a20022000100f0b0300010b0b2f0200418080080b1c77726f6e67206e756d626572206f6620617267756d656e747373756d00419c80080b049cffffff@0506@2a\n" ] } ], "source": [ "contract_address = Address.from_bech32(\"erd1qqqqqqqqqqqqqpgquzmh78klkqwt0p4rjys0qtp3la07gz4d396qn50nnm\")\n", - "bytecode = Path(\"./data/counter.wasm\").read_bytes()\n", + "bytecode = Path(\"./contracts/adder.wasm\").read_bytes()\n", "\n", - "upgrade_transaction = sc_factory.create_transaction_for_upgrade(\n", + "upgrade_transaction = factory.create_transaction_for_upgrade(\n", " sender=alice,\n", " contract=contract_address,\n", " bytecode=bytecode,\n", " gas_limit=10000000,\n", - " arguments=[42, \"test\"],\n", + " arguments=[42],\n", " is_upgradeable=True,\n", " is_readable=True,\n", " is_payable=True,\n", @@ -757,56 +1031,168 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "Create a transaction that invokes a smart contract function:" + "## Contract interactions" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The recommended way to create transactions for calling (and, for that matter, deploying and upgrading) smart contracts is through a `SmartContractTransactionsFactory`." ] }, { "cell_type": "code", - "execution_count": 24, + "execution_count": 133, + "metadata": {}, + "outputs": [], + "source": [ + "from multiversx_sdk import SmartContractTransactionsFactory\n", + "\n", + "factory = SmartContractTransactionsFactory(config)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "If the contract ABI is available, provide it to the factory:" + ] + }, + { + "cell_type": "code", + "execution_count": 134, + "metadata": {}, + "outputs": [], + "source": [ + "abi = Abi.load(Path(\"contracts/adder.abi.json\"))\n", + "factory = SmartContractTransactionsFactory(config, abi)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Regular interactions" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now, let's prepare a contract transaction, to call the `add` function of our previously deployed smart contract:" + ] + }, + { + "cell_type": "code", + "execution_count": 135, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "Transaction: {'nonce': 0, 'value': '0', 'receiver': 'erd1qqqqqqqqqqqqqpgquzmh78klkqwt0p4rjys0qtp3la07gz4d396qn50nnm', 'sender': 'erd1qyu5wthldzr8wx5c9ucg8kjagg0jfs53s8nr3zpz3hypefsdd8ssycr6th', 'senderUsername': '', 'receiverUsername': '', 'gasPrice': 1000000000, 'gasLimit': 10000000, 'data': 'Zm9vQDJhQDc0NjU3Mzc0', 'chainID': 'D', 'version': 2, 'options': 0, 'guardian': '', 'signature': '', 'guardianSignature': ''}\n", - "Transaction data: foo@2a@74657374\n" + "Transaction: {'nonce': 0, 'value': '0', 'receiver': 'erd1qqqqqqqqqqqqqpgqws44xjx2t056nn79fn29q0rjwfrd3m43396ql35kxy', 'sender': 'erd1qyu5wthldzr8wx5c9ucg8kjagg0jfs53s8nr3zpz3hypefsdd8ssycr6th', 'senderUsername': '', 'receiverUsername': '', 'gasPrice': 1000000000, 'gasLimit': 10000000, 'data': 'YWRkQDJh', 'chainID': 'D', 'version': 2, 'options': 0, 'guardian': '', 'signature': '', 'guardianSignature': ''}\n", + "Transaction data: add@2a\n" ] } ], "source": [ - "contract_address = Address.from_bech32(\"erd1qqqqqqqqqqqqqpgquzmh78klkqwt0p4rjys0qtp3la07gz4d396qn50nnm\")\n", + "contract_address = Address.from_bech32(\"erd1qqqqqqqqqqqqqpgqws44xjx2t056nn79fn29q0rjwfrd3m43396ql35kxy\")\n", + "\n", + "# For arguments, use typed value objects if you haven't provided an ABI to the factory:\n", + "args = [U32Value(42)]\n", + "# Or use simple, plain Python values and objects if you have provided an ABI to the factory:\n", + "args = [42]\n", "\n", - "call_transaction = sc_factory.create_transaction_for_execute(\n", + "transaction = factory.create_transaction_for_execute(\n", " sender=alice,\n", " contract=contract_address,\n", - " function=\"foo\",\n", + " function=\"add\",\n", " gas_limit=10000000,\n", - " arguments=[42, \"test\"]\n", + " arguments=args\n", ")\n", "\n", - "print(\"Transaction:\", transaction_converter.transaction_to_dictionary(call_transaction))\n", - "print(\"Transaction data:\", call_transaction.data.decode())" + "print(\"Transaction:\", transaction_converter.transaction_to_dictionary(transaction))\n", + "print(\"Transaction data:\", transaction.data.decode())" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + ":::tip\n", + "When creating transactions using `SmartContractTransactionsFactory`, even if the ABI is available and provided,\n", + "you can still use _typed value_ objects as arguments for deployments and interactions.\n", + "\n", + "Even further, you can use a mix of _typed value_ objects and plain Python values and objects. For example:\n", + "```\n", + "args = [U32Value(42), \"hello\", { \"foo\": \"bar\" }, TokenIdentifierValue(\"TEST-abcdef\")];\n", + "```\n", + ":::" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + ":::note\n", + "Setting the transaction nonce, signing a transaction and broadcasting it are depicted in a later section.\n", + ":::" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Transfer & execute" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "At times, you may want to send some tokens (native EGLD or ESDT) along with the contract call.\n", + "\n", + "For transfer & execute with native EGLD, prepare your transaction as follows:" + ] + }, + { + "cell_type": "code", + "execution_count": 136, + "metadata": {}, + "outputs": [], + "source": [ + "transaction = factory.create_transaction_for_execute(\n", + " sender=alice,\n", + " contract=contract_address,\n", + " function=\"add\",\n", + " gas_limit=10000000,\n", + " arguments=[42],\n", + " native_transfer_amount=1000000000000000000\n", + ")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "Now, let's create a call that also transfers one or more tokens (**transfer & execute**):" + "Above, we're sending 1 EGLD along with the contract call.\n", + "\n", + "For transfer & execute with ESDT tokens, prepare your transaction as follows:" ] }, { "cell_type": "code", - "execution_count": 25, + "execution_count": 137, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "Transaction: {'nonce': 0, 'value': '0', 'receiver': 'erd1qyu5wthldzr8wx5c9ucg8kjagg0jfs53s8nr3zpz3hypefsdd8ssycr6th', 'sender': 'erd1qyu5wthldzr8wx5c9ucg8kjagg0jfs53s8nr3zpz3hypefsdd8ssycr6th', 'senderUsername': '', 'receiverUsername': '', 'gasPrice': 1000000000, 'gasLimit': 10000000, 'data': 'TXVsdGlFU0RUTkZUVHJhbnNmZXJAMDAwMDAwMDAwMDAwMDAwMDA1MDBlMGI3N2YxZWRmYjAxY2I3ODZhMzkxMjBmMDJjMzFmZjVmZTQwYWFkODk3NEAwMkA1NDQ1NTM1NDJkMzMzODY2MzIzNDM5QDAxQDAxQDQyNDE1MjJkNjMzODMwNjQzMjM5QEA4YWM3MjMwNDg5ZTgwMDAwQDY4NjU2YzZjNmZAMmFANzQ2NTczNzQ=', 'chainID': 'D', 'version': 2, 'options': 0, 'guardian': '', 'signature': '', 'guardianSignature': ''}\n", - "Transaction data: MultiESDTNFTTransfer@00000000000000000500e0b77f1edfb01cb786a39120f02c31ff5fe40aad8974@02@544553542d333866323439@01@01@4241522d633830643239@@8ac7230489e80000@68656c6c6f@2a@74657374\n" + "Transaction: {'nonce': 0, 'value': '0', 'receiver': 'erd1qyu5wthldzr8wx5c9ucg8kjagg0jfs53s8nr3zpz3hypefsdd8ssycr6th', 'sender': 'erd1qyu5wthldzr8wx5c9ucg8kjagg0jfs53s8nr3zpz3hypefsdd8ssycr6th', 'senderUsername': '', 'receiverUsername': '', 'gasPrice': 1000000000, 'gasLimit': 10000000, 'data': 'TXVsdGlFU0RUTkZUVHJhbnNmZXJAMDAwMDAwMDAwMDAwMDAwMDA1MDA3NDJiNTM0OGNhNWJlOWE5Y2ZjNTRjZDQ1MDNjNzI3MjQ2ZDhlZWIxODk3NEAwMkA1NDQ1NTM1NDJkMzMzODY2MzIzNDM5QDAxQDAxQDQyNDE1MjJkNjMzODMwNjQzMjM5QEA4YWM3MjMwNDg5ZTgwMDAwQDYxNjQ2NEAyYQ==', 'chainID': 'D', 'version': 2, 'options': 0, 'guardian': '', 'signature': '', 'guardianSignature': ''}\n", + "Transaction data: MultiESDTNFTTransfer@00000000000000000500742b5348ca5be9a9cfc54cd4503c727246d8eeb18974@02@544553542d333866323439@01@01@4241522d633830643239@@8ac7230489e80000@616464@2a\n" ] } ], @@ -819,17 +1205,39 @@ "\n", "transfers = [first_transfer, second_transfer]\n", "\n", - "call_transaction = sc_factory.create_transaction_for_execute(\n", + "transaction = factory.create_transaction_for_execute(\n", " sender=alice,\n", " contract=contract_address,\n", - " function=\"hello\",\n", + " function=\"add\",\n", " gas_limit=10000000,\n", - " arguments=[42, \"test\"],\n", + " arguments=[42],\n", " token_transfers=transfers\n", ")\n", "\n", - "print(\"Transaction:\", transaction_converter.transaction_to_dictionary(call_transaction))\n", - "print(\"Transaction data:\", call_transaction.data.decode())" + "print(\"Transaction:\", transaction_converter.transaction_to_dictionary(transaction))\n", + "print(\"Transaction data:\", transaction.data.decode())" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Parsing transaction outcome\n", + "\n", + ":::note\n", + "Documentation in this section is preliminary and subject to change.\n", + ":::" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Decode transaction events\n", + "\n", + ":::note\n", + "Documentation in this section is preliminary and subject to change.\n", + ":::" ] }, { @@ -843,31 +1251,64 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "In order to do a contract query against the network (more details about **network providers** can be found below), do as follows:" + "In order to perform Smart Contract queries, we recommend the use of `SmartContractQueriesController`.\n", + "\n", + "You will notice that the `SmartContractQueriesController` requires a `QueryRunner` object at initialization. A `NetworkProvider`, slighly adapted, is used to satisfy this requirement (more details about **network providers** can be found in a later section)." + ] + }, + { + "cell_type": "code", + "execution_count": 138, + "metadata": {}, + "outputs": [], + "source": [ + "from multiversx_sdk import (ProxyNetworkProvider, QueryRunnerAdapter,\n", + " SmartContractQueriesController)\n", + "\n", + "contract = Address.from_bech32(\"erd1qqqqqqqqqqqqqpgqqy34h7he2ya6qcagqre7ur7cc65vt0mxrc8qnudkr4\")\n", + "query_runner = QueryRunnerAdapter(ProxyNetworkProvider(\"https://devnet-api.multiversx.com\"))\n", + "\n", + "query_controller = SmartContractQueriesController(query_runner)\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "If the contract ABI is available, provide it to the controller:" ] }, { "cell_type": "code", - "execution_count": 26, + "execution_count": 139, + "metadata": {}, + "outputs": [], + "source": [ + "abi = Abi.load(Path(\"contracts/adder.abi.json\"))\n", + "query_controller = SmartContractQueriesController(query_runner, abi)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Query the contract as follows:" + ] + }, + { + "cell_type": "code", + "execution_count": 140, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "Return data (parsed): [b'\\x05']\n" + "Return data (parsed): [5]\n" ] } ], "source": [ - "from multiversx_sdk import (ProxyNetworkProvider, QueryRunnerAdapter,\n", - " SmartContractQueriesController)\n", - "\n", - "contract = Address.from_bech32(\"erd1qqqqqqqqqqqqqpgqqy34h7he2ya6qcagqre7ur7cc65vt0mxrc8qnudkr4\")\n", - "query_runner = QueryRunnerAdapter(ProxyNetworkProvider(\"https://devnet-api.multiversx.com\"))\n", - "\n", - "query_controller = SmartContractQueriesController(query_runner)\n", - "\n", "data_parts = query_controller.query(\n", " contract=contract.to_bech32(),\n", " function=\"getSum\",\n", @@ -886,7 +1327,7 @@ }, { "cell_type": "code", - "execution_count": 56, + "execution_count": 141, "metadata": {}, "outputs": [ { @@ -895,7 +1336,7 @@ "text": [ "Return code: ok\n", "Return data (raw): [b'\\x05']\n", - "Return data (parsed): [b'\\x05']\n" + "Return data (parsed): [5]\n" ] } ], @@ -930,14 +1371,14 @@ }, { "cell_type": "code", - "execution_count": 4, + "execution_count": 142, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "['duck', 'road', 'best', 'card', 'rapid', 'belt', 'shuffle', 'umbrella', 'trophy', 'donor', 'discover', 'maple', 'inherit', 'play', 'chat', 'need', 'siege', 'tiny', 'broom', 'ugly', 'margin', 'life', 'shove', 'frown']\n" + "['circle', 'found', 'capable', 'scissors', 'catalog', 'soda', 'media', 'bundle', 'amateur', 'frown', 'normal', 'device', 'mobile', 'royal', 'pretty', 'leaf', 'agent', 'disease', 'tube', 'hire', 'yellow', 'rebuild', 'squeeze', 'thunder']\n" ] } ], @@ -960,7 +1401,7 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": 143, "metadata": {}, "outputs": [], "source": [ @@ -984,15 +1425,15 @@ }, { "cell_type": "code", - "execution_count": 10, + "execution_count": 144, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "Secret key: 2f0c8a8f516f820c09d1c13a35cf90eaedcb59a66203810b515c4c6162e0a234\n", - "Public key: b80a407e1a7e05ef0b5b91351b1818e695a2defb41ff211311f99aad9846394f\n" + "Secret key: 75df52e4e866dd1f68eb3b5919aabd9d8a38355c654d04a3b3fbeb0aed6d2ed3\n", + "Public key: cb388f029b3f14e9b38f083903980a1d7d414db5dc0bddcb48759fdcdc0fed05\n" ] } ], @@ -1014,7 +1455,7 @@ }, { "cell_type": "code", - "execution_count": 11, + "execution_count": 145, "metadata": {}, "outputs": [], "source": [ @@ -1035,7 +1476,7 @@ }, { "cell_type": "code", - "execution_count": 13, + "execution_count": 146, "metadata": {}, "outputs": [], "source": [ @@ -1074,7 +1515,7 @@ }, { "cell_type": "code", - "execution_count": 31, + "execution_count": 147, "metadata": {}, "outputs": [ { @@ -1106,7 +1547,7 @@ }, { "cell_type": "code", - "execution_count": 32, + "execution_count": 148, "metadata": {}, "outputs": [ { @@ -1136,7 +1577,7 @@ }, { "cell_type": "code", - "execution_count": 33, + "execution_count": 149, "metadata": {}, "outputs": [ { @@ -1173,7 +1614,7 @@ }, { "cell_type": "code", - "execution_count": 34, + "execution_count": 150, "metadata": {}, "outputs": [], "source": [ @@ -1191,7 +1632,7 @@ }, { "cell_type": "code", - "execution_count": 35, + "execution_count": 151, "metadata": {}, "outputs": [], "source": [ @@ -1207,7 +1648,7 @@ }, { "cell_type": "code", - "execution_count": 36, + "execution_count": 152, "metadata": {}, "outputs": [ { @@ -1245,7 +1686,7 @@ }, { "cell_type": "code", - "execution_count": 37, + "execution_count": 153, "metadata": {}, "outputs": [ { @@ -1284,7 +1725,7 @@ }, { "cell_type": "code", - "execution_count": 38, + "execution_count": 154, "metadata": {}, "outputs": [], "source": [ @@ -1306,7 +1747,7 @@ }, { "cell_type": "code", - "execution_count": 39, + "execution_count": 155, "metadata": {}, "outputs": [ { @@ -1355,7 +1796,7 @@ }, { "cell_type": "code", - "execution_count": 40, + "execution_count": 156, "metadata": {}, "outputs": [], "source": [ @@ -1373,7 +1814,7 @@ }, { "cell_type": "code", - "execution_count": 41, + "execution_count": 157, "metadata": {}, "outputs": [], "source": [ @@ -1398,7 +1839,7 @@ }, { "cell_type": "code", - "execution_count": 42, + "execution_count": 158, "metadata": {}, "outputs": [ { @@ -1433,15 +1874,15 @@ }, { "cell_type": "code", - "execution_count": 43, + "execution_count": 159, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "Nonce: 1133\n", - "Balance: 17869817183859999837\n" + "Nonce: 1459\n", + "Balance: 7728563062706014403\n" ] } ], @@ -1461,7 +1902,7 @@ }, { "cell_type": "code", - "execution_count": 44, + "execution_count": 160, "metadata": {}, "outputs": [], "source": [ @@ -1496,14 +1937,14 @@ }, { "cell_type": "code", - "execution_count": 45, + "execution_count": 161, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "Transaction hash: 4c57f147644bf21ad83c5e732e95dd6cebf56bded40827929130dfcc1bf721c5\n" + "Transaction hash: 16d7a645955ce7aac94301ad591df45e74fda401d5c644d957206b96b196f120\n" ] } ], @@ -1535,14 +1976,14 @@ }, { "cell_type": "code", - "execution_count": 46, + "execution_count": 162, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "Transactions hashes: (3, {'0': '4c57f147644bf21ad83c5e732e95dd6cebf56bded40827929130dfcc1bf721c5', '1': '1dc19cc442afdc80bfe341120778b197bd24e5f4ff41511f9be8b882132060d8', '2': '795e81c21c4c613479ebdbfc466140d8c24574f71d672bcffd2e5fee0580da42'})\n" + "Transactions hashes: (3, {'0': '16d7a645955ce7aac94301ad591df45e74fda401d5c644d957206b96b196f120', '1': '9735c6f072a93375b07cfdfbe89b51cb23e86f93f0acc92ec6ec2062349ad6ea', '2': 'b1178a243c1185f543478a54ba991816820b165f366ad8e2a6079ab257334270'})\n" ] } ], @@ -1592,7 +2033,7 @@ }, { "cell_type": "code", - "execution_count": 47, + "execution_count": 163, "metadata": {}, "outputs": [ { From 0de38e2f7d7173326fa1815da5da4cb3e991aabe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrei=20B=C4=83ncioiu?= Date: Mon, 17 Jun 2024 11:58:46 +0300 Subject: [PATCH 5/9] API docs. --- docs/multiversx_sdk.abi.rst | 229 ++++++++++++++++++++++++++++++++++++ docs/multiversx_sdk.rst | 1 + 2 files changed, 230 insertions(+) create mode 100644 docs/multiversx_sdk.abi.rst diff --git a/docs/multiversx_sdk.abi.rst b/docs/multiversx_sdk.abi.rst new file mode 100644 index 00000000..a3a7f9bf --- /dev/null +++ b/docs/multiversx_sdk.abi.rst @@ -0,0 +1,229 @@ +multiversx\_sdk.abi package +=========================== + +Submodules +---------- + +multiversx\_sdk.abi.abi module +------------------------------ + +.. automodule:: multiversx_sdk.abi.abi + :members: + :undoc-members: + :show-inheritance: + +multiversx\_sdk.abi.abi\_definition module +------------------------------------------ + +.. automodule:: multiversx_sdk.abi.abi_definition + :members: + :undoc-members: + :show-inheritance: + +multiversx\_sdk.abi.address\_value module +----------------------------------------- + +.. automodule:: multiversx_sdk.abi.address_value + :members: + :undoc-members: + :show-inheritance: + +multiversx\_sdk.abi.bigint\_value module +---------------------------------------- + +.. automodule:: multiversx_sdk.abi.bigint_value + :members: + :undoc-members: + :show-inheritance: + +multiversx\_sdk.abi.biguint\_value module +----------------------------------------- + +.. automodule:: multiversx_sdk.abi.biguint_value + :members: + :undoc-members: + :show-inheritance: + +multiversx\_sdk.abi.bool\_value module +-------------------------------------- + +.. automodule:: multiversx_sdk.abi.bool_value + :members: + :undoc-members: + :show-inheritance: + +multiversx\_sdk.abi.bytes\_value module +--------------------------------------- + +.. automodule:: multiversx_sdk.abi.bytes_value + :members: + :undoc-members: + :show-inheritance: + +multiversx\_sdk.abi.codec module +-------------------------------- + +.. automodule:: multiversx_sdk.abi.codec + :members: + :undoc-members: + :show-inheritance: + +multiversx\_sdk.abi.enum\_value module +-------------------------------------- + +.. automodule:: multiversx_sdk.abi.enum_value + :members: + :undoc-members: + :show-inheritance: + +multiversx\_sdk.abi.fields module +--------------------------------- + +.. automodule:: multiversx_sdk.abi.fields + :members: + :undoc-members: + :show-inheritance: + +multiversx\_sdk.abi.interface module +------------------------------------ + +.. automodule:: multiversx_sdk.abi.interface + :members: + :undoc-members: + :show-inheritance: + +multiversx\_sdk.abi.list\_value module +-------------------------------------- + +.. automodule:: multiversx_sdk.abi.list_value + :members: + :undoc-members: + :show-inheritance: + +multiversx\_sdk.abi.multi\_value module +--------------------------------------- + +.. automodule:: multiversx_sdk.abi.multi_value + :members: + :undoc-members: + :show-inheritance: + +multiversx\_sdk.abi.option\_value module +---------------------------------------- + +.. automodule:: multiversx_sdk.abi.option_value + :members: + :undoc-members: + :show-inheritance: + +multiversx\_sdk.abi.optional\_value module +------------------------------------------ + +.. automodule:: multiversx_sdk.abi.optional_value + :members: + :undoc-members: + :show-inheritance: + +multiversx\_sdk.abi.parts module +-------------------------------- + +.. automodule:: multiversx_sdk.abi.parts + :members: + :undoc-members: + :show-inheritance: + +multiversx\_sdk.abi.serializer module +------------------------------------- + +.. automodule:: multiversx_sdk.abi.serializer + :members: + :undoc-members: + :show-inheritance: + +multiversx\_sdk.abi.shared module +--------------------------------- + +.. automodule:: multiversx_sdk.abi.shared + :members: + :undoc-members: + :show-inheritance: + +multiversx\_sdk.abi.small\_int\_values module +--------------------------------------------- + +.. automodule:: multiversx_sdk.abi.small_int_values + :members: + :undoc-members: + :show-inheritance: + +multiversx\_sdk.abi.string\_value module +---------------------------------------- + +.. automodule:: multiversx_sdk.abi.string_value + :members: + :undoc-members: + :show-inheritance: + +multiversx\_sdk.abi.struct\_value module +---------------------------------------- + +.. automodule:: multiversx_sdk.abi.struct_value + :members: + :undoc-members: + :show-inheritance: + +multiversx\_sdk.abi.token\_identifier\_value module +--------------------------------------------------- + +.. automodule:: multiversx_sdk.abi.token_identifier_value + :members: + :undoc-members: + :show-inheritance: + +multiversx\_sdk.abi.tuple\_value module +--------------------------------------- + +.. automodule:: multiversx_sdk.abi.tuple_value + :members: + :undoc-members: + :show-inheritance: + +multiversx\_sdk.abi.type\_formula module +---------------------------------------- + +.. automodule:: multiversx_sdk.abi.type_formula + :members: + :undoc-members: + :show-inheritance: + +multiversx\_sdk.abi.type\_formula\_parser module +------------------------------------------------ + +.. automodule:: multiversx_sdk.abi.type_formula_parser + :members: + :undoc-members: + :show-inheritance: + +multiversx\_sdk.abi.typesystem module +------------------------------------- + +.. automodule:: multiversx_sdk.abi.typesystem + :members: + :undoc-members: + :show-inheritance: + +multiversx\_sdk.abi.variadic\_values module +------------------------------------------- + +.. automodule:: multiversx_sdk.abi.variadic_values + :members: + :undoc-members: + :show-inheritance: + +Module contents +--------------- + +.. automodule:: multiversx_sdk.abi + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/multiversx_sdk.rst b/docs/multiversx_sdk.rst index 5602d523..45d0f95f 100644 --- a/docs/multiversx_sdk.rst +++ b/docs/multiversx_sdk.rst @@ -7,6 +7,7 @@ Subpackages .. toctree:: :maxdepth: 4 + multiversx_sdk.abi multiversx_sdk.adapters multiversx_sdk.converters multiversx_sdk.core From d53c7b2b40d4f620a0e78a3d9eee0c151e768974 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrei=20B=C4=83ncioiu?= Date: Mon, 17 Jun 2024 13:05:35 +0300 Subject: [PATCH 6/9] Fix after self-review. --- examples/Cookbook.ipynb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/Cookbook.ipynb b/examples/Cookbook.ipynb index cf95c9a7..78a18aa9 100644 --- a/examples/Cookbook.ipynb +++ b/examples/Cookbook.ipynb @@ -983,14 +983,14 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "### Contract upgrades" + "## Contract upgrades" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "Contract upgrade transactions are similar to deployment transactions, in the sense that they also require a contract bytecode. In this context, though, the contract address is already known." + "Contract upgrade transactions are similar to deployment transactions (see above), in the sense that they also require a contract bytecode. In this context, though, the contract address is already known." ] }, { From d0c5b8c9ac94ea689af94d29feb230137d156cc7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrei=20B=C4=83ncioiu?= Date: Mon, 17 Jun 2024 13:11:21 +0300 Subject: [PATCH 7/9] Bump version. --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 7ba0a2d9..54d972eb 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -7,7 +7,7 @@ allow-direct-references = true [project] name = "multiversx-sdk" -version = "0.9.1" +version = "0.10.0" authors = [ { name="MultiversX" }, ] From 860da50fde076195d58d6d25b1f8656b7244a49b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrei=20B=C4=83ncioiu?= Date: Mon, 17 Jun 2024 13:58:30 +0300 Subject: [PATCH 8/9] Fix after review. --- examples/Cookbook.ipynb | 40 ++++++++++++++-------------------------- 1 file changed, 14 insertions(+), 26 deletions(-) diff --git a/examples/Cookbook.ipynb b/examples/Cookbook.ipynb index 78a18aa9..f6c2f277 100644 --- a/examples/Cookbook.ipynb +++ b/examples/Cookbook.ipynb @@ -317,8 +317,8 @@ "from multiversx_sdk import TransferTransactionsFactory\n", "\n", "transfer_factory = TransferTransactionsFactory(config=config)\n", - "alice = Address.from_bech32(\"erd1qyu5wthldzr8wx5c9ucg8kjagg0jfs53s8nr3zpz3hypefsdd8ssycr6th\")\n", - "bob = Address.from_bech32(\"erd1spyavw0956vq68xj8y4tenjpq2wd5a9p2c6j8gsz7ztyrnpxrruqzu66jx\")\n", + "alice = Address.new_from_bech32(\"erd1qyu5wthldzr8wx5c9ucg8kjagg0jfs53s8nr3zpz3hypefsdd8ssycr6th\")\n", + "bob = Address.new_from_bech32(\"erd1spyavw0956vq68xj8y4tenjpq2wd5a9p2c6j8gsz7ztyrnpxrruqzu66jx\")\n", "\n", "# With \"data\" field\n", "transaction = transfer_factory.create_transaction_for_native_token_transfer(\n", @@ -588,7 +588,7 @@ "\n", "config = TransactionsFactoryConfig(chain_id=\"D\")\n", "factory = RelayedTransactionsFactory(config=config)\n", - "relayer = Address.from_bech32(\"erd1qyu5wthldzr8wx5c9ucg8kjagg0jfs53s8nr3zpz3hypefsdd8ssycr6th\")\n", + "relayer = Address.new_from_bech32(\"erd1qyu5wthldzr8wx5c9ucg8kjagg0jfs53s8nr3zpz3hypefsdd8ssycr6th\")\n", "\n", "relayed_tx = factory.create_relayed_v1_transaction(\n", " inner_transaction=inner_tx,\n", @@ -642,7 +642,7 @@ "\n", "config = TransactionsFactoryConfig(chain_id=\"D\")\n", "factory = RelayedTransactionsFactory(config=config)\n", - "relayer = Address.from_bech32(\"erd1qyu5wthldzr8wx5c9ucg8kjagg0jfs53s8nr3zpz3hypefsdd8ssycr6th\")\n", + "relayer = Address.new_from_bech32(\"erd1qyu5wthldzr8wx5c9ucg8kjagg0jfs53s8nr3zpz3hypefsdd8ssycr6th\")\n", "\n", "relayed_tx = factory.create_relayed_v2_transaction(\n", " inner_transaction=inner_tx,\n", @@ -880,24 +880,20 @@ "cell_type": "markdown", "metadata": {}, "source": [ - ":::tip\n", "When creating transactions using `SmartContractTransactionsFactory`, even if the ABI is available and provided,\n", "you can still use _typed value_ objects as arguments for deployments and interactions.\n", "\n", "Even further, you can use a mix of _typed value_ objects and plain Python values and objects. For example:\n", "```\n", "args = [U32Value(42), \"hello\", { \"foo\": \"bar\" }, TokenIdentifierValue(\"TEST-abcdef\")];\n", - "```\n", - ":::" + "```" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - ":::note\n", - "Setting the transaction nonce, signing a transaction and broadcasting it are depicted in a later section.\n", - ":::" + "Setting the transaction nonce, signing a transaction and broadcasting it are depicted in a later section." ] }, { @@ -1008,7 +1004,7 @@ } ], "source": [ - "contract_address = Address.from_bech32(\"erd1qqqqqqqqqqqqqpgquzmh78klkqwt0p4rjys0qtp3la07gz4d396qn50nnm\")\n", + "contract_address = Address.new_from_bech32(\"erd1qqqqqqqqqqqqqpgquzmh78klkqwt0p4rjys0qtp3la07gz4d396qn50nnm\")\n", "bytecode = Path(\"./contracts/adder.wasm\").read_bytes()\n", "\n", "upgrade_transaction = factory.create_transaction_for_upgrade(\n", @@ -1098,7 +1094,7 @@ } ], "source": [ - "contract_address = Address.from_bech32(\"erd1qqqqqqqqqqqqqpgqws44xjx2t056nn79fn29q0rjwfrd3m43396ql35kxy\")\n", + "contract_address = Address.new_from_bech32(\"erd1qqqqqqqqqqqqqpgqws44xjx2t056nn79fn29q0rjwfrd3m43396ql35kxy\")\n", "\n", "# For arguments, use typed value objects if you haven't provided an ABI to the factory:\n", "args = [U32Value(42)]\n", @@ -1121,24 +1117,20 @@ "cell_type": "markdown", "metadata": {}, "source": [ - ":::tip\n", "When creating transactions using `SmartContractTransactionsFactory`, even if the ABI is available and provided,\n", "you can still use _typed value_ objects as arguments for deployments and interactions.\n", "\n", "Even further, you can use a mix of _typed value_ objects and plain Python values and objects. For example:\n", "```\n", "args = [U32Value(42), \"hello\", { \"foo\": \"bar\" }, TokenIdentifierValue(\"TEST-abcdef\")];\n", - "```\n", - ":::" + "```" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - ":::note\n", - "Setting the transaction nonce, signing a transaction and broadcasting it are depicted in a later section.\n", - ":::" + "Setting the transaction nonce, signing a transaction and broadcasting it are depicted in a later section." ] }, { @@ -1224,9 +1216,7 @@ "source": [ "### Parsing transaction outcome\n", "\n", - ":::note\n", - "Documentation in this section is preliminary and subject to change.\n", - ":::" + "Documentation in this section is preliminary and subject to change." ] }, { @@ -1235,9 +1225,7 @@ "source": [ "### Decode transaction events\n", "\n", - ":::note\n", - "Documentation in this section is preliminary and subject to change.\n", - ":::" + "Documentation in this section is preliminary and subject to change." ] }, { @@ -1265,7 +1253,7 @@ "from multiversx_sdk import (ProxyNetworkProvider, QueryRunnerAdapter,\n", " SmartContractQueriesController)\n", "\n", - "contract = Address.from_bech32(\"erd1qqqqqqqqqqqqqpgqqy34h7he2ya6qcagqre7ur7cc65vt0mxrc8qnudkr4\")\n", + "contract = Address.new_from_bech32(\"erd1qqqqqqqqqqqqqpgqqy34h7he2ya6qcagqre7ur7cc65vt0mxrc8qnudkr4\")\n", "query_runner = QueryRunnerAdapter(ProxyNetworkProvider(\"https://devnet-api.multiversx.com\"))\n", "\n", "query_controller = SmartContractQueriesController(query_runner)\n" @@ -1949,7 +1937,7 @@ } ], "source": [ - "alice = Address.from_bech32(\"erd1qyu5wthldzr8wx5c9ucg8kjagg0jfs53s8nr3zpz3hypefsdd8ssycr6th\")\n", + "alice = Address.new_from_bech32(\"erd1qyu5wthldzr8wx5c9ucg8kjagg0jfs53s8nr3zpz3hypefsdd8ssycr6th\")\n", "\n", "tx = Transaction(\n", " sender=alice.to_bech32(),\n", From 8efbf82e9bde0e6c3d4616be638b08ad703219f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrei=20B=C4=83ncioiu?= Date: Mon, 17 Jun 2024 14:03:30 +0300 Subject: [PATCH 9/9] Fix after review. --- examples/Cookbook.ipynb | 140 +++++++++--------- ...tract_transactions_outcome_parser_types.py | 3 + 2 files changed, 73 insertions(+), 70 deletions(-) diff --git a/examples/Cookbook.ipynb b/examples/Cookbook.ipynb index f6c2f277..0aee1a5c 100644 --- a/examples/Cookbook.ipynb +++ b/examples/Cookbook.ipynb @@ -2,7 +2,7 @@ "cells": [ { "cell_type": "code", - "execution_count": 102, + "execution_count": 63, "metadata": {}, "outputs": [], "source": [ @@ -26,7 +26,7 @@ }, { "cell_type": "code", - "execution_count": 103, + "execution_count": 64, "metadata": {}, "outputs": [ { @@ -58,7 +58,7 @@ }, { "cell_type": "code", - "execution_count": 104, + "execution_count": 65, "metadata": {}, "outputs": [], "source": [ @@ -74,7 +74,7 @@ }, { "cell_type": "code", - "execution_count": 105, + "execution_count": 66, "metadata": {}, "outputs": [], "source": [ @@ -91,7 +91,7 @@ }, { "cell_type": "code", - "execution_count": 106, + "execution_count": 67, "metadata": {}, "outputs": [], "source": [ @@ -113,7 +113,7 @@ }, { "cell_type": "code", - "execution_count": 107, + "execution_count": 68, "metadata": {}, "outputs": [ { @@ -139,7 +139,7 @@ }, { "cell_type": "code", - "execution_count": 108, + "execution_count": 69, "metadata": {}, "outputs": [ { @@ -166,7 +166,7 @@ }, { "cell_type": "code", - "execution_count": 109, + "execution_count": 70, "metadata": {}, "outputs": [ { @@ -199,7 +199,7 @@ }, { "cell_type": "code", - "execution_count": 110, + "execution_count": 71, "metadata": {}, "outputs": [ { @@ -249,7 +249,7 @@ }, { "cell_type": "code", - "execution_count": 111, + "execution_count": 72, "metadata": {}, "outputs": [ { @@ -283,7 +283,7 @@ }, { "cell_type": "code", - "execution_count": 112, + "execution_count": 73, "metadata": {}, "outputs": [], "source": [ @@ -301,7 +301,7 @@ }, { "cell_type": "code", - "execution_count": 113, + "execution_count": 74, "metadata": {}, "outputs": [ { @@ -341,7 +341,7 @@ }, { "cell_type": "code", - "execution_count": 114, + "execution_count": 75, "metadata": {}, "outputs": [ { @@ -380,7 +380,7 @@ }, { "cell_type": "code", - "execution_count": 115, + "execution_count": 76, "metadata": {}, "outputs": [ { @@ -415,7 +415,7 @@ }, { "cell_type": "code", - "execution_count": 116, + "execution_count": 77, "metadata": {}, "outputs": [ { @@ -450,7 +450,7 @@ }, { "cell_type": "code", - "execution_count": 117, + "execution_count": 78, "metadata": {}, "outputs": [ { @@ -497,7 +497,7 @@ }, { "cell_type": "code", - "execution_count": 118, + "execution_count": 79, "metadata": {}, "outputs": [ { @@ -536,7 +536,7 @@ }, { "cell_type": "code", - "execution_count": 119, + "execution_count": 80, "metadata": {}, "outputs": [], "source": [ @@ -555,7 +555,7 @@ }, { "cell_type": "code", - "execution_count": 120, + "execution_count": 81, "metadata": {}, "outputs": [ { @@ -608,7 +608,7 @@ }, { "cell_type": "code", - "execution_count": 121, + "execution_count": 82, "metadata": {}, "outputs": [ { @@ -672,7 +672,7 @@ }, { "cell_type": "code", - "execution_count": 122, + "execution_count": 83, "metadata": {}, "outputs": [], "source": [ @@ -691,7 +691,7 @@ }, { "cell_type": "code", - "execution_count": 123, + "execution_count": 84, "metadata": {}, "outputs": [], "source": [ @@ -714,7 +714,7 @@ }, { "cell_type": "code", - "execution_count": 124, + "execution_count": 85, "metadata": {}, "outputs": [], "source": [ @@ -741,7 +741,7 @@ }, { "cell_type": "code", - "execution_count": 125, + "execution_count": 86, "metadata": {}, "outputs": [], "source": [ @@ -786,7 +786,7 @@ }, { "cell_type": "code", - "execution_count": 126, + "execution_count": 87, "metadata": {}, "outputs": [], "source": [ @@ -806,7 +806,7 @@ }, { "cell_type": "code", - "execution_count": 127, + "execution_count": 88, "metadata": {}, "outputs": [], "source": [ @@ -824,7 +824,7 @@ }, { "cell_type": "code", - "execution_count": 128, + "execution_count": 89, "metadata": {}, "outputs": [], "source": [ @@ -841,7 +841,7 @@ }, { "cell_type": "code", - "execution_count": 129, + "execution_count": 90, "metadata": {}, "outputs": [ { @@ -912,7 +912,7 @@ }, { "cell_type": "code", - "execution_count": 130, + "execution_count": 91, "metadata": {}, "outputs": [ { @@ -951,14 +951,14 @@ }, { "cell_type": "code", - "execution_count": 131, + "execution_count": 92, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "SmartContractDeployOutcome(return_code='', return_message='', contracts=[DeployedSmartContract(address='erd1qqqqqqqqqqqqqpgqws44xjx2t056nn79fn29q0rjwfrd3m43396ql35kxy', owner_address='erd1testnlersh4z0wsv8kjx39me4rmnvjkwu8dsaea7ukdvvc9z396qykv7z7', code_hash=b'8Kh\\r\\xf7\\xa9^\\xbc\\xec\\xa0/\\xfb>v\\n/\\xc2\\x88\\xde\\xa1\\xb8\\x02h^\\xf1]\\xf2*\\xe8\\x8b\\xa1[')])\n" + "SmartContractDeployOutcome(return_code='', return_message='', contracts=[DeployedSmartContract(address=erd1qqqqqqqqqqqqqpgqws44xjx2t056nn79fn29q0rjwfrd3m43396ql35kxy, owner_address=erd1testnlersh4z0wsv8kjx39me4rmnvjkwu8dsaea7ukdvvc9z396qykv7z7, code_hash=384b680df7a95ebceca02ffb3e760a2fc288dea1b802685ef15df22ae88ba15b)])\n" ] } ], @@ -991,7 +991,7 @@ }, { "cell_type": "code", - "execution_count": 132, + "execution_count": 93, "metadata": {}, "outputs": [ { @@ -1039,7 +1039,7 @@ }, { "cell_type": "code", - "execution_count": 133, + "execution_count": 94, "metadata": {}, "outputs": [], "source": [ @@ -1057,7 +1057,7 @@ }, { "cell_type": "code", - "execution_count": 134, + "execution_count": 95, "metadata": {}, "outputs": [], "source": [ @@ -1081,7 +1081,7 @@ }, { "cell_type": "code", - "execution_count": 135, + "execution_count": 96, "metadata": {}, "outputs": [ { @@ -1151,7 +1151,7 @@ }, { "cell_type": "code", - "execution_count": 136, + "execution_count": 97, "metadata": {}, "outputs": [], "source": [ @@ -1176,7 +1176,7 @@ }, { "cell_type": "code", - "execution_count": 137, + "execution_count": 98, "metadata": {}, "outputs": [ { @@ -1246,7 +1246,7 @@ }, { "cell_type": "code", - "execution_count": 138, + "execution_count": 99, "metadata": {}, "outputs": [], "source": [ @@ -1268,7 +1268,7 @@ }, { "cell_type": "code", - "execution_count": 139, + "execution_count": 100, "metadata": {}, "outputs": [], "source": [ @@ -1285,7 +1285,7 @@ }, { "cell_type": "code", - "execution_count": 140, + "execution_count": 101, "metadata": {}, "outputs": [ { @@ -1315,7 +1315,7 @@ }, { "cell_type": "code", - "execution_count": 141, + "execution_count": 102, "metadata": {}, "outputs": [ { @@ -1359,14 +1359,14 @@ }, { "cell_type": "code", - "execution_count": 142, + "execution_count": 103, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "['circle', 'found', 'capable', 'scissors', 'catalog', 'soda', 'media', 'bundle', 'amateur', 'frown', 'normal', 'device', 'mobile', 'royal', 'pretty', 'leaf', 'agent', 'disease', 'tube', 'hire', 'yellow', 'rebuild', 'squeeze', 'thunder']\n" + "['calm', 'correct', 'orchard', 'earn', 'army', 'tower', 'token', 'dice', 'bleak', 'tackle', 'copper', 'walnut', 'sell', 'cradle', 'typical', 'supreme', 'lesson', 'laundry', 'silk', 'sand', 'feel', 'cancel', 'shoulder', 'rail']\n" ] } ], @@ -1389,7 +1389,7 @@ }, { "cell_type": "code", - "execution_count": 143, + "execution_count": 104, "metadata": {}, "outputs": [], "source": [ @@ -1413,15 +1413,15 @@ }, { "cell_type": "code", - "execution_count": 144, + "execution_count": 105, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "Secret key: 75df52e4e866dd1f68eb3b5919aabd9d8a38355c654d04a3b3fbeb0aed6d2ed3\n", - "Public key: cb388f029b3f14e9b38f083903980a1d7d414db5dc0bddcb48759fdcdc0fed05\n" + "Secret key: 74a35a90d0554b87277f432b00db2b2c17543034c86f3d23204f4d75cb2ca0a9\n", + "Public key: 2234d1d5eee679f5391d3c04678ee7761a3692e2f5b15393248a8a28b35d1a98\n" ] } ], @@ -1443,7 +1443,7 @@ }, { "cell_type": "code", - "execution_count": 145, + "execution_count": 106, "metadata": {}, "outputs": [], "source": [ @@ -1464,7 +1464,7 @@ }, { "cell_type": "code", - "execution_count": 146, + "execution_count": 107, "metadata": {}, "outputs": [], "source": [ @@ -1503,7 +1503,7 @@ }, { "cell_type": "code", - "execution_count": 147, + "execution_count": 108, "metadata": {}, "outputs": [ { @@ -1535,7 +1535,7 @@ }, { "cell_type": "code", - "execution_count": 148, + "execution_count": 109, "metadata": {}, "outputs": [ { @@ -1565,7 +1565,7 @@ }, { "cell_type": "code", - "execution_count": 149, + "execution_count": 110, "metadata": {}, "outputs": [ { @@ -1602,7 +1602,7 @@ }, { "cell_type": "code", - "execution_count": 150, + "execution_count": 111, "metadata": {}, "outputs": [], "source": [ @@ -1620,7 +1620,7 @@ }, { "cell_type": "code", - "execution_count": 151, + "execution_count": 112, "metadata": {}, "outputs": [], "source": [ @@ -1636,7 +1636,7 @@ }, { "cell_type": "code", - "execution_count": 152, + "execution_count": 113, "metadata": {}, "outputs": [ { @@ -1674,7 +1674,7 @@ }, { "cell_type": "code", - "execution_count": 153, + "execution_count": 114, "metadata": {}, "outputs": [ { @@ -1713,7 +1713,7 @@ }, { "cell_type": "code", - "execution_count": 154, + "execution_count": 115, "metadata": {}, "outputs": [], "source": [ @@ -1735,7 +1735,7 @@ }, { "cell_type": "code", - "execution_count": 155, + "execution_count": 116, "metadata": {}, "outputs": [ { @@ -1784,7 +1784,7 @@ }, { "cell_type": "code", - "execution_count": 156, + "execution_count": 117, "metadata": {}, "outputs": [], "source": [ @@ -1802,7 +1802,7 @@ }, { "cell_type": "code", - "execution_count": 157, + "execution_count": 118, "metadata": {}, "outputs": [], "source": [ @@ -1827,7 +1827,7 @@ }, { "cell_type": "code", - "execution_count": 158, + "execution_count": 119, "metadata": {}, "outputs": [ { @@ -1862,15 +1862,15 @@ }, { "cell_type": "code", - "execution_count": 159, + "execution_count": 120, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "Nonce: 1459\n", - "Balance: 7728563062706014403\n" + "Nonce: 1465\n", + "Balance: 7728263062706014403\n" ] } ], @@ -1890,7 +1890,7 @@ }, { "cell_type": "code", - "execution_count": 160, + "execution_count": 121, "metadata": {}, "outputs": [], "source": [ @@ -1925,14 +1925,14 @@ }, { "cell_type": "code", - "execution_count": 161, + "execution_count": 122, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "Transaction hash: 16d7a645955ce7aac94301ad591df45e74fda401d5c644d957206b96b196f120\n" + "Transaction hash: 0e32fcf92dc500c343714092df451296820bcd35d1158302729fe7d6b505a1ce\n" ] } ], @@ -1964,14 +1964,14 @@ }, { "cell_type": "code", - "execution_count": 162, + "execution_count": 123, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "Transactions hashes: (3, {'0': '16d7a645955ce7aac94301ad591df45e74fda401d5c644d957206b96b196f120', '1': '9735c6f072a93375b07cfdfbe89b51cb23e86f93f0acc92ec6ec2062349ad6ea', '2': 'b1178a243c1185f543478a54ba991816820b165f366ad8e2a6079ab257334270'})\n" + "Transactions hashes: (3, {'0': '0e32fcf92dc500c343714092df451296820bcd35d1158302729fe7d6b505a1ce', '1': 'dbcb03c474069ab994ad636be4732e35c1fefbbe206d571fb5126229b251f8e3', '2': 'a809e28394cd998808a21c71ce9e1df79c13a12b707134fe1df263bf07cc1d45'})\n" ] } ], @@ -2021,7 +2021,7 @@ }, { "cell_type": "code", - "execution_count": 163, + "execution_count": 124, "metadata": {}, "outputs": [ { diff --git a/multiversx_sdk/core/transactions_outcome_parsers/smart_contract_transactions_outcome_parser_types.py b/multiversx_sdk/core/transactions_outcome_parsers/smart_contract_transactions_outcome_parser_types.py index a47a581d..54ddf669 100644 --- a/multiversx_sdk/core/transactions_outcome_parsers/smart_contract_transactions_outcome_parser_types.py +++ b/multiversx_sdk/core/transactions_outcome_parsers/smart_contract_transactions_outcome_parser_types.py @@ -8,6 +8,9 @@ class DeployedSmartContract: owner_address: str code_hash: bytes + def __repr__(self) -> str: + return f"DeployedSmartContract(address={self.address}, owner_address={self.owner_address}, code_hash={self.code_hash.hex()})" + @dataclass class SmartContractDeployOutcome: