Here we will write the code needed to deploy the smart contract. As mentioned in the prerequisites, you will need to have some Ropsten ETH at your disposal.
Open up your deployer.py file and write the following code.
deploying the smart contract
from eth_account import Account
from web3 import Web3
import secrets
priv = secrets.token_hex(32)
private_key = "0x" + priv
print ("SAVE BUT DO NOT SHARE THIS:", private_key)
acct = Account.from_key(private_key)
print("Address:", acct.address)
from eth_account import Account
from web3 import Web3
import secrets
priv = secrets.token_hex(32)
private_key = "0x" + priv
print ("SAVE BUT DO NOT SHARE THIS:", private_key)
acct = Account.from_key(private_key)
print("Address:", acct.address)
from eth_account import Account
from web3 import Web3
import secrets
priv = secrets.token_hex(32)
private_key = "0x" + priv
print ("SAVE BUT DO NOT SHARE THIS:", private_key)
acct = Account.from_key(private_key)
print("Address:", acct.address)
Here we are importing all of the libraries we will need to deploy the contract, as well as generating a private key ussing the secrets.token_hex() method. Save this file, and then run the script with the following command:
deploying the smart contract
python3 deployer.py
python3 deployer.py
Alt Text: SAVE BUT DO NOT SHARE THIS: 0xae4d38cbdd44521036658724403d3f2b33dbb26b2e9c93a93be083515979a2e3 Address: 0xd466687E156D088E8e97e13bb838113A4676EC06
Here you can see we have generated a private key, along with its address. Modify your python code to have this private key hardcoded. I will be using the one that I'm sharing in the terminal, but you should use the key that your script generated.
deploying the smart contract
from eth_account import Account
from web3 import Web3
import secrets
priv = secrets.token_hex(32)
private_key = "0x" + priv
private_key = "YOUR_PRIVATE_KEY_HERE"
print ("SAVE BUT DO NOT SHARE THIS:", private_key)
acct = Account.from_key(private_key)
print("Address:", acct.address)
from eth_account import Account
from web3 import Web3
import secrets
priv = secrets.token_hex(32)
private_key = "0x" + priv
private_key = "YOUR_PRIVATE_KEY_HERE"
print ("SAVE BUT DO NOT SHARE THIS:", private_key)
acct = Account.from_key(private_key)
print("Address:", acct.address)
from eth_account import Account
from web3 import Web3
import secrets
priv = secrets.token_hex(32)
private_key = "0x" + priv
private_key = "YOUR_PRIVATE_KEY_HERE"
print ("SAVE BUT DO NOT SHARE THIS:", private_key)
acct = Account.from_key(private_key)
print("Address:", acct.address)
Here you can see that we are reassigning private_key from the randomly generated value to the value you generated from running the script.
The next thing we will need to do is compile our smart contract into bytecode so we can deploy the contract to the testnet.
To do so, run the following command:
deploying the smart contract
vyper graffiti_wall.vy
vyper graffiti_wall.vy
It should spit out a long string that looks a little like this:
deploying the smart contract
0x33600a55600346186102a85761029056600436101561000d57610275565b60046000601c376000513461027b57632502eb8081186100a6576004358060a01c61027b5760e052600a54331861027b5760006101005261014060006005818352015b6101405154610120526000610120511461007f5761010080516001818183011061027b57808201905090508152505b815160010180835281141561005057505060e051600161010051600581101561027b570255005b63f92d4699811861019557600435600401606481351161027b57808035602001808260e0375050506000610180526101c060006005818352015b6101c051546101a052336101a051186100fa576001610180525b81516001018083528114156100e057505061018051156101935760e0806005602082510160c060006005818352015b8260c051602002111561013b5761015a565b60c05160200285015160c0518501558151600101808352811415610129575b50505050505060e08051602082012090507f1feb66a2165328c0029dd757c8c304e5a76ebb0f047f8eefaf16e9bbfa6e336660006101a0a25b005b635506011181186101b9576001600435600581101561027b57025460e052602060e0f35b63bbbaf2c3811861025c5760e08060208082528083018060058082602082540160c060006005818352015b8260c05160200211156101f657610215565b60c05185015460c05160200285015281516001018083528114156101e4575b5050505050508051806020830101818260206001820306601f8201039050033682375050805160200160206001820306601f820103905090509050810190509050905060e0f35b638da5cb5b811861027357600a5460e052602060e0f35b505b60006000fd5b600080fd5b61001061029003610010600039610010610290036000f35b600080fd
0x33600a55600346186102a85761029056600436101561000d57610275565b60046000601c376000513461027b57632502eb8081186100a6576004358060a01c61027b5760e052600a54331861027b5760006101005261014060006005818352015b6101405154610120526000610120511461007f5761010080516001818183011061027b57808201905090508152505b815160010180835281141561005057505060e051600161010051600581101561027b570255005b63f92d4699811861019557600435600401606481351161027b57808035602001808260e0375050506000610180526101c060006005818352015b6101c051546101a052336101a051186100fa576001610180525b81516001018083528114156100e057505061018051156101935760e0806005602082510160c060006005818352015b8260c051602002111561013b5761015a565b60c05160200285015160c0518501558151600101808352811415610129575b50505050505060e08051602082012090507f1feb66a2165328c0029dd757c8c304e5a76ebb0f047f8eefaf16e9bbfa6e336660006101a0a25b005b635506011181186101b9576001600435600581101561027b57025460e052602060e0f35b63bbbaf2c3811861025c5760e08060208082528083018060058082602082540160c060006005818352015b8260c05160200211156101f657610215565b60c05185015460c05160200285015281516001018083528114156101e4575b5050505050508051806020830101818260206001820306601f8201039050033682375050805160200160206001820306601f820103905090509050810190509050905060e0f35b638da5cb5b811861027357600a5460e052602060e0f35b505b60006000fd5b600080fd5b61001061029003610010600039610010610290036000f35b600080fd
0x33600a55600346186102a85761029056600436101561000d57610275565b60046000601c376000513461027b57632502eb8081186100a6576004358060a01c61027b5760e052600a54331861027b5760006101005261014060006005818352015b6101405154610120526000610120511461007f5761010080516001818183011061027b57808201905090508152505b815160010180835281141561005057505060e051600161010051600581101561027b570255005b63f92d4699811861019557600435600401606481351161027b57808035602001808260e0375050506000610180526101c060006005818352015b6101c051546101a052336101a051186100fa576001610180525b81516001018083528114156100e057505061018051156101935760e0806005602082510160c060006005818352015b8260c051602002111561013b5761015a565b60c05160200285015160c0518501558151600101808352811415610129575b50505050505060e08051602082012090507f1feb66a2165328c0029dd757c8c304e5a76ebb0f047f8eefaf16e9bbfa6e336660006101a0a25b005b635506011181186101b9576001600435600581101561027b57025460e052602060e0f35b63bbbaf2c3811861025c5760e08060208082528083018060058082602082540160c060006005818352015b8260c05160200211156101f657610215565b60c05185015460c05160200285015281516001018083528114156101e4575b5050505050508051806020830101818260206001820306601f8201039050033682375050805160200160206001820306601f820103905090509050810190509050905060e0f35b638da5cb5b811861027357600a5460e052602060e0f35b505b60006000fd5b600080fd5b61001061029003610010600039610010610290036000f35b600080fd
We are going to assign this to a variable called bytecode in our python script. Along with the new variable, we are going to connect to the blockchain using our HTTP Provider from QuickNode, and then deploy the contract to the testnet. All in all, your script should look like this:
deploying the smart contract
from eth_account import Account
from web3 import Web3
import secrets
priv = secrets.token_hex(32)
private_key = "0x" + priv
private_key = "YOUR_PRIVATE_KEY_HERE"
print ("SAVE BUT DO NOT SHARE THIS:", private_key)
acct = Account.from_key(private_key)
print("Address:", acct.address)
bytecode = "0x33600a55600346186102a85761029056600436101561000d57610275565b60046000601c376000513461027b57632502eb8081186100a6576004358060a01c61027b5760e052600a54331861027b5760006101005261014060006005818352015b6101405154610120526000610120511461007f5761010080516001818183011061027b57808201905090508152505b815160010180835281141561005057505060e051600161010051600581101561027b570255005b63f92d4699811861019557600435600401606481351161027b57808035602001808260e0375050506000610180526101c060006005818352015b6101c051546101a052336101a051186100fa576001610180525b81516001018083528114156100e057505061018051156101935760e0806005602082510160c060006005818352015b8260c051602002111561013b5761015a565b60c05160200285015160c0518501558151600101808352811415610129575b50505050505060e08051602082012090507f1feb66a2165328c0029dd757c8c304e5a76ebb0f047f8eefaf16e9bbfa6e336660006101a0a25b005b635506011181186101b9576001600435600581101561027b57025460e052602060e0f35b63bbbaf2c3811861025c5760e08060208082528083018060058082602082540160c060006005818352015b8260c05160200211156101f657610215565b60c05185015460c05160200285015281516001018083528114156101e4575b5050505050508051806020830101818260206001820306601f8201039050033682375050805160200160206001820306601f820103905090509050810190509050905060e0f35b638da5cb5b811861027357600a5460e052602060e0f35b505b60006000fd5b600080fd5b61001061029003610010600039610010610290036000f35b600080fd"
w3 = Web3(Web3.HTTPProvider('https://cool-frosty-moon.ropsten.quiknode.pro/your-token-here'))
signed_txn = w3.eth.account.sign_transaction(dict(
nonce=w3.eth.get_transaction_count(acct.address),
gasPrice=20000000000,
gas=900000,
to=None,
value=0,
data=bytecode,
chainId=3, #ropsten
),
private_key,
)
print(signed_txn)
tx = w3.eth.send_raw_transaction(signed_txn.rawTransaction)
print(tx.hex())
from eth_account import Account
from web3 import Web3
import secrets
priv = secrets.token_hex(32)
private_key = "0x" + priv
private_key = "YOUR_PRIVATE_KEY_HERE"
print ("SAVE BUT DO NOT SHARE THIS:", private_key)
acct = Account.from_key(private_key)
print("Address:", acct.address)
bytecode = "0x33600a55600346186102a85761029056600436101561000d57610275565b60046000601c376000513461027b57632502eb8081186100a6576004358060a01c61027b5760e052600a54331861027b5760006101005261014060006005818352015b6101405154610120526000610120511461007f5761010080516001818183011061027b57808201905090508152505b815160010180835281141561005057505060e051600161010051600581101561027b570255005b63f92d4699811861019557600435600401606481351161027b57808035602001808260e0375050506000610180526101c060006005818352015b6101c051546101a052336101a051186100fa576001610180525b81516001018083528114156100e057505061018051156101935760e0806005602082510160c060006005818352015b8260c051602002111561013b5761015a565b60c05160200285015160c0518501558151600101808352811415610129575b50505050505060e08051602082012090507f1feb66a2165328c0029dd757c8c304e5a76ebb0f047f8eefaf16e9bbfa6e336660006101a0a25b005b635506011181186101b9576001600435600581101561027b57025460e052602060e0f35b63bbbaf2c3811861025c5760e08060208082528083018060058082602082540160c060006005818352015b8260c05160200211156101f657610215565b60c05185015460c05160200285015281516001018083528114156101e4575b5050505050508051806020830101818260206001820306601f8201039050033682375050805160200160206001820306601f820103905090509050810190509050905060e0f35b638da5cb5b811861027357600a5460e052602060e0f35b505b60006000fd5b600080fd5b61001061029003610010600039610010610290036000f35b600080fd"
w3 = Web3(Web3.HTTPProvider('https://cool-frosty-moon.ropsten.quiknode.pro/your-token-here'))
signed_txn = w3.eth.account.sign_transaction(dict(
nonce=w3.eth.get_transaction_count(acct.address),
gasPrice=20000000000,
gas=900000,
to=None,
value=0,
data=bytecode,
chainId=3, #ropsten
),
private_key,
)
print(signed_txn)
tx = w3.eth.send_raw_transaction(signed_txn.rawTransaction)
print(tx.hex())
from eth_account import Account
from web3 import Web3
import secrets
priv = secrets.token_hex(32)
private_key = "0x" + priv
private_key = "YOUR_PRIVATE_KEY_HERE"
print ("SAVE BUT DO NOT SHARE THIS:", private_key)
acct = Account.from_key(private_key)
print("Address:", acct.address)
bytecode = "0x33600a55600346186102a85761029056600436101561000d57610275565b60046000601c376000513461027b57632502eb8081186100a6576004358060a01c61027b5760e052600a54331861027b5760006101005261014060006005818352015b6101405154610120526000610120511461007f5761010080516001818183011061027b57808201905090508152505b815160010180835281141561005057505060e051600161010051600581101561027b570255005b63f92d4699811861019557600435600401606481351161027b57808035602001808260e0375050506000610180526101c060006005818352015b6101c051546101a052336101a051186100fa576001610180525b81516001018083528114156100e057505061018051156101935760e0806005602082510160c060006005818352015b8260c051602002111561013b5761015a565b60c05160200285015160c0518501558151600101808352811415610129575b50505050505060e08051602082012090507f1feb66a2165328c0029dd757c8c304e5a76ebb0f047f8eefaf16e9bbfa6e336660006101a0a25b005b635506011181186101b9576001600435600581101561027b57025460e052602060e0f35b63bbbaf2c3811861025c5760e08060208082528083018060058082602082540160c060006005818352015b8260c05160200211156101f657610215565b60c05185015460c05160200285015281516001018083528114156101e4575b5050505050508051806020830101818260206001820306601f8201039050033682375050805160200160206001820306601f820103905090509050810190509050905060e0f35b638da5cb5b811861027357600a5460e052602060e0f35b505b60006000fd5b600080fd5b61001061029003610010600039610010610290036000f35b600080fd"
w3 = Web3(Web3.HTTPProvider('https://cool-frosty-moon.ropsten.quiknode.pro/your-token-here'))
signed_txn = w3.eth.account.sign_transaction(dict(
nonce=w3.eth.get_transaction_count(acct.address),
gasPrice=20000000000,
gas=900000,
to=None,
value=0,
data=bytecode,
chainId=3, #ropsten
),
private_key,
)
print(signed_txn)
tx = w3.eth.send_raw_transaction(signed_txn.rawTransaction)
print(tx.hex())
Here you can see our newly added bytecode, in addition to the code needed to send a transaction using web3.py. You can see we initialize the w3 variable, which allows us to connect to the blockchain so we can send transactions. We then use the sign_transaction method to generate a transaction, and then we use the send_raw_transaction method to send the transaction up to the blockchain.
The contents of the transaction are around setting up the gas price you are willing to pay, what network you are sending it to, and what data should be included. This code is sending the smart contract (the bytecode) to
None, which is how we deploy smart contracts to Ethereum networks. You can also dictate which network to deploy to via this transaction data. In this transaction, we are using a chain id of 3 which is the id of the Ropsten network. This also is not utilizing some of the knobs that EIP-1559 have given users. If you would like to, you can learn more about how to send EIP-1559 transactions
here.
Save your file, and then run the command we used before.
deploying the smart contract
python3 deployer.py
python3 deployer.py
Your output should look similar to this:
This is mostly information about the transaction. What we are really interested in is the hash of the transaction so we can look it up on etherscan. You can find the hash at the very bottom of your output. In my case it was:
0x22e17f92dea5f3208e179dbc7125271fb9cb77fc3a9da86903b7d6772640d733. Open up
Ropsten Etherscan and paste your transaction hash in. My transaction looks like the picture below.
From there, you can see the contract you deployed in the to field of the transaction. From there, go to the contract tab.
You will want to open up MetaMask, and import a new account using the private key you generated earlier.
After setting up your MetaMask account (make sure you are on the Ropsten Test Network), hit the "Connect to Web3" button under the "Write Contract" tab. After connecting your wallet, paste your wallet address into the add_approved_address method and click "Write." You should now have a MetaMask pop up asking for confirmation. Once that transaction goes through, you can then go to the second method.
Here you can paste any string. I'm going to send "gm graffiti frens." Once both of those transactions have been approved go to the "Read Contract" tab. Check the approved_addresses at the 0 index. You should see the address that you pasted in the previous step. Here you can confirm the statement I made earlier around the 0x00 address. If you query numbers 1-4 you will see the address returned is 0x00. If you query a number higher than 4, you will get an error, as we only allocated space in the smart contract for 5 addresses total.
You also can check the graffiti_wall for the message. You can check what mine looks like
here. If you would like to test the security of the contract, you can switch to a different account, and try the same methods. You will not be able to add anyone to the approved addresses array as you are not the owner and will not be able to write to the wall since you are not on the white list.
The last thing to check is that our events are being properly emitted. Go over to the "Events" tab in Etherscan and you should have 1 GraffitiSet event logged there.