What we plan on accomplishing:
In part one, we created all of the accounts we needed and established an API connection to our infura project. Now we are going to deploy our vyper smart contract, read some values, and execute some transactions. There are two ways to install the latest version of vyper, docker and pip, follow their instructions (I used pip in a venv). Once installed, we can issue vyper commands: vyper --version 0.2.12+commit.2c6842c I will be using the company stock example, we can copy and paste that into a file, company_stock.vy and execute the `vyper file.vy` for the byte code, and with the tag `-f abi` which will display the ABI. Both the Bytecode and ABI are needed for deploying the smart contract, verifying the code, and most importantly, connecting to the smart contract to execute commands. If you are copying the Bytecode or ABI below, take precaution, they are very long, copy carefully, copy fully. If you are having issues, there are also online compilers. vyper company_stock.vy 0x60606105e86101403960206105e860c03960c05160a01c1561002057600080fd5b6000610160511161003057600080fd5b6000610180511161004057600080fd5b61014051600055610160516001556101805160025561016051600360005460e05260c052604060c020556105d056600436101561000d576104b6565b600035601c52600051631d1dc1f08114156100ef5734600254808061003157600080fd5b820490509050610140526101405161014051600658016104bc565b610160526101405261016051101561006357600080fd5b600360005460e05260c052604060c0208054610140518082101561008657600080fd5b8082039050905081555060033360e05260c052604060c0208054610140518181830110156100b357600080fd5b808201905090508155506101405161016052337fe3d4187f6ca4248660cc0ac8b8056515bac4a8132be2eca31d6d0cc170722a7e6020610160a2005b34156100fa57600080fd5b633ce828de81141561012057600658016104bc565b610140526101405160005260206000f35b63eeb466348114156101615760043560a01c1561013c57600080fd5b6004356101405261014051600658016104dd565b6101a0526101a05160005260206000f35b63961be391811415610177574760005260206000f35b639104c81e8114156102a65760006004351161019257600080fd5b600435336101405261014051600658016104dd565b6101a0526101a05110156101ba57600080fd5b60043560025480820282158284830414176101d457600080fd5b809050905090504710156101e757600080fd5b60033360e05260c052604060c02080546004358082101561020757600080fd5b80820390509050815550600360005460e05260c052604060c020805460043581818301101561023557600080fd5b808201905090508155506000600060006000600435600254808202821582848304141761026157600080fd5b80905090509050336000f161027557600080fd5b60043561014052337f5e5e995ce3133561afceaa51a9a154d5db228cd7525d34df5185582c18d3df096020610140a2005b637f59e5348114156103855760043560a01c156102c257600080fd5b6000602435116102d157600080fd5b602435336101405261014051600658016104dd565b6101a0526101a05110156102f957600080fd5b60033360e05260c052604060c02080546024358082101561031957600080fd5b80820390509050815550600360043560e05260c052604060c020805460243581818301101561034757600080fd5b8082019050905081555060243561014052600435337fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef6020610140a3005b632293448781141561040b5760043560a01c156103a157600080fd5b60005433146103af57600080fd5b6024354710156103be57600080fd5b60006000600060006024356004356000f16103d857600080fd5b602435610140526004357f357b676c439b9e49b4410f8eb8680bee4223724802d8e3fd422e1756f87b475f6020610140a2005b630dca59c18114156104315760065801610503565b610140526101405160005260206000f35b63ad11c13181141561046c574760065801610503565b61014052610140518082101561045c57600080fd5b8082039050905060005260206000f35b636904c94d8114156104845760005460005260206000f35b633a98ef3981141561049c5760015460005260206000f35b63a035b1fe8114156104b45760025460005260206000f35b505b60006000fd5b61014052600360005460e05260c052604060c0205460005260005161014051565b610160526101405260036101405160e05260c052604060c0205460005260005161016051565b6101405260015461014051600658016104bc565b6101605261014052610160518082101561053057600080fd5b80820390509050600254808202821582848304141761054e57600080fd5b8090509050905060005260005161014051565b61006f6105d00361006f60003961006f6105d0036000f3 vyper -f abi company_stock.vy [{"name": "Transfer", "inputs": [{"name": "sender", "type": "address", "indexed": true}, {"name": "receiver", "type": "address", "indexed": true}, {"name": "value", "type": "uint256", "indexed": false}], "anonymous": false, "type": "event"}, {"name": "Buy", "inputs": [{"name": "buyer", "type": "address", "indexed": true}, {"name": "buy_order", "type": "uint256", "indexed": false}], "anonymous": false, "type": "event"}, {"name": "Sell", "inputs": [{"name": "seller", "type": "address", "indexed": true}, {"name": "sell_order", "type": "uint256", "indexed": false}], "anonymous": false, "type": "event"}, {"name": "Pay", "inputs": [{"name": "vendor", "type": "address", "indexed": true}, {"name": "amount", "type": "uint256", "indexed": false}], "anonymous": false, "type": "event"}, {"stateMutability": "nonpayable", "type": "constructor", "inputs": [{"name": "_company", "type": "address"}, {"name": "_total_shares", "type": "uint256"}, {"name": "initial_price", "type": "uint256"}], "outputs": []}, {"stateMutability": "view", "type": "function", "name": "stockAvailable", "inputs": [], "outputs": [{"name": "", "type": "uint256"}], "gas": 4952}, {"stateMutability": "payable", "type": "function", "name": "buyStock", "inputs": [], "outputs": [], "gas": 85886}, {"stateMutability": "view", "type": "function", "name": "getHolding", "inputs": [{"name": "_stockholder", "type": "address"}], "outputs": [{"name": "", "type": "uint256"}], "gas": 3171}, {"stateMutability": "view", "type": "function", "name": "cash", "inputs": [], "outputs": [{"name": "", "type": "uint256"}], "gas": 380}, {"stateMutability": "nonpayable", "type": "function", "name": "sellStock", "inputs": [{"name": "sell_order", "type": "uint256"}], "outputs": [], "gas": 122880}, {"stateMutability": "nonpayable", "type": "function", "name": "transferStock", "inputs": [{"name": "receiver", "type": "address"}, {"name": "transfer_order", "type": "uint256"}], "outputs": [], "gas": 80332}, {"stateMutability": "nonpayable", "type": "function", "name": "payBill", "inputs": [{"name": "vendor", "type": "address"}, {"name": "amount", "type": "uint256"}], "outputs": [], "gas": 40765}, {"stateMutability": "view", "type": "function", "name": "debt", "inputs": [], "outputs": [{"name": "", "type": "uint256"}], "gas": 14965}, {"stateMutability": "view", "type": "function", "name": "worth", "inputs": [], "outputs": [{"name": "", "type": "uint256"}], "gas": 15164}, {"stateMutability": "view", "type": "function", "name": "company", "inputs": [], "outputs": [{"name": "", "type": "address"}], "gas": 2658}, {"stateMutability": "view", "type": "function", "name": "totalShares", "inputs": [], "outputs": [{"name": "", "type": "uint256"}], "gas": 2688}, {"stateMutability": "view", "type": "function", "name": "price", "inputs": [], "outputs": [{"name": "", "type": "uint256"}], "gas": 2718}] There are various test networks, Ropsten, Rinkeby, Gorli, and many, many more. As mentioned in Part 1, we will be using Ropsten, but you can compare some of the common ones below, their block time, faucets, proof of work/authority, etc. If you are interested in another network not listed below, there are a ton of different networks many of which can be explored here. Now let's talk about some history and provide some insight into where Etherium Classic (ETC) came from and where it is going Etherium (ETH). There was a hard fork in the Etherium Classic code (ETC), which by the way, has a market cap of $15 Billion compared to Etherium (ETH) which has a $411 Billion market cap as of May 2021. "Another difference between the two is that the Etherium chain will soon update from aproof-of-work (PoW) consensus mechanism to adopt proof-of-stake (PoS) algorithm, in an upgrade known as Ethereum 2.0. This should mean that the Ethereum network will be faster, more efficient and will be able to significantly scale transactions. As the fork meant that the new blockchain isn’t backwards compatible, many in the Ethereum Classic camp are waiting to see if they will also follow in the same direction (source)." So while you do dev work, it is important to check which chain you are working on, ETH vs ETC, PoW vs PoA vs PoS, block times, what is supported, and any other specifics for your needs. I've included these 5 tabs below to show you some comparison between the different chains.
<
>
TL;DR....
For those who are not comfortable with deploying the contract in code, or run into issues, you can deploy the contract in MEW. You'll need the Byte Code, ABI, and Contract Name.
Once you enter the information, you can sign and verify the contract. If you take a look at the vyper code, you'll see the various functions, such as `getHolding` or`TransferStock` shown below. Let's take a look at the code for these two functions and then how to create the code to call them. Parts of the Contract
# Find out how much stock any address (that's owned by someone) has. @view @internal def _getHolding(_stockholder: address) -> uint256: return self.holdings[_stockholder] # Public function to allow external access to _getHolding @view @external def getHolding(_stockholder: address) -> uint256: return self._getHolding(_stockholder) # Transfer stock from one stockholder to another. (Assume that the # receiver is given some compensation, but this is not enforced.) @external def transferStock(receiver: address, transfer_order: uint256): assert transfer_order > 0 # This is similar to sellStock above. # Similarly, you can only trade as much stock as you own. assert self._getHolding(msg.sender) >= transfer_order # Debit the sender's stock and add to the receiver's address. self.holdings[msg.sender] -= transfer_order self.holdings[receiver] += transfer_order # Log the transfer event. log Transfer(msg.sender, receiver, transfer_order) Initializing the Code
To begin coding, we will need to initialize our environment. First, we'll connect to the infura project that we created in Part 1. Web3 should return a `True` value. Next, we'll make sure our ABI, Bytecode, and contract address are available, create a sender and a receiver account. And finally we'll initialize our contract_instance. This contract instance will then be able to issue the various functions/standards from ERC20 and ERC721.
ERC20 defines the functions balanceOf , totalSupply , transfer , transferFrom , approve , and allowance. The ERC-721 standard defines many of the same functions from ERC20 and the following functions: name, symbol, ownerOf, takeOwnership, tokenOfOwnerByIndex, and tokenMetadata. It also defines two events: Transfer and Approval. A more in-depth look into the various functions can be found here. So, below is fairly self-explanatory, we are going to start with some imports, connect to our project, verify that is it connected and set some variables like the abi, and bytecode. from web3 import Web3 import json import os import pickle import time # Connect to the Infura project your_infura_project_id = "93fd067aa3d34ba1bb7b1110ca535409" infura_url = f"https://ropsten.infura.io/v3/{your_infura_project_id}" w3 = Web3(Web3.HTTPProvider(infura_url)) print(f"Web3 is connected?: {w3.isConnected()}") # vyper -f abi company_stock.vy ABI = '[{"name": "Transfer", "inputs": [{"name": "sender", "type": "address", "indexed": true}, {"name": "receiver", "type": "address", "indexed": true}, {"name": "value", "type": "uint256", "indexed": false}], "anonymous": false, "type": "event"}, {"name": "Buy", "inputs": [{"name": "buyer", "type": "address", "indexed": true}, {"name": "buy_order", "type": "uint256", "indexed": false}], "anonymous": false, "type": "event"}, {"name": "Sell", "inputs": [{"name": "seller", "type": "address", "indexed": true}, {"name": "sell_order", "type": "uint256", "indexed": false}], "anonymous": false, "type": "event"}, {"name": "Pay", "inputs": [{"name": "vendor", "type": "address", "indexed": true}, {"name": "amount", "type": "uint256", "indexed": false}], "anonymous": false, "type": "event"}, {"stateMutability": "nonpayable", "type": "constructor", "inputs": [{"name": "_company", "type": "address"}, {"name": "_total_shares", "type": "uint256"}, {"name": "initial_price", "type": "uint256"}], "outputs": []}, {"stateMutability": "view", "type": "function", "name": "stockAvailable", "inputs": [], "outputs": [{"name": "", "type": "uint256"}], "gas": 4952}, {"stateMutability": "payable", "type": "function", "name": "buyStock", "inputs": [], "outputs": [], "gas": 85886}, {"stateMutability": "view", "type": "function", "name": "getHolding", "inputs": [{"name": "_stockholder", "type": "address"}], "outputs": [{"name": "", "type": "uint256"}], "gas": 3171}, {"stateMutability": "view", "type": "function", "name": "cash", "inputs": [], "outputs": [{"name": "", "type": "uint256"}], "gas": 380}, {"stateMutability": "nonpayable", "type": "function", "name": "sellStock", "inputs": [{"name": "sell_order", "type": "uint256"}], "outputs": [], "gas": 122880}, {"stateMutability": "nonpayable", "type": "function", "name": "transferStock", "inputs": [{"name": "receiver", "type": "address"}, {"name": "transfer_order", "type": "uint256"}], "outputs": [], "gas": 80332}, {"stateMutability": "nonpayable", "type": "function", "name": "payBill", "inputs": [{"name": "vendor", "type": "address"}, {"name": "amount", "type": "uint256"}], "outputs": [], "gas": 40765}, {"stateMutability": "view", "type": "function", "name": "debt", "inputs": [], "outputs": [{"name": "", "type": "uint256"}], "gas": 14965}, {"stateMutability": "view", "type": "function", "name": "worth", "inputs": [], "outputs": [{"name": "", "type": "uint256"}], "gas": 15164}, {"stateMutability": "view", "type": "function", "name": "company", "inputs": [], "outputs": [{"name": "", "type": "address"}], "gas": 2658}, {"stateMutability": "view", "type": "function", "name": "totalShares", "inputs": [], "outputs": [{"name": "", "type": "uint256"}], "gas": 2688}, {"stateMutability": "view", "type": "function", "name": "price", "inputs": [], "outputs": [{"name": "", "type": "uint256"}], "gas": 2718}]' abi = json.loads(ABI) # vyper -f bytecode company_stock.vy BYTECODE = '0x60606105e86101403960206105e860c03960c05160a01c1561002057600080fd5b6000610160511161003057600080fd5b6000610180511161004057600080fd5b61014051600055610160516001556101805160025561016051600360005460e05260c052604060c020556105d056600436101561000d576104b6565b600035601c52600051631d1dc1f08114156100ef5734600254808061003157600080fd5b820490509050610140526101405161014051600658016104bc565b610160526101405261016051101561006357600080fd5b600360005460e05260c052604060c0208054610140518082101561008657600080fd5b8082039050905081555060033360e05260c052604060c0208054610140518181830110156100b357600080fd5b808201905090508155506101405161016052337fe3d4187f6ca4248660cc0ac8b8056515bac4a8132be2eca31d6d0cc170722a7e6020610160a2005b34156100fa57600080fd5b633ce828de81141561012057600658016104bc565b610140526101405160005260206000f35b63eeb466348114156101615760043560a01c1561013c57600080fd5b6004356101405261014051600658016104dd565b6101a0526101a05160005260206000f35b63961be391811415610177574760005260206000f35b639104c81e8114156102a65760006004351161019257600080fd5b600435336101405261014051600658016104dd565b6101a0526101a05110156101ba57600080fd5b60043560025480820282158284830414176101d457600080fd5b809050905090504710156101e757600080fd5b60033360e05260c052604060c02080546004358082101561020757600080fd5b80820390509050815550600360005460e05260c052604060c020805460043581818301101561023557600080fd5b808201905090508155506000600060006000600435600254808202821582848304141761026157600080fd5b80905090509050336000f161027557600080fd5b60043561014052337f5e5e995ce3133561afceaa51a9a154d5db228cd7525d34df5185582c18d3df096020610140a2005b637f59e5348114156103855760043560a01c156102c257600080fd5b6000602435116102d157600080fd5b602435336101405261014051600658016104dd565b6101a0526101a05110156102f957600080fd5b60033360e05260c052604060c02080546024358082101561031957600080fd5b80820390509050815550600360043560e05260c052604060c020805460243581818301101561034757600080fd5b8082019050905081555060243561014052600435337fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef6020610140a3005b632293448781141561040b5760043560a01c156103a157600080fd5b60005433146103af57600080fd5b6024354710156103be57600080fd5b60006000600060006024356004356000f16103d857600080fd5b602435610140526004357f357b676c439b9e49b4410f8eb8680bee4223724802d8e3fd422e1756f87b475f6020610140a2005b630dca59c18114156104315760065801610503565b610140526101405160005260206000f35b63ad11c13181141561046c574760065801610503565b61014052610140518082101561045c57600080fd5b8082039050905060005260206000f35b636904c94d8114156104845760005460005260206000f35b633a98ef3981141561049c5760015460005260206000f35b63a035b1fe8114156104b45760025460005260206000f35b505b60006000fd5b61014052600360005460e05260c052604060c0205460005260005161014051565b610160526101405260036101405160e05260c052604060c0205460005260005161016051565b6101405260015461014051600658016104bc565b6101605261014052610160518082101561053057600080fd5b80820390509050600254808202821582848304141761054e57600080fd5b8090509050905060005260005161014051565b61006f6105d00361006f60003961006f6105d0036000f3' Next, because we will probably run this a few times, I'm going to create our accounts fresh, pickle them and save them to a file. If we have to re-run our code, this will load those files so we don't have to keep on creating accounts and modifying account numbers, etc. Also, to avoid spamming our faucet, we can only get a drip, once per 24 hrs, after that you'll be graylisted. We will load our one ropsten to our sender account, which will end up being our contract creator. print("Checking for saved receiver account") if os.path.exists("receiver_account.p"): file = open("receiver_account.p", 'rb') receiver_account = pickle.load(file) file.close() else: print("Couldn't find saved receiver account, creating a new one.") receiver_account = w3.eth.account.create("receiver_account") file = open("receiver_account.p", 'wb') pickle.dump(receiver_account, file) file.close() print("Checking for saved sender account") if os.path.exists("sender_account.p"): file = open("sender_account.p", 'rb') sender_account = pickle.load(file) file.close() else: print("Couldn't find saved sender account, creating a new one.") sender_account = w3.eth.account.create("sender_account") file = open("sender_account.p", 'wb') pickle.dump(sender_account, file) file.close() print("Getting ropsten token, you can do this only once per day.") os.system(f"wget https://faucet.ropsten.be/donate/{sender_account.address}") Now that we have our account info set and our ropsten token, we can build our contract and deploy it. Once it is deployed, depending on how much gas was used, it might take a few minutes to a few hours. I've set a delay of 4 minutes, but you should really check that it is deployed before you try to transfer anything. In the contract, I've set 100,000 shares, each valued at $1. It is very possible that the current gas and gasPrice may need to be modified to deploy successfully. To deploy a contract we need to build the contract, sign it, then send the raw transaction. Once it is sent, we will wait (times out at 2 minutes), for the transaction to be accepted. However, it might take longer until it is fully written to a block. Inside of the contract, the ChainID is unique to each of the blockchains. If you look at the table above, you'll see that Ropsten is 3, Rinkeby is 4, etc. The gas used should be somewhere between 50,000 to 100,000 to be successful (I received errors that the gas was too low, so I jumped it to 700k, don't do this in real life!), with an absolute minimum of 21,000. Meanwhile, gas price will and certainly do change, but as of today (May 2021):
#================ BUILD CONTRACT ================ company_shares = 100000 company_shares_price = 1 company_stock = w3.eth.contract(abi=abi, bytecode=BYTECODE) construct_txn = company_stock.constructor(sender_account.address, company_shares, company_shares_price).buildTransaction({ 'chainId': 3, 'from': sender_account.address, 'gas': 700000, 'gasPrice': w3.toWei('220', 'gwei'), 'nonce': w3.eth.getTransactionCount(sender_account.address)}) # You may need to adjust the gas and the gasPrice for this to complete. # Upon completion, all of the shares will be given to the contract creator. # Sign, create the contract, and wait until the transaction is complete. print("Creating the contract transaction") signed_txn = w3.eth.account.signTransaction(construct_txn, sender_account.privateKey) print(f"Signed Txn: {signed_txn}") tx_hash = w3.eth.sendRawTransaction(signed_txn.rawTransaction) print(f"tx HASH: {tx_hash}") tx_receipt = w3.eth.waitForTransactionReceipt(tx_hash) print(f"TX RECEIPT: {tx_receipt}") print(f"NEW CONTRACT ADDRESS: {tx_receipt.contractAddress}") time_to_wait = 240 print(f"It may take a few minutes to create your contract, sleeping for {time_to_wait} seconds.") time.sleep(time_to_wait) Now that we have waited and the contract has been created, I'm going to display the addresses (you can show the private keys if you want, just in case something goes very south). Then we can check our holdings for the various accounts. This should show that the sender has all of the shares, 100,000, and both the contract and the receiver will have none. amount_to_buy = 20 contract_addr = tx_receipt.contractAddress #contract_addr="0x39898B49021fa1d7847D8C507fe3a750f5DcDfba" contract_instance = w3.eth.contract(address=contract_addr, abi=abi) print(f"Sender Account: {sender_account.address}") #print(f"Sender Account Private Key: {sender_account.privateKey}") print(f"Receiver Account: {receiver_account.address}") #print(f"Receiver Account Private Key: {receiver_account.privateKey}") print(f"Contract Address: {contract_addr}") contract_owner = sender_account.address contract_owner_private = sender_account.privateKey print(f"Contract Owner address: {contract_owner}") print(f"Get holding for contract_addr:") print(contract_instance.functions.getHolding(contract_addr).call()) print(f"Get holding for contract_owner address:") print(contract_instance.functions.getHolding(contract_owner).call()) print(f"Get holding for sender_account address:") print(contract_instance.functions.getHolding(sender_account.address).call()) print(f"Get holding for receiver_account address:") print(contract_instance.functions.getHolding(receiver_account.address).call()) Now that we have verified that the balances are correct, we will transfer some of the funds from the sender to the receiver. We will follow a similar process as building the contract: create the transaction, sign it, send it, and wait for receipt. Once it is complete, we will check the balances once more. print(f"\n{receiver_account.address} is transfering {amount_to_buy} shares of stock.\n") # Functions: payBill, sellStock, buyStock, transferStock transaction = contract_instance.functions.transferStock(receiver_account.address, amount_to_buy).buildTransaction({'chainId': 3, 'gas':75000, 'nonce': w3.eth.getTransactionCount(sender_account.address)}) signed_txn = w3.eth.account.signTransaction(transaction, sender_account.privateKey) txn_hash = w3.eth.sendRawTransaction(signed_txn.rawTransaction) tx_receipt = w3.eth.waitForTransactionReceipt(txn_hash) print(f"Get holding for Contract address:") print(contract_instance.functions.getHolding(contract_addr).call()) print(f"Get holding for sender_account address:") print(contract_instance.functions.getHolding(sender_account.address).call()) print(f"Get holding for receiver_account address:") print(contract_instance.functions.getHolding(receiver_account.address).call()) print("\nFINISHED.") Congratulations on building, deploying, reading and writing to your smart contract. If you have any questions or comments, please leave them below. Here is a link to the complete code used.
What we plan on accomplishing:
As with everything, documentation is lacking and it took me a few days to find all of the resources to deploy an example smart contract and find the necessary resources. I'm hoping that this will help students and developers to quickly get going with all of the resources necessary to start doing development work on Blockchain, in python, quickly. That said, this "guide", may not be complete, may not be accurate (especially since things are evolving so rapidly), but it is my guide from not having an address or account anywhere, to deploying a smart vyper contract and interacting with it in CLI. Consider it a cheat sheet on how to get started fast. We will be doing everything free, so we will be using the "Ropsten Testnet Network" and for completeness, we'll be using vyper most complete example for smart contract, their company stock example. From their website: This contract is just a tad bit more thorough than the ones we’ve previously encountered. In this example, we are going to look at a comprehensive contract that manages the holdings of all shares of a company. The contract allows for a person to buy, sell and transfer shares of a company as well as allowing for the company to pay a person in ether. The company, upon initialization of the contract, holds all shares of the company at first but can sell them all. Currently, most smart contracts are written in solidity and vyper. Solidity follows javascript, while vyper is more pythonic. Older, no longer supported, or rarely updated languages include Mutan, LLL, Serpant, and Bamboo. While solidity is akin to the 800 pound gorilla, vyper has some strong benefits and focuses on security and has been well studied (pdf) and actively maintained. So without further adieu, lets begin. TL;DR....
pip3 install web3 from web3 import Web3 infura_url = "https://ropsten.infura.io/v3/<PROJECT ID>" web3 = Web3(Web3.HTTPProvider(infura_url)) my_account = web3.eth.account.create('Awesome test') print(f"Web3 is connected?: {web3.isConnected()}")
Note: my_account will then have your: my_account.address, my_account.key, and my_account.privateKey
Your web3, should show as connected, returning a True. You can also create a wallet from places like, https://www.myetherwallet.com. If you made your key manually and have a text file, for example, `UTC--2021-04-26T20-00-11.234Z--ABCDEFGHIJKLMNOP`, you can create your private key as follows: with open('UTC--2021-04-26T20-00-11.234Z--ABCDEFGHIJKLMNOP') as keyfile: encrypted_key = keyfile.read() private_key = web3.eth.account.decrypt(encrypted_key, '<SUPER SECURE PASSWORD HERE USED AT CREATION>')
4. Go to https://faucet.ropsten.be/ and enter your address. This will give you a test Ether.
5. Go to https://ropsten.etherscan.io and verify that your account now has one test Ether. 6. Go to https://www.myetherwallet.com (MEW)and connect to your account. If you followed the steps above, you can enter your private key into the "Access by Software" section on the website and entering your private key in hex form: `print(my_account.privateKey.hex())` Since none of us are bitcoin millionaires and this is for testing purposes, I don't mind the relaxed security for testing. If there is ANY real currency, I highly recommend other, more secure, approaches. MEW is a nice tool to easily view 1. that you have received your test ethers, 2. displaying & 3. deploying smart contracts, and 4. viewing transactions. The above 6 steps are essential in getting you started and paving the way for starting your development work in Blockchain technology. In the next part, we will deploy our smart contract, and create some simple code to start interacting with it. Resources: |
AuthorJames Benson is an IT professional. Archives
August 2022
Categories
All
|