diff --git a/smartcontract-annotated.ipynb b/smartcontract-annotated.ipynb new file mode 100644 index 0000000000000000000000000000000000000000..6ab79212f06d626e2b7ba2b4bb7b3199c063ccf6 --- /dev/null +++ b/smartcontract-annotated.ipynb @@ -0,0 +1,330 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 76, + "id": "3825b37b", + "metadata": {}, + "outputs": [], + "source": [ + "#variables\n", + "\n", + "node_url = 'https://goerli.infura.io/v3/83e52d0ce6f642a0bd9e7c701b9c62a8' #node that connects us to the blockchain\n", + "w3 = Web3(Web3.HTTPProvider(node_url)) #use web3 library to connect to blockchain through node\n", + "account = '0x9B32D01A2436877494C4dc17eEC02F91389a5D94' #meta mask\n", + "private_key = '0x' + '3bf70049e1fd371ff99480f046d68b6dd383ca8672e6a9a74d2c55e91f9ecb48'" + ] + }, + { + "cell_type": "code", + "execution_count": 77, + "id": "d7cf9bd2", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Requirement already satisfied: web3 in c:\\users\\bradley bennett\\anaconda3\\lib\\site-packages (5.31.3)\n", + "Requirement already satisfied: requests<3.0.0,>=2.16.0 in c:\\users\\bradley bennett\\anaconda3\\lib\\site-packages (from web3) (2.28.1)\n", + "Requirement already satisfied: eth-account<0.6.0,>=0.5.9 in c:\\users\\bradley bennett\\anaconda3\\lib\\site-packages (from web3) (0.5.9)\n", + "Requirement already satisfied: eth-hash[pycryptodome]<1.0.0,>=0.2.0 in c:\\users\\bradley bennett\\anaconda3\\lib\\site-packages (from web3) (0.5.1)\n", + "Requirement already satisfied: lru-dict<2.0.0,>=1.1.6 in c:\\users\\bradley bennett\\anaconda3\\lib\\site-packages (from web3) (1.1.8)\n", + "Requirement already satisfied: eth-typing<3.0.0,>=2.0.0 in c:\\users\\bradley bennett\\anaconda3\\lib\\site-packages (from web3) (2.3.0)\n", + "Requirement already satisfied: protobuf==3.19.5 in c:\\users\\bradley bennett\\anaconda3\\lib\\site-packages (from web3) (3.19.5)\n", + "Requirement already satisfied: eth-utils<2.0.0,>=1.9.5 in c:\\users\\bradley bennett\\anaconda3\\lib\\site-packages (from web3) (1.9.5)\n", + "Requirement already satisfied: pywin32>=223 in c:\\users\\bradley bennett\\anaconda3\\lib\\site-packages (from web3) (302)\n", + "Requirement already satisfied: websockets<10,>=9.1 in c:\\users\\bradley bennett\\anaconda3\\lib\\site-packages (from web3) (9.1)\n", + "Requirement already satisfied: eth-rlp<0.3 in c:\\users\\bradley bennett\\anaconda3\\lib\\site-packages (from web3) (0.2.1)\n", + "Requirement already satisfied: ipfshttpclient==0.8.0a2 in c:\\users\\bradley bennett\\anaconda3\\lib\\site-packages (from web3) (0.8.0a2)\n", + "Requirement already satisfied: aiohttp<4,>=3.7.4.post0 in c:\\users\\bradley bennett\\anaconda3\\lib\\site-packages (from web3) (3.8.4)\n", + "Requirement already satisfied: hexbytes<1.0.0,>=0.1.0 in c:\\users\\bradley bennett\\anaconda3\\lib\\site-packages (from web3) (0.3.0)\n", + "Requirement already satisfied: jsonschema<5,>=3.2.0 in c:\\users\\bradley bennett\\anaconda3\\lib\\site-packages (from web3) (4.16.0)\n", + "Requirement already satisfied: eth-abi<3.0.0,>=2.2.0 in c:\\users\\bradley bennett\\anaconda3\\lib\\site-packages (from web3) (2.2.0)\n", + "Requirement already satisfied: multiaddr>=0.0.7 in c:\\users\\bradley bennett\\anaconda3\\lib\\site-packages (from ipfshttpclient==0.8.0a2->web3) (0.0.9)\n", + "Requirement already satisfied: charset-normalizer<4.0,>=2.0 in c:\\users\\bradley bennett\\anaconda3\\lib\\site-packages (from aiohttp<4,>=3.7.4.post0->web3) (2.0.4)\n", + "Requirement already satisfied: multidict<7.0,>=4.5 in c:\\users\\bradley bennett\\anaconda3\\lib\\site-packages (from aiohttp<4,>=3.7.4.post0->web3) (6.0.4)\n", + "Requirement already satisfied: yarl<2.0,>=1.0 in c:\\users\\bradley bennett\\anaconda3\\lib\\site-packages (from aiohttp<4,>=3.7.4.post0->web3) (1.8.2)\n", + "Requirement already satisfied: attrs>=17.3.0 in c:\\users\\bradley bennett\\anaconda3\\lib\\site-packages (from aiohttp<4,>=3.7.4.post0->web3) (21.4.0)\n", + "Requirement already satisfied: aiosignal>=1.1.2 in c:\\users\\bradley bennett\\anaconda3\\lib\\site-packages (from aiohttp<4,>=3.7.4.post0->web3) (1.3.1)\n", + "Requirement already satisfied: frozenlist>=1.1.1 in c:\\users\\bradley bennett\\anaconda3\\lib\\site-packages (from aiohttp<4,>=3.7.4.post0->web3) (1.3.3)\n", + "Requirement already satisfied: async-timeout<5.0,>=4.0.0a3 in c:\\users\\bradley bennett\\anaconda3\\lib\\site-packages (from aiohttp<4,>=3.7.4.post0->web3) (4.0.2)\n", + "Requirement already satisfied: parsimonious<0.9.0,>=0.8.0 in c:\\users\\bradley bennett\\anaconda3\\lib\\site-packages (from eth-abi<3.0.0,>=2.2.0->web3) (0.8.1)\n", + "Requirement already satisfied: bitarray<3,>=1.2.1 in c:\\users\\bradley bennett\\anaconda3\\lib\\site-packages (from eth-account<0.6.0,>=0.5.9->web3) (2.5.1)\n", + "Requirement already satisfied: eth-keys<0.4.0,>=0.3.4 in c:\\users\\bradley bennett\\anaconda3\\lib\\site-packages (from eth-account<0.6.0,>=0.5.9->web3) (0.3.4)\n", + "Requirement already satisfied: eth-keyfile<0.6.0,>=0.5.0 in c:\\users\\bradley bennett\\anaconda3\\lib\\site-packages (from eth-account<0.6.0,>=0.5.9->web3) (0.5.1)\n", + "Requirement already satisfied: rlp<3,>=1.0.0 in c:\\users\\bradley bennett\\anaconda3\\lib\\site-packages (from eth-account<0.6.0,>=0.5.9->web3) (2.0.1)\n", + "Requirement already satisfied: pycryptodome<4,>=3.6.6 in c:\\users\\bradley bennett\\anaconda3\\lib\\site-packages (from eth-hash[pycryptodome]<1.0.0,>=0.2.0->web3) (3.17)\n", + "Requirement already satisfied: cytoolz<1.0.0,>=0.10.1 in c:\\users\\bradley bennett\\anaconda3\\lib\\site-packages (from eth-utils<2.0.0,>=1.9.5->web3) (0.11.0)\n", + "Requirement already satisfied: pyrsistent!=0.17.0,!=0.17.1,!=0.17.2,>=0.14.0 in c:\\users\\bradley bennett\\anaconda3\\lib\\site-packages (from jsonschema<5,>=3.2.0->web3) (0.18.0)\n", + "Requirement already satisfied: idna<4,>=2.5 in c:\\users\\bradley bennett\\anaconda3\\lib\\site-packages (from requests<3.0.0,>=2.16.0->web3) (3.3)\n", + "Requirement already satisfied: certifi>=2017.4.17 in c:\\users\\bradley bennett\\anaconda3\\lib\\site-packages (from requests<3.0.0,>=2.16.0->web3) (2022.9.14)\n", + "Requirement already satisfied: urllib3<1.27,>=1.21.1 in c:\\users\\bradley bennett\\anaconda3\\lib\\site-packages (from requests<3.0.0,>=2.16.0->web3) (1.26.11)\n", + "Requirement already satisfied: toolz>=0.8.0 in c:\\users\\bradley bennett\\anaconda3\\lib\\site-packages (from cytoolz<1.0.0,>=0.10.1->eth-utils<2.0.0,>=1.9.5->web3) (0.11.2)\n", + "Requirement already satisfied: netaddr in c:\\users\\bradley bennett\\anaconda3\\lib\\site-packages (from multiaddr>=0.0.7->ipfshttpclient==0.8.0a2->web3) (0.8.0)\n", + "Requirement already satisfied: base58 in c:\\users\\bradley bennett\\anaconda3\\lib\\site-packages (from multiaddr>=0.0.7->ipfshttpclient==0.8.0a2->web3) (2.1.1)\n", + "Requirement already satisfied: varint in c:\\users\\bradley bennett\\anaconda3\\lib\\site-packages (from multiaddr>=0.0.7->ipfshttpclient==0.8.0a2->web3) (1.0.2)\n", + "Requirement already satisfied: six in c:\\users\\bradley bennett\\anaconda3\\lib\\site-packages (from multiaddr>=0.0.7->ipfshttpclient==0.8.0a2->web3) (1.16.0)\n", + "Requirement already satisfied: py-solc in c:\\users\\bradley bennett\\anaconda3\\lib\\site-packages (3.2.0)\n", + "Requirement already satisfied: semantic-version>=2.6.0 in c:\\users\\bradley bennett\\anaconda3\\lib\\site-packages (from py-solc) (2.10.0)\n", + "Requirement already satisfied: py-solc-x in c:\\users\\bradley bennett\\anaconda3\\lib\\site-packages (1.1.1)\n", + "Requirement already satisfied: requests<3,>=2.19.0 in c:\\users\\bradley bennett\\anaconda3\\lib\\site-packages (from py-solc-x) (2.28.1)\n", + "Requirement already satisfied: semantic-version<3,>=2.8.1 in c:\\users\\bradley bennett\\anaconda3\\lib\\site-packages (from py-solc-x) (2.10.0)\n", + "Requirement already satisfied: idna<4,>=2.5 in c:\\users\\bradley bennett\\anaconda3\\lib\\site-packages (from requests<3,>=2.19.0->py-solc-x) (3.3)\n", + "Requirement already satisfied: certifi>=2017.4.17 in c:\\users\\bradley bennett\\anaconda3\\lib\\site-packages (from requests<3,>=2.19.0->py-solc-x) (2022.9.14)\n", + "Requirement already satisfied: urllib3<1.27,>=1.21.1 in c:\\users\\bradley bennett\\anaconda3\\lib\\site-packages (from requests<3,>=2.19.0->py-solc-x) (1.26.11)\n", + "Requirement already satisfied: charset-normalizer<3,>=2 in c:\\users\\bradley bennett\\anaconda3\\lib\\site-packages (from requests<3,>=2.19.0->py-solc-x) (2.0.4)\n" + ] + } + ], + "source": [ + "#install the web3 module to iteract with node\n", + "!pip install web3\n", + "#install solidity to use as contract, solcx is python\n", + "!pip install py-solc\n", + "!pip install py-solc-x\n", + "\n", + "#import the python variant of solidity(Wrapper) - converts solididity into evm bytecode\n", + "import solc\n", + "import solcx\n", + "\n", + "from web3 import Web3\n", + "\n", + "from solcx import compile_source\n" + ] + }, + { + "cell_type": "code", + "execution_count": 78, + "id": "ed74136e", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "Version('0.8.12')" + ] + }, + "execution_count": 78, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "solcx.install_solc('0.8.12') #change the version of solidity to match contract" + ] + }, + { + "cell_type": "code", + "execution_count": 79, + "id": "48dee090", + "metadata": {}, + "outputs": [], + "source": [ + "#smart contract, compile source allows us to pass contract as a string\n", + "\n", + "item_smart_contract = compile_source(\n", + " '''\n", + "// SPDX-License-Identifier: MIT\n", + "\n", + "pragma solidity 0.8.12;\n", + "\n", + "contract HelloWorrld {\n", + "\n", + " string public message;\n", + "\n", + " constructor() {\n", + " message = \"Hello World\";\n", + " }\n", + "\n", + " function setMessage(string memory _message) public {\n", + " message = _message;\n", + "\n", + " }\n", + " function sayMessage() view public returns (string memory) {\n", + " return message;\n", + " }\n", + "\n", + "}\n", + " ''', output_values = ['abi', 'bin'])" + ] + }, + { + "cell_type": "code", + "execution_count": 80, + "id": "651f20c3", + "metadata": {}, + "outputs": [], + "source": [ + "contract_id, contract_interface = item_smart_contract.popitem() # pop item method to extract abi and bin from dictonary we created in last step\n", + "\n", + "bytecode = contract_id['bin'] #What is deployed on blockchain, language of EVM\n", + "abi = contract_interface['abi'] #abi is interface to interact with smart contract sort of like an API" + ] + }, + { + "cell_type": "code", + "execution_count": 81, + "id": "3d414b47", + "metadata": {}, + "outputs": [], + "source": [ + "compiled_contract = w3.eth.contract(abi = abi, bytecode = bytecode)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "945903eb", + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": 82, + "id": "fdb0b43f", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "2" + ] + }, + "execution_count": 82, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "goreli_chain = 5 #the chain number, ethereum would be 1\n", + "\n", + "wallet = '0x9B32D01A2436877494C4dc17eEC02F91389a5D94'\n", + "nonce = w3.eth.getTransactionCount(wallet) # Transaction number to ensure the transaction is not repeated\n" + ] + }, + { + "cell_type": "code", + "execution_count": 83, + "id": "ee8c71e4", + "metadata": {}, + "outputs": [], + "source": [ + "#Information about transaction\n", + "\n", + "transaction = compiled_contract.constructor().buildTransaction(\n", + " {\n", + " \"gasPrice\": w3.eth.gas_price, #current gas price\n", + " \"chainId\": goreli_chain, #chain number\n", + " \"from\": wallet, # wallet id\n", + " \"nonce\": nonce #transaction number\n", + " }\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": 84, + "id": "aa82bc49", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "SignedTransaction(rawTransaction=HexBytes('0xf907270285125e507bd28305beea8080b906d4608060405234801561001057600080fd5b506040518060400160405280600b81526020017f48656c6c6f20576f726c640000000000000000000000000000000000000000008152506000908051906020019061005c929190610062565b50610166565b82805461006e90610134565b90600052602060002090601f01602090048101928261009057600085556100d7565b82601f106100a957805160ff19168380011785556100d7565b828001600101855582156100d7579182015b828111156100d65782518255916020019190600101906100bb565b5b5090506100e491906100e8565b5090565b5b808211156101015760008160009055506001016100e9565b5090565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b6000600282049050600182168061014c57607f821691505b602082108114156101605761015f610105565b5b50919050565b61055f806101756000396000f3fe608060405234801561001057600080fd5b50600436106100415760003560e01c8063368b877214610046578063e21f37ce14610062578063fc4a028714610080575b600080fd5b610060600480360381019061005b91906103d5565b61009e565b005b61006a6100b8565b60405161007791906104a6565b60405180910390f35b610088610146565b60405161009591906104a6565b60405180910390f35b80600090805190602001906100b49291906101d8565b5050565b600080546100c5906104f7565b80601f01602080910402602001604051908101604052809291908181526020018280546100f1906104f7565b801561013e5780601f106101135761010080835404028352916020019161013e565b820191906000526020600020905b81548152906001019060200180831161012157829003601f168201915b505050505081565b606060008054610155906104f7565b80601f0160208091040260200160405190810160405280929190818152602001828054610181906104f7565b80156101ce5780601f106101a3576101008083540402835291602001916101ce565b820191906000526020600020905b8154815290600101906020018083116101b157829003601f168201915b5050505050905090565b8280546101e4906104f7565b90600052602060002090601f016020900481019282610206576000855561024d565b82601f1061021f57805160ff191683800117855561024d565b8280016001018555821561024d579182015b8281111561024c578251825591602001919060010190610231565b5b50905061025a919061025e565b5090565b5b8082111561027757600081600090555060010161025f565b5090565b6000604051905090565b600080fd5b600080fd5b600080fd5b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6102e282610299565b810181811067ffffffffffffffff82111715610301576103006102aa565b5b80604052505050565b600061031461027b565b905061032082826102d9565b919050565b600067ffffffffffffffff8211156103405761033f6102aa565b5b61034982610299565b9050602081019050919050565b82818337600083830152505050565b600061037861037384610325565b61030a565b90508281526020810184848401111561039457610393610294565b5b61039f848285610356565b509392505050565b600082601f8301126103bc576103bb61028f565b5b81356103cc848260208601610365565b91505092915050565b6000602082840312156103eb576103ea610285565b5b600082013567ffffffffffffffff8111156104095761040861028a565b5b610415848285016103a7565b91505092915050565b600081519050919050565b600082825260208201905092915050565b60005b8381101561045857808201518184015260208101905061043d565b83811115610467576000848401525b50505050565b60006104788261041e565b6104828185610429565b935061049281856020860161043a565b61049b81610299565b840191505092915050565b600060208201905081810360008301526104c0818461046d565b905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b6000600282049050600182168061050f57607f821691505b60208210811415610523576105226104c8565b5b5091905056fea2646970667358221220683318554249509aeea22f43e242f195d1f048ecc1e37b6f20aa3b5975050baa64736f6c634300080c00332da01689d36f690bc6297051ac2c25da314e50aa6cef3777e2810f14b835a83cebdea0612de18129b491d7030dc81c230e737e8df87734f800485ba185c8b6bfecff95'), hash=HexBytes('0x83781e794cbd9b73c0c248bc7a4b98dcec5892d60a55010ca3bcdc64870d77a6'), r=10194399988802386256625336259406871636682944471873349698168191618125137767390, s=43955410805645100925486867654928003367725255261307795708159024528247434837909, v=45)" + ] + }, + "execution_count": 84, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "#Signing Transaction to blockchain to verify it is our wallet that wants to send\n", + "signed_transaction = w3.eth.account.sign_transaction(transaction, private_key = private_key)\n", + "\n", + "signed_transaction" + ] + }, + { + "cell_type": "code", + "execution_count": 85, + "id": "dd89d078", + "metadata": {}, + "outputs": [], + "source": [ + "transaction_hash = w3.eth.send_raw_transaction(signed_transaction.rawTransaction) #deploying the contract" + ] + }, + { + "cell_type": "code", + "execution_count": 87, + "id": "78b3a399", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "AttributeDict({'blockHash': HexBytes('0xda20a02ea70d5f132a74cd3e38245350c05fc76d8e03241a2eec290ef1c5f989'),\n", + " 'blockNumber': 8618834,\n", + " 'contractAddress': '0xC6307A2a4179aDE29bcC7a1Fc3aDB9277a0dBEf2',\n", + " 'cumulativeGasUsed': 26514672,\n", + " 'effectiveGasPrice': 78891744210,\n", + " 'from': '0x9B32D01A2436877494C4dc17eEC02F91389a5D94',\n", + " 'gasUsed': 376554,\n", + " 'logs': [],\n", + " 'logsBloom': HexBytes('0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000'),\n", + " 'status': 1,\n", + " 'to': None,\n", + " 'transactionHash': HexBytes('0x83781e794cbd9b73c0c248bc7a4b98dcec5892d60a55010ca3bcdc64870d77a6'),\n", + " 'transactionIndex': 122,\n", + " 'type': '0x0'})" + ] + }, + "execution_count": 87, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "transaction_reciept = w3.eth.wait_for_transaction_receipt(transaction_hash) #hash as reciept - unique indentifer\n", + "\n", + "transaction_reciept" + ] + }, + { + "cell_type": "markdown", + "id": "1491f9e0", + "metadata": {}, + "source": [ + "This contract will work for deploying a smart contract to the etherem blockchain network. However, it does have its limitations: - Thee code will need to be put into a function that is called when conditions of the register product page is met as if they are not in the right specifications it may cause an error.\n", + "- As we will be hosting this on a website our private key will be exposed, the way that we will be able to combat this is to use our own node. In this node we can store our private key details as environment variables which will hide it.\n", + "- Our code may also be exposed\n", + "- The smart contract is good, however, we will have to create a new contract everytime the item is transfered, the only way around us doing this is to send ownership to the customers wallet but this would mean we would have to require them to have one which in turn might turn customers away as it adds friction to the process.\n", + "- When transfer of ownership is made we will have to pay everytime, could massively increase or costs and potentially make the solution unviable." + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.9.13" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +}