From 4e45a0a9a9cc6656a479f60a5da28f8b5d474a21 Mon Sep 17 00:00:00 2001 From: matteo-cristino Date: Tue, 15 Oct 2024 10:06:42 +0200 Subject: [PATCH 1/8] fix(http): improve uri parsing --- src/lua/zencode_http.lua | 39 +++++++++++++++++++++++++++------------ 1 file changed, 27 insertions(+), 12 deletions(-) diff --git a/src/lua/zencode_http.lua b/src/lua/zencode_http.lua index 5758280e8..fd06be0ae 100644 --- a/src/lua/zencode_http.lua +++ b/src/lua/zencode_http.lua @@ -19,6 +19,7 @@ --Last modified by Denis Roio --on Saturday, 27th November 2021 --]] + local _UNRESERVED = "A-Za-z0-9%-._~" local _GEN_DELIMS = ":/?#%[%]@" local _SUB_DELIMS = "!$&'()*+,;=" @@ -126,19 +127,33 @@ local function _is_valid_host (host) return nil end +function is_valid_uri(uri) + local parsed = {} + local uri_pattern = + "^(%a[%w+.-]*):" .. -- Scheme + "//([^/?#]*)" .. -- Authority + "([^?#]*)" .. -- Path + "%%?([^#]*)" .. -- Query + "#?(.*)" -- Fragment + parsed.scheme, parsed.authority, parsed.path, parsed.query, parsed.fragment = uri:str():match(uri_pattern) + if parsed.scheme == "" then + error("invalid uri, missing scheme in '" .. uri .. "'", 2) + end + if parsed.authority ~= "" then + local host_error = _is_valid_host(parsed.authority) + if host_error then + error(host_error, 2) + end + end + return parsed +end + When("create url from ''", function(src) - local obj = have(src) - local url = obj:str():lower() - empty'url' - local proto - if url:sub(1,7)=='http://' then proto = 'http://' end - if url:sub(1,8)=='https://' then proto = 'https://' end - zencode_assert(proto, "Invalid http prefix in url: "..obj:str()) - local toks = strtok(url, '/') -- second is the host - local res = _is_valid_host(toks[2]) - zencode_assert(not res, res) - ACK.url = obj - new_codec('url',{zentype='e',content='url', encoding='string'}) + local obj = have(src) + is_valid_uri(obj) + empty'url' + ACK.url = obj + new_codec('url',{zentype='e',content='url', encoding='string'}) end) local function _append_to_url(ele, dst, encoding_f) From f084af068159f4ae4628d15ffbd3f4f4b8db55af Mon Sep 17 00:00:00 2001 From: matteo-cristino Date: Tue, 15 Oct 2024 10:33:45 +0200 Subject: [PATCH 2/8] fix(http): allow to append also numbers as url query parameters --- src/lua/zencode_http.lua | 19 +++++++++------- test/zencode/http.bats | 47 +++++++++++++++++++++++++++++++++++----- 2 files changed, 52 insertions(+), 14 deletions(-) diff --git a/src/lua/zencode_http.lua b/src/lua/zencode_http.lua index fd06be0ae..9df0d90ef 100644 --- a/src/lua/zencode_http.lua +++ b/src/lua/zencode_http.lua @@ -159,13 +159,15 @@ end) local function _append_to_url(ele, dst, encoding_f) local arg, arg_c = have(ele) local url, url_c = have(dst) - zencode_assert(arg_c.encoding == 'string' and luatype(arg) ~= 'table', - "Cannot append http request that are not strings: "..ele) - zencode_assert(url_c.content == 'url', - "Cannot append http request to invalid url: "..dst) + if url_c.content ~= 'url' then + error("Cannot append http request to invalid url: "..dst, 2) + end + if luatype(arg) == 'table' then + error("Cannot append table to url: "..dst, 2) + end local separator = fif( url:str():find('?'), '&', '?' ) local tv = type(arg) - if tv == 'zenroom.time' or tv == 'zenroom.big' then + if tv == 'zenroom.time' or tv == 'zenroom.big' or tv == 'zenroom.float' then arg = tostring(arg) elseif tv == 'zenroom.octet' then arg = arg:str() @@ -193,13 +195,14 @@ local function _get_parameters_from_table(table_params, encoding_f) if(params_c.zentype ~= 'd') then error("Expected dictionary, found "..params_c.zentype.." for "..table_params, 2) end - if(params_c.encoding ~= 'string') then - error("Parameters in "..table_params.." must be strings", 2) + if( params_c.encoding ~= 'string' and params_c.encoding ~= 'float' and + params_c.encoding ~= 'integer' and params_c.encoding ~= 'time') then + error("Parameters in "..table_params.." must be of type 'string', 'float', 'integer' or 'time'", 2) end local res = "" for k,v in pairs(params) do local tv = type(v) - if tv == 'zenroom.time' or tv == 'zenroom.big' then + if tv == 'zenroom.time' or tv == 'zenroom.big' or tv == 'zenroom.float' then v = tostring(v) elseif tv == 'zenroom.octet' then v = v:str() diff --git a/test/zencode/http.bats b/test/zencode/http.bats index 0dbab14e0..dc9f61945 100644 --- a/test/zencode/http.bats +++ b/test/zencode/http.bats @@ -219,26 +219,28 @@ EOF assert_output '{"empty_get_parameters":"","get_parameters_with_percent_endoing":"client_id=did%3Adyne%3Asandbox.signroom%3APTDvvQn1iWQiVxkfsDnUid8FbieKbHq46Qs8c9CZx67&code=eyJhbGciOiJFUzI1NiJ9.eyJzdWIiOiJlYWMyMjNmOTMwYmRkNzk1NDdlNzI2ZGRjZTg5ZTlmYTA1NWExZTFjIiwiaWF0IjoxNzA5MDQ4MzkzMjk1LCJpc3MiOiJodHRwczovL3ZhbGlkLmlzc3Vlci51cmwiLCJhdWQiOiJkaWQ6ZHluZTpzYW5kYm94LmdlbmVyaWNpc3N1ZXI6NkNwOG1QVXZKbVFhTXhRUFNuTnloYjc0ZjlHYTRXcWZYQ2tCbmVGZ2lrbTUiLCJleHAiOjE3MDkwNTE5OTN9.TahF8CqDDj5yynvtvkhr-Gt6RjzHSvKMosOhFf5sVmWGohKBPMNFhI8WlBlWj7aRauXB0lsvbQk03lf4eZN-2g&redirectUris=https%3A%2F%2Fdidroom.com%2F&grant_type=authorization_code&code_verifier=JYTDgtxcjiNqa3AvJjfubMX6gx98-wCH7iTydBYAeFg","get_parameters_without_percent_endoing":"client_id=did:dyne:sandbox.signroom:PTDvvQn1iWQiVxkfsDnUid8FbieKbHq46Qs8c9CZx67&code=eyJhbGciOiJFUzI1NiJ9.eyJzdWIiOiJlYWMyMjNmOTMwYmRkNzk1NDdlNzI2ZGRjZTg5ZTlmYTA1NWExZTFjIiwiaWF0IjoxNzA5MDQ4MzkzMjk1LCJpc3MiOiJodHRwczovL3ZhbGlkLmlzc3Vlci51cmwiLCJhdWQiOiJkaWQ6ZHluZTpzYW5kYm94LmdlbmVyaWNpc3N1ZXI6NkNwOG1QVXZKbVFhTXhRUFNuTnloYjc0ZjlHYTRXcWZYQ2tCbmVGZ2lrbTUiLCJleHAiOjE3MDkwNTE5OTN9.TahF8CqDDj5yynvtvkhr-Gt6RjzHSvKMosOhFf5sVmWGohKBPMNFhI8WlBlWj7aRauXB0lsvbQk03lf4eZN-2g&redirectUris=https://didroom.com/&grant_type=authorization_code&code_verifier=JYTDgtxcjiNqa3AvJjfubMX6gx98-wCH7iTydBYAeFg"}' } -@test "create a GET parameters from a with big and time" { - cat < Date: Wed, 23 Oct 2024 17:31:47 +0200 Subject: [PATCH 3/8] fix(http): separate hostname and port before host checks --- src/lua/zencode_http.lua | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/lua/zencode_http.lua b/src/lua/zencode_http.lua index 9df0d90ef..6df98eca7 100644 --- a/src/lua/zencode_http.lua +++ b/src/lua/zencode_http.lua @@ -140,7 +140,12 @@ function is_valid_uri(uri) error("invalid uri, missing scheme in '" .. uri .. "'", 2) end if parsed.authority ~= "" then - local host_error = _is_valid_host(parsed.authority) + local authority_pattern = "^([^:]+):?(%d*)$" + parsed.hostname, parsed.port = parsed.authority:match(authority_pattern) + if parsed.port ~= "" and not tonumber(parsed.port) then + error("invalid port in '" .. parsed.authority .. "'", 2) + end + local host_error = _is_valid_host(parsed.hostname) if host_error then error(host_error, 2) end From 6a3accaa03f48f3e6fedf5b03515429043424cd7 Mon Sep 17 00:00:00 2001 From: matteo-cristino Date: Wed, 23 Oct 2024 17:32:20 +0200 Subject: [PATCH 4/8] test(http): parse url with port --- test/zencode/http.bats | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/test/zencode/http.bats b/test/zencode/http.bats index dc9f61945..2c8c91425 100644 --- a/test/zencode/http.bats +++ b/test/zencode/http.bats @@ -287,3 +287,22 @@ EOF save_output 'append_different_values.json' assert_output '{"another_url":"openid-credential-issuer://www.example.com?param1=value1¶m2=1000¶m3=2000¶m4=3000","url":"openid-credential-issuer://www.example.com?param1=value1¶m2=1000¶m3=2000¶m4=3000"}' } + +@test "url with port" { + cat < Date: Fri, 18 Oct 2024 14:11:35 +0000 Subject: [PATCH 5/8] Verify that SmartCondract realy deployed and work --- .../ethereum/doc_deploy_contract_erc721.py | 6 ++++-- docs/pages/zencode-scenarios-ethereum.md | 13 +++++++++---- 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/docs/examples/zencode_cookbook/ethereum/doc_deploy_contract_erc721.py b/docs/examples/zencode_cookbook/ethereum/doc_deploy_contract_erc721.py index ef5897851..0ab36f1b7 100644 --- a/docs/examples/zencode_cookbook/ethereum/doc_deploy_contract_erc721.py +++ b/docs/examples/zencode_cookbook/ethereum/doc_deploy_contract_erc721.py @@ -87,7 +87,7 @@ def get_private_key(password='My_pass', keystore_file='a.json'): "gasPrice": w3.eth.gas_price, "from": my_address, "nonce": nonce, - 'gas': 2000000, + 'gas': 8000000, } ) @@ -102,4 +102,6 @@ def get_private_key(password='My_pass', keystore_file='a.json'): tx_receipt = w3.eth.wait_for_transaction_receipt(tx_hash) print(f"Done! Contract deployed to {tx_receipt.contractAddress}") - +#Verification that code realy deployed (With OpenZeppilin 3.1.0 all work for ERC 1155) +my_code = w3.eth.get_code(tx_receipt.contractAddress) +print(f"Verify code after deployed (Must be NOT b\' \' or change gas value 8000000) {my_code}") diff --git a/docs/pages/zencode-scenarios-ethereum.md b/docs/pages/zencode-scenarios-ethereum.md index c82b539ff..6408e76f8 100644 --- a/docs/pages/zencode-scenarios-ethereum.md +++ b/docs/pages/zencode-scenarios-ethereum.md @@ -237,7 +237,6 @@ The output should look like: **NOTE**: in the end one can use the same scripts as above to create and verify the signature of the obtained *hash*. -# The script used to create the material in this page ## Create the smart contract for token ERC 721 by python @@ -260,9 +259,13 @@ To deploy a contract we use a script: You will also need an environment file .env GETH_RPC_URL=http://example.com:8545 -# The ID of Ethereum Network + +The ID of Ethereum Network + NETWORK_ID=1337 -# The password to create and access the primary account + +The password to create and access the primary account + ACCOUNT_PASSWORD=My_pass To deploy contract for ERC721 token, you can also use the sample [deploy.sh](https://github.com/dyne/Zenroom/blob/master/test/ethereum/deploy.sh) @@ -274,11 +277,13 @@ Also pay attention to the following examples: If you select the Ownable feature in the OpenZeppelin Contracts Wizard, then in the contract constructor you need to pass the token owner's address in string format. -# Submit the transaction that deploys the contract +Submit the transaction that deploys the contract transaction = Zen721.constructor(my_address).build_transaction(.... +# The script used to create the material in this page + All the smart contracts and the data you see in this page are generated by the scripts [ethereum.bats](https://github.com/dyne/Zenroom/blob/master/test/zencode/ethereum.bats) . If you want to run the scripts (on Linux) you should: - *git clone https://github.com/dyne/Zenroom.git* From 78b13bafdb53b5f9cc40870d0ba1da2960596ba3 Mon Sep 17 00:00:00 2001 From: ignat99 Date: Fri, 18 Oct 2024 15:07:53 +0000 Subject: [PATCH 6/8] Mint token from SmartCondract ERC 1155 --- .../doc_deploy_contract_erc1155_oz310.py | 107 ++++++++ .../ethereum/doc_deploy_contract_erc721.py | 9 +- .../ethereum/doc_mint_erc1155.py | 229 ++++++++++++++++++ .../zencode_cookbook/ethereum/zen1155.sol | 22 ++ 4 files changed, 363 insertions(+), 4 deletions(-) create mode 100644 docs/examples/zencode_cookbook/ethereum/doc_deploy_contract_erc1155_oz310.py create mode 100644 docs/examples/zencode_cookbook/ethereum/doc_mint_erc1155.py create mode 100644 docs/examples/zencode_cookbook/ethereum/zen1155.sol diff --git a/docs/examples/zencode_cookbook/ethereum/doc_deploy_contract_erc1155_oz310.py b/docs/examples/zencode_cookbook/ethereum/doc_deploy_contract_erc1155_oz310.py new file mode 100644 index 000000000..d0d1b7c68 --- /dev/null +++ b/docs/examples/zencode_cookbook/ethereum/doc_deploy_contract_erc1155_oz310.py @@ -0,0 +1,107 @@ +#!/usr/bin/env python + +from solcx import compile_standard, install_solc +import json +import os +from web3 import Web3 +import eth_keys +from eth_account import account +from dotenv import load_dotenv + +def get_private_key(password='My_pass', keystore_file='a.json'): + keyfile = open('./' + keystore_file) + keyfile_contents = keyfile.read() + keyfile.close() + private_key = eth_keys.keys.PrivateKey(account.Account.decrypt(keyfile_contents, password)) + private_key_str = str(private_key) + return private_key_str + + +load_dotenv() + +with open("./zen1155.sol", "r") as file: + simple_storage_file = file.read() + + install_solc("0.6.2") + + compiled_sol = compile_standard( + { + "language": "Solidity", + "sources": {"Inkan1155.sol": {"content": simple_storage_file}}, + "settings": { + "outputSelection": { + "*": {"*": ["abi", "metadata", "evm.bytecode", "evm.sourceMap"]} + } + }, + }, + solc_binary="/usr/local/lib/python3.9/site-packages/solcx/bin/solc-v0.6.2", + allow_paths="/root/3.1.0/" + ) + +with open("compiled_code.json", "w") as file: + json.dump(compiled_sol, file) + + +# get bytecode +bytecode = compiled_sol["contracts"]["Inkan1155.sol"]["Inkan1155"]["evm"]["bytecode"]["object"] + +# get abi +abi = json.loads(compiled_sol["contracts"]["Inkan1155.sol"]["Inkan1155"]["metadata"])["output"]["abi"] + +print(abi) + + + +# For connecting to geth_rpc +w3 = Web3(Web3.HTTPProvider(os.getenv("GETH_RPC_URL"))) + +#Check Connection +t=w3.is_connected() +print(f"Connected {t}") + +chain_id = int(os.getenv("NETWORK_ID")) +private_key = get_private_key() + +# Create a signer wallet +PA=w3.eth.account.from_key(private_key) + +# Get public address from a signer wallet +my_address = PA.address +print(f"Address {my_address}") +checksum_address = w3.to_checksum_address(my_address) + +#Print balance on current accaunt +BA=w3.eth.get_balance(my_address) +print(f"Balance {BA}") + +# Create the contract in Python +SimpleStorage = w3.eth.contract(abi=abi, bytecode=bytecode) + +# Get the latest transaction +nonce = w3.eth.get_transaction_count(my_address) + +# Submit the transaction that deploys the contract +transaction = SimpleStorage.constructor().build_transaction( + { + "chainId": chain_id, + "gasPrice": w3.eth.gas_price, + "from": my_address, + "nonce": nonce, + 'gas': 8000000, + } +) + +# Sign the transaction +signed_txn = w3.eth.account.sign_transaction(transaction, private_key=private_key) +print("Deploying Contract!") + +# Send it! +tx_hash = w3.eth.send_raw_transaction(signed_txn.rawTransaction) +# Wait for the transaction to be mined, and get the transaction receipt +print("Waiting for transaction to finish...") +tx_receipt = w3.eth.wait_for_transaction_receipt(tx_hash) +print(f"Done! Contract deployed to {tx_receipt.contractAddress}") + +#Verification that code realy deployed (With OpenZeppilin 3.1.0 all work for ERC 1155) +my_code = w3.eth.get_code(tx_receipt.contractAddress) +print(f"Verify code after deployed (Must be NOT b\' \' or change gas value to maximum 8000000) {my_code}") \ No newline at end of file diff --git a/docs/examples/zencode_cookbook/ethereum/doc_deploy_contract_erc721.py b/docs/examples/zencode_cookbook/ethereum/doc_deploy_contract_erc721.py index 0ab36f1b7..d4922df1b 100644 --- a/docs/examples/zencode_cookbook/ethereum/doc_deploy_contract_erc721.py +++ b/docs/examples/zencode_cookbook/ethereum/doc_deploy_contract_erc721.py @@ -22,7 +22,7 @@ def get_private_key(password='My_pass', keystore_file='a.json'): with open("./zen721.sol", "r") as file: simple_storage_file = file.read() - install_solc("0.8.20") + install_solc("0.6.2") compiled_sol = compile_standard( { @@ -34,7 +34,8 @@ def get_private_key(password='My_pass', keystore_file='a.json'): } }, }, -# solc_version="0.8.20", + solc_binary="/usr/local/lib/python3.9/site-packages/solcx/bin/solc-v0.6.2", + allow_paths="/root/3.1.0/" ) with open("compiled_code.json", "w") as file: @@ -102,6 +103,6 @@ def get_private_key(password='My_pass', keystore_file='a.json'): tx_receipt = w3.eth.wait_for_transaction_receipt(tx_hash) print(f"Done! Contract deployed to {tx_receipt.contractAddress}") -#Verification that code realy deployed (With OpenZeppilin 3.1.0 all work for ERC 1155) +#Verification that code realy deployed (With OpenZeppilin 3.1.0 all work for ERC 721) my_code = w3.eth.get_code(tx_receipt.contractAddress) -print(f"Verify code after deployed (Must be NOT b\' \' or change gas value 8000000) {my_code}") +print(f"Verify code after deployed (Must be NOT b\' \' or change gas value to maximum 8000000) {my_code}") diff --git a/docs/examples/zencode_cookbook/ethereum/doc_mint_erc1155.py b/docs/examples/zencode_cookbook/ethereum/doc_mint_erc1155.py new file mode 100644 index 000000000..690c1bcab --- /dev/null +++ b/docs/examples/zencode_cookbook/ethereum/doc_mint_erc1155.py @@ -0,0 +1,229 @@ +#!/usr/bin/env python + +from solcx import compile_standard, install_solc +import json +import os +from web3 import Web3 +import eth_keys +from eth_account import account +from dotenv import load_dotenv +from web3.middleware import geth_poa_middleware + + +def get_private_key(password='My_pass', keystore_file='a.json'): + keyfile = open('./' + keystore_file) + keyfile_contents = keyfile.read() + keyfile.close() + private_key = eth_keys.keys.PrivateKey(account.Account.decrypt(keyfile_contents, password)) + private_key_str = str(private_key) + return private_key_str + + +load_dotenv() + +with open("./zen1155.sol", "r") as file: + simple_storage_file = file.read() + + install_solc("0.6.2") + + compiled_sol = compile_standard( + { + "language": "Solidity", + "sources": {"Inkan1155.sol": {"content": simple_storage_file}}, + "settings": { + "outputSelection": { + "*": {"*": ["abi", "metadata", "evm.bytecode", "evm.sourceMap"]} + } + }, + }, + solc_binary="/usr/local/lib/python3.9/site-packages/solcx/bin/solc-v0.6.2", + allow_paths="/root/3.1.0/" + ) + +with open("compiled_code.json", "w") as file: + json.dump(compiled_sol, file) + + +# get bytecode +bytecode = compiled_sol["contracts"]["Inkan1155.sol"]["Inkan1155"]["evm"]["bytecode"]["object"] + +# get abi +abi = json.loads(compiled_sol["contracts"]["Inkan1155.sol"]["Inkan1155"]["metadata"])["output"]["abi"] + +print(abi) + + +# For connecting to geth_rpc +w3 = Web3(Web3.HTTPProvider(os.getenv("GETH_RPC_URL"))) + +#Check Connection +t=w3.is_connected() +print(f"Connected {t}") + + +chain_id = int(os.getenv("NETWORK_ID")) +private_key = get_private_key() + +# Create a signer wallet +PA=w3.eth.account.from_key(private_key) + +# Get public address from a signer wallet +my_address = PA.address +print(f"Account {my_address}") + +#Print balance on current accaunt +BA=w3.eth.get_balance(my_address) +print(f"Balance {BA}") + +# Create the contract in Python +SimpleStorage = w3.eth.contract(abi=abi, bytecode=bytecode) + +# Get the latest transaction +nonce = w3.eth.get_transaction_count(my_address) + +# Submit the transaction that deploys the contract +#transaction = SimpleStorage.constructor(my_address).build_transaction( +transaction = SimpleStorage.constructor().build_transaction( + { + "chainId": chain_id, + "gasPrice": w3.eth.gas_price, + "from": my_address, + "nonce": nonce, + 'gas': 2000000, + } +) + +# Address of SmartContract in SMART_CONTRACT +nft_contract = w3.eth.contract(address=os.getenv('SMART_CONTRACT'), abi=abi) +print(f"Contract {os.getenv('SMART_CONTRACT')}") + +nonce = w3.eth.get_transaction_count(my_address) +print(f"Nonce : {nonce}") + +dict_transaction = { + 'chainId': w3.eth.chain_id, + 'from': my_address, + 'gasPrice': w3.eth.gas_price, + 'nonce': nonce, +} + +number_of_nfts_to_mint = 1 +transaction = nft_contract.functions.mint( + my_address, + 1, + number_of_nfts_to_mint, + bytes('', 'utf-8') +).build_transaction(dict_transaction) + + +# Signed +signed_txn = w3.eth.account.sign_transaction(transaction, private_key) +print(f"Sig. transaction : {signed_txn}") + +# Mint +txn_hash = w3.eth.send_raw_transaction(signed_txn.rawTransaction) +print(f"Transaction {txn_hash.hex()}") + +tx_receipt = w3.eth.wait_for_transaction_receipt(txn_hash) +print(f"Receipt {tx_receipt}") + + + + +nonce = w3.eth.get_transaction_count(my_address) +print(f"Nonce : {nonce}") + +dict_transaction = { + 'chainId': w3.eth.chain_id, + 'from': my_address, + 'gasPrice': w3.eth.gas_price, + 'nonce': nonce, +} + +transaction = nft_contract.functions.mint( + my_address, + 2, + number_of_nfts_to_mint, + bytes('', 'utf-8') +).build_transaction(dict_transaction) + +signed_txn = w3.eth.account.sign_transaction(transaction, private_key) +#print(f"Sig. transaction : {signed_txn}") +txn_hash = w3.eth.send_raw_transaction(signed_txn.rawTransaction) +print(f"Transaction {txn_hash.hex()}") +tx_receipt = w3.eth.wait_for_transaction_receipt(txn_hash) +#print(f"Receipt {tx_receipt}") + + +print(nft_contract.all_functions()) + +i=1 +amount = nft_contract.functions.balanceOf(my_address, i).call() +print(f"Amount of token : {amount} with index : {i} ") + +transaction = nft_contract.functions.mint( + my_address, + 1, + number_of_nfts_to_mint, + bytes('', 'utf-8') +).call({'from' : my_address}) + + + +print(f"Mint one more token {transaction} without sign") + + +amount = nft_contract.functions.balanceOf(my_address, i).call() +print(f"Amount of token : {amount} with index : {i} ") + + +nonce = w3.eth.get_transaction_count(my_address) +print(f"Nonce : {nonce}") + + +dict_transaction = { + 'chainId': w3.eth.chain_id, + 'from': my_address, + 'gasPrice': w3.eth.gas_price, + 'nonce': nonce, +} + +number_of_nfts_to_mint = 1 +transaction = nft_contract.functions.mint( + my_address, + 1, + number_of_nfts_to_mint, + bytes('', 'utf-8') +).build_transaction(dict_transaction) + +#Personal not work (IMHO it depend from geth settings) +#e = w3.eth.personal +#e.unlock_account() +#nft_contract.functions.getOwner().call({'from': e.account}) +#nft_contract.functions.getOwner().transact({'from': e.account}) +print(f"Mint one more token {transaction} with sign") + + +# Sign +signed_txn = w3.eth.account.sign_transaction(transaction, private_key) +print(f"Sig. transaction : {signed_txn}") + +# Mint +txn_hash = w3.eth.send_raw_transaction(signed_txn.rawTransaction) +print(f"Transaction {txn_hash.hex()}") + +tx_receipt = w3.eth.wait_for_transaction_receipt(txn_hash) +print(f"Receipt {tx_receipt}") + +print(f"Mint one more token {transaction} with sign") + + + + +for i in range(5): + #i=1 + amount = nft_contract.functions.balanceOf(my_address, i).call() + print(f"Amount of token : {amount} with index : {i} ") + + + diff --git a/docs/examples/zencode_cookbook/ethereum/zen1155.sol b/docs/examples/zencode_cookbook/ethereum/zen1155.sol new file mode 100644 index 000000000..770a4742c --- /dev/null +++ b/docs/examples/zencode_cookbook/ethereum/zen1155.sol @@ -0,0 +1,22 @@ +// SPDX-License-Identifier: MIT +// Compatible with OpenZeppelin Contracts ^3.1.0 +pragma solidity ^0.6.0; + +import "./3.1.0/contracts/token/ERC1155/ERC1155.sol"; + +contract Zen1155 is ERC1155 { + + + constructor() public ERC1155("http://example.com:8080/api/tokens/") { + } + + + function mint(address account, uint256 id, uint256 amount, bytes memory data) + public +// onlyOwner + { + _mint(account, id, amount, data); + } + + +} From e3bb7bdf7356397529ee8076fd6f28f4abbd0f87 Mon Sep 17 00:00:00 2001 From: ignat99 Date: Fri, 18 Oct 2024 18:21:59 +0000 Subject: [PATCH 7/8] Mint token from SmartCondract ERC 1155 OZ 5.0.1 with evmVersion: paris --- .../doc_deploy_contract_erc1155_oz310.py | 6 +- .../doc_deploy_contract_erc1155_oz501.py | 108 ++++++++ .../ethereum/doc_mint_erc1155.py | 6 +- .../ethereum/doc_mint_erc1155_oz501.py | 230 ++++++++++++++++++ .../zencode_cookbook/ethereum/zen1155.sol | 2 +- .../ethereum/zen1155_oz501.sol | 22 ++ 6 files changed, 367 insertions(+), 7 deletions(-) create mode 100644 docs/examples/zencode_cookbook/ethereum/doc_deploy_contract_erc1155_oz501.py create mode 100644 docs/examples/zencode_cookbook/ethereum/doc_mint_erc1155_oz501.py create mode 100644 docs/examples/zencode_cookbook/ethereum/zen1155_oz501.sol diff --git a/docs/examples/zencode_cookbook/ethereum/doc_deploy_contract_erc1155_oz310.py b/docs/examples/zencode_cookbook/ethereum/doc_deploy_contract_erc1155_oz310.py index d0d1b7c68..7600b8f16 100644 --- a/docs/examples/zencode_cookbook/ethereum/doc_deploy_contract_erc1155_oz310.py +++ b/docs/examples/zencode_cookbook/ethereum/doc_deploy_contract_erc1155_oz310.py @@ -27,7 +27,7 @@ def get_private_key(password='My_pass', keystore_file='a.json'): compiled_sol = compile_standard( { "language": "Solidity", - "sources": {"Inkan1155.sol": {"content": simple_storage_file}}, + "sources": {"zen1155.sol": {"content": simple_storage_file}}, "settings": { "outputSelection": { "*": {"*": ["abi", "metadata", "evm.bytecode", "evm.sourceMap"]} @@ -43,10 +43,10 @@ def get_private_key(password='My_pass', keystore_file='a.json'): # get bytecode -bytecode = compiled_sol["contracts"]["Inkan1155.sol"]["Inkan1155"]["evm"]["bytecode"]["object"] +bytecode = compiled_sol["contracts"]["zen1155.sol"]["zen1155"]["evm"]["bytecode"]["object"] # get abi -abi = json.loads(compiled_sol["contracts"]["Inkan1155.sol"]["Inkan1155"]["metadata"])["output"]["abi"] +abi = json.loads(compiled_sol["contracts"]["zen1155.sol"]["zen1155"]["metadata"])["output"]["abi"] print(abi) diff --git a/docs/examples/zencode_cookbook/ethereum/doc_deploy_contract_erc1155_oz501.py b/docs/examples/zencode_cookbook/ethereum/doc_deploy_contract_erc1155_oz501.py new file mode 100644 index 000000000..a74d63c06 --- /dev/null +++ b/docs/examples/zencode_cookbook/ethereum/doc_deploy_contract_erc1155_oz501.py @@ -0,0 +1,108 @@ +#!/usr/bin/env python + +from solcx import compile_standard, install_solc +import json +import os +from web3 import Web3 +import eth_keys +from eth_account import account +from dotenv import load_dotenv + +def get_private_key(password='My_pass', keystore_file='a.json'): + keyfile = open('./' + keystore_file) + keyfile_contents = keyfile.read() + keyfile.close() + private_key = eth_keys.keys.PrivateKey(account.Account.decrypt(keyfile_contents, password)) + private_key_str = str(private_key) + return private_key_str + + +load_dotenv() + +with open("./zen1155_oz501.sol", "r") as file: + simple_storage_file = file.read() + + install_solc("0.8.20") + + compiled_sol = compile_standard( + { + "language": "Solidity", + "sources": {"zen1155_oz501.sol": {"content": simple_storage_file}}, + "settings": { + "outputSelection": { + "*": {"*": ["abi", "metadata", "evm.bytecode", "evm.sourceMap"]} + }, + "evmVersion": "paris" + }, + }, + solc_binary="/usr/local/lib/python3.9/site-packages/solcx/bin/solc-v0.8.20", + allow_paths="/root/5.0.1/" + ) + +with open("compiled_code.json", "w") as file: + json.dump(compiled_sol, file) + + +# get bytecode +bytecode = compiled_sol["contracts"]["zen1155_oz501.sol"]["zen1155"]["evm"]["bytecode"]["object"] + +# get abi +abi = json.loads(compiled_sol["contracts"]["zen1155_oz501.sol"]["zen1155"]["metadata"])["output"]["abi"] + +print(abi) + + + +# For connecting to geth_rpc +w3 = Web3(Web3.HTTPProvider(os.getenv("GETH_RPC_URL"))) + +#Check Connection +t=w3.is_connected() +print(f"Connected {t}") + +chain_id = int(os.getenv("NETWORK_ID")) +private_key = get_private_key() + +# Create a signer wallet +PA=w3.eth.account.from_key(private_key) + +# Get public address from a signer wallet +my_address = PA.address +print(f"Address {my_address}") +checksum_address = w3.to_checksum_address(my_address) + +#Print balance on current accaunt +BA=w3.eth.get_balance(my_address) +print(f"Balance {BA}") + +# Create the contract in Python +SimpleStorage = w3.eth.contract(abi=abi, bytecode=bytecode) + +# Get the latest transaction +nonce = w3.eth.get_transaction_count(my_address) + +# Submit the transaction that deploys the contract +transaction = SimpleStorage.constructor().build_transaction( + { + "chainId": chain_id, + "gasPrice": w3.eth.gas_price, + "from": my_address, + "nonce": nonce, + 'gas': 8000000, + } +) + +# Sign the transaction +signed_txn = w3.eth.account.sign_transaction(transaction, private_key=private_key) +print("Deploying Contract!") + +# Send it! +tx_hash = w3.eth.send_raw_transaction(signed_txn.rawTransaction) +# Wait for the transaction to be mined, and get the transaction receipt +print("Waiting for transaction to finish...") +tx_receipt = w3.eth.wait_for_transaction_receipt(tx_hash) +print(f"Done! Contract deployed to {tx_receipt.contractAddress}") + +#Verification that code realy deployed (With OpenZeppilin 3.1.0 all work for ERC 1155) +my_code = w3.eth.get_code(tx_receipt.contractAddress) +print(f"Verify code after deployed (Must be NOT b\' \' or change gas value to maximum 8000000) {my_code}") \ No newline at end of file diff --git a/docs/examples/zencode_cookbook/ethereum/doc_mint_erc1155.py b/docs/examples/zencode_cookbook/ethereum/doc_mint_erc1155.py index 690c1bcab..9c7576f4c 100644 --- a/docs/examples/zencode_cookbook/ethereum/doc_mint_erc1155.py +++ b/docs/examples/zencode_cookbook/ethereum/doc_mint_erc1155.py @@ -29,7 +29,7 @@ def get_private_key(password='My_pass', keystore_file='a.json'): compiled_sol = compile_standard( { "language": "Solidity", - "sources": {"Inkan1155.sol": {"content": simple_storage_file}}, + "sources": {"zen1155.sol": {"content": simple_storage_file}}, "settings": { "outputSelection": { "*": {"*": ["abi", "metadata", "evm.bytecode", "evm.sourceMap"]} @@ -45,10 +45,10 @@ def get_private_key(password='My_pass', keystore_file='a.json'): # get bytecode -bytecode = compiled_sol["contracts"]["Inkan1155.sol"]["Inkan1155"]["evm"]["bytecode"]["object"] +bytecode = compiled_sol["contracts"]["zen1155.sol"]["zen1155"]["evm"]["bytecode"]["object"] # get abi -abi = json.loads(compiled_sol["contracts"]["Inkan1155.sol"]["Inkan1155"]["metadata"])["output"]["abi"] +abi = json.loads(compiled_sol["contracts"]["zen1155.sol"]["zen1155"]["metadata"])["output"]["abi"] print(abi) diff --git a/docs/examples/zencode_cookbook/ethereum/doc_mint_erc1155_oz501.py b/docs/examples/zencode_cookbook/ethereum/doc_mint_erc1155_oz501.py new file mode 100644 index 000000000..e54b7c3ad --- /dev/null +++ b/docs/examples/zencode_cookbook/ethereum/doc_mint_erc1155_oz501.py @@ -0,0 +1,230 @@ +#!/usr/bin/env python + +from solcx import compile_standard, install_solc +import json +import os +from web3 import Web3 +import eth_keys +from eth_account import account +from dotenv import load_dotenv +from web3.middleware import geth_poa_middleware + + +def get_private_key(password='My_pass', keystore_file='a.json'): + keyfile = open('./' + keystore_file) + keyfile_contents = keyfile.read() + keyfile.close() + private_key = eth_keys.keys.PrivateKey(account.Account.decrypt(keyfile_contents, password)) + private_key_str = str(private_key) + return private_key_str + + +load_dotenv() + +with open("./zen1155_oz501.sol", "r") as file: + simple_storage_file = file.read() + + install_solc("0.8.20") + + compiled_sol = compile_standard( + { + "language": "Solidity", + "sources": {"zen1155_oz501.sol": {"content": simple_storage_file}}, + "settings": { + "outputSelection": { + "*": {"*": ["abi", "metadata", "evm.bytecode", "evm.sourceMap"]} + }, + "evmVersion": "paris" + }, + }, + solc_binary="/usr/local/lib/python3.9/site-packages/solcx/bin/solc-v0.8.20", + allow_paths="/root/5.0.1/" + ) + +with open("compiled_code.json", "w") as file: + json.dump(compiled_sol, file) + + +# get bytecode +bytecode = compiled_sol["contracts"]["zen1155_oz501.sol"]["zen1155"]["evm"]["bytecode"]["object"] + +# get abi +abi = json.loads(compiled_sol["contracts"]["zen1155_oz501.sol"]["zen1155"]["metadata"])["output"]["abi"] + +print(abi) + + +# For connecting to geth_rpc +w3 = Web3(Web3.HTTPProvider(os.getenv("GETH_RPC_URL"))) + +#Check Connection +t=w3.is_connected() +print(f"Connected {t}") + + +chain_id = int(os.getenv("NETWORK_ID")) +private_key = get_private_key() + +# Create a signer wallet +PA=w3.eth.account.from_key(private_key) + +# Get public address from a signer wallet +my_address = PA.address +print(f"Account {my_address}") + +#Print balance on current accaunt +BA=w3.eth.get_balance(my_address) +print(f"Balance {BA}") + +# Create the contract in Python +SimpleStorage = w3.eth.contract(abi=abi, bytecode=bytecode) + +# Get the latest transaction +nonce = w3.eth.get_transaction_count(my_address) + +# Submit the transaction that deploys the contract +#transaction = SimpleStorage.constructor(my_address).build_transaction( +transaction = SimpleStorage.constructor().build_transaction( + { + "chainId": chain_id, + "gasPrice": w3.eth.gas_price, + "from": my_address, + "nonce": nonce, + 'gas': 2000000, + } +) + +# Address of SmartContract in SMART_CONTRACT +nft_contract = w3.eth.contract(address=os.getenv('SMART_CONTRACT'), abi=abi) +print(f"Contract {os.getenv('SMART_CONTRACT')}") + +nonce = w3.eth.get_transaction_count(my_address) +print(f"Nonce : {nonce}") + +dict_transaction = { + 'chainId': w3.eth.chain_id, + 'from': my_address, + 'gasPrice': w3.eth.gas_price, + 'nonce': nonce, +} + +number_of_nfts_to_mint = 1 +transaction = nft_contract.functions.mint( + my_address, + 1, + number_of_nfts_to_mint, + bytes('', 'utf-8') +).build_transaction(dict_transaction) + + +# Signed +signed_txn = w3.eth.account.sign_transaction(transaction, private_key) +print(f"Sig. transaction : {signed_txn}") + +# Mint +txn_hash = w3.eth.send_raw_transaction(signed_txn.rawTransaction) +print(f"Transaction {txn_hash.hex()}") + +tx_receipt = w3.eth.wait_for_transaction_receipt(txn_hash) +print(f"Receipt {tx_receipt}") + + + + +nonce = w3.eth.get_transaction_count(my_address) +print(f"Nonce : {nonce}") + +dict_transaction = { + 'chainId': w3.eth.chain_id, + 'from': my_address, + 'gasPrice': w3.eth.gas_price, + 'nonce': nonce, +} + +transaction = nft_contract.functions.mint( + my_address, + 2, + number_of_nfts_to_mint, + bytes('', 'utf-8') +).build_transaction(dict_transaction) + +signed_txn = w3.eth.account.sign_transaction(transaction, private_key) +#print(f"Sig. transaction : {signed_txn}") +txn_hash = w3.eth.send_raw_transaction(signed_txn.rawTransaction) +print(f"Transaction {txn_hash.hex()}") +tx_receipt = w3.eth.wait_for_transaction_receipt(txn_hash) +#print(f"Receipt {tx_receipt}") + + +print(nft_contract.all_functions()) + +i=1 +amount = nft_contract.functions.balanceOf(my_address, i).call() +print(f"Amount of token : {amount} with index : {i} ") + +transaction = nft_contract.functions.mint( + my_address, + 1, + number_of_nfts_to_mint, + bytes('', 'utf-8') +).call({'from' : my_address}) + + + +print(f"Mint one more token {transaction} without sign") + + +amount = nft_contract.functions.balanceOf(my_address, i).call() +print(f"Amount of token : {amount} with index : {i} ") + + +nonce = w3.eth.get_transaction_count(my_address) +print(f"Nonce : {nonce}") + + +dict_transaction = { + 'chainId': w3.eth.chain_id, + 'from': my_address, + 'gasPrice': w3.eth.gas_price, + 'nonce': nonce, +} + +number_of_nfts_to_mint = 1 +transaction = nft_contract.functions.mint( + my_address, + 1, + number_of_nfts_to_mint, + bytes('', 'utf-8') +).build_transaction(dict_transaction) + +#Personal not work (IMHO it depend from geth settings) +#e = w3.eth.personal +#e.unlock_account() +#nft_contract.functions.getOwner().call({'from': e.account}) +#nft_contract.functions.getOwner().transact({'from': e.account}) +print(f"Mint one more token {transaction} with sign") + + +# Sign +signed_txn = w3.eth.account.sign_transaction(transaction, private_key) +print(f"Sig. transaction : {signed_txn}") + +# Mint +txn_hash = w3.eth.send_raw_transaction(signed_txn.rawTransaction) +print(f"Transaction {txn_hash.hex()}") + +tx_receipt = w3.eth.wait_for_transaction_receipt(txn_hash) +print(f"Receipt {tx_receipt}") + +print(f"Mint one more token {transaction} with sign") + + + + +for i in range(5): + #i=1 + amount = nft_contract.functions.balanceOf(my_address, i).call() + print(f"Amount of token : {amount} with index : {i} ") + + + diff --git a/docs/examples/zencode_cookbook/ethereum/zen1155.sol b/docs/examples/zencode_cookbook/ethereum/zen1155.sol index 770a4742c..0d696b649 100644 --- a/docs/examples/zencode_cookbook/ethereum/zen1155.sol +++ b/docs/examples/zencode_cookbook/ethereum/zen1155.sol @@ -4,7 +4,7 @@ pragma solidity ^0.6.0; import "./3.1.0/contracts/token/ERC1155/ERC1155.sol"; -contract Zen1155 is ERC1155 { +contract zen1155 is ERC1155 { constructor() public ERC1155("http://example.com:8080/api/tokens/") { diff --git a/docs/examples/zencode_cookbook/ethereum/zen1155_oz501.sol b/docs/examples/zencode_cookbook/ethereum/zen1155_oz501.sol new file mode 100644 index 000000000..6fcddd8d6 --- /dev/null +++ b/docs/examples/zencode_cookbook/ethereum/zen1155_oz501.sol @@ -0,0 +1,22 @@ +// SPDX-License-Identifier: MIT +// Compatible with OpenZeppelin Contracts ^5.0.0 +pragma solidity ^0.8.0; + +import "./5.0.1/contracts/token/ERC1155/ERC1155.sol"; + +contract zen1155 is ERC1155 { + + + constructor() public ERC1155("http://example.com:8080/api/tokens/") { + } + + + function mint(address account, uint256 id, uint256 amount, bytes memory data) + public +// onlyOwner + { + _mint(account, id, amount, data); + } + + +} From 30e6c1d50683394cef695f3219e03379f545ad10 Mon Sep 17 00:00:00 2001 From: ignat99 Date: Fri, 18 Oct 2024 18:45:19 +0000 Subject: [PATCH 8/8] May be better without gas --- .../ethereum/doc_deploy_contract_erc1155_oz310.py | 2 +- .../ethereum/doc_deploy_contract_erc1155_oz501.py | 2 +- .../zencode_cookbook/ethereum/doc_deploy_contract_erc721.py | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/examples/zencode_cookbook/ethereum/doc_deploy_contract_erc1155_oz310.py b/docs/examples/zencode_cookbook/ethereum/doc_deploy_contract_erc1155_oz310.py index 7600b8f16..790e391aa 100644 --- a/docs/examples/zencode_cookbook/ethereum/doc_deploy_contract_erc1155_oz310.py +++ b/docs/examples/zencode_cookbook/ethereum/doc_deploy_contract_erc1155_oz310.py @@ -87,7 +87,7 @@ def get_private_key(password='My_pass', keystore_file='a.json'): "gasPrice": w3.eth.gas_price, "from": my_address, "nonce": nonce, - 'gas': 8000000, +# 'gas': 8000000, } ) diff --git a/docs/examples/zencode_cookbook/ethereum/doc_deploy_contract_erc1155_oz501.py b/docs/examples/zencode_cookbook/ethereum/doc_deploy_contract_erc1155_oz501.py index a74d63c06..d2e4d25f8 100644 --- a/docs/examples/zencode_cookbook/ethereum/doc_deploy_contract_erc1155_oz501.py +++ b/docs/examples/zencode_cookbook/ethereum/doc_deploy_contract_erc1155_oz501.py @@ -88,7 +88,7 @@ def get_private_key(password='My_pass', keystore_file='a.json'): "gasPrice": w3.eth.gas_price, "from": my_address, "nonce": nonce, - 'gas': 8000000, +# 'gas': 8000000, } ) diff --git a/docs/examples/zencode_cookbook/ethereum/doc_deploy_contract_erc721.py b/docs/examples/zencode_cookbook/ethereum/doc_deploy_contract_erc721.py index d4922df1b..c28aaffb6 100644 --- a/docs/examples/zencode_cookbook/ethereum/doc_deploy_contract_erc721.py +++ b/docs/examples/zencode_cookbook/ethereum/doc_deploy_contract_erc721.py @@ -88,7 +88,7 @@ def get_private_key(password='My_pass', keystore_file='a.json'): "gasPrice": w3.eth.gas_price, "from": my_address, "nonce": nonce, - 'gas': 8000000, +# 'gas': 8000000, } )