-
Notifications
You must be signed in to change notification settings - Fork 5
/
06_zksync2_deploy_contract.py
113 lines (85 loc) · 3.55 KB
/
06_zksync2_deploy_contract.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
import os
from pathlib import Path
from dotenv import load_dotenv
from eth_account import Account
from eth_account.signers.local import LocalAccount
from eth_typing import HexAddress, HexStr
from eth_utils import remove_0x_prefix
from web3 import Web3
from zksync2.core.types import EthBlockParams
from zksync2.manage_contracts.contract_encoder_base import ContractEncoder
from zksync2.module.module_builder import ZkSyncBuilder
from zksync2.signer.eth_signer import PrivateKeyEthSigner
from zksync2.transaction.transaction_builders import TxCreateContract
from utils.read_wallets import ReadWallets
def deploy_contract(
zk_web3: Web3, account: LocalAccount, compiled_contract: Path
) -> HexAddress:
"""Deploy compiled contract on zkSync network using create() opcode
:param zk_web3:
Instance of ZkSyncBuilder that interacts with zkSync network
:param account:
From which account the deployment contract tx will be made
:param compiled_contract:
Compiled contract source.
:return:
Address of deployed contract.
"""
# Get chain id of zkSync network
chain_id = zk_web3.zksync.chain_id
# Signer is used to generate signature of provided transaction
signer = PrivateKeyEthSigner(account, chain_id)
# Get nonce of ETH address on zkSync network
nonce = zk_web3.zksync.get_transaction_count(
account.address, EthBlockParams.PENDING.value
)
# Get contract ABI and bytecode information
storage_contract = ContractEncoder.from_json(zk_web3, compiled_contract)[0]
# Get current gas price in Wei
gas_price = zk_web3.zksync.gas_price
# Create deployment contract transaction
create_contract = TxCreateContract(
web3=zk_web3,
chain_id=chain_id,
nonce=nonce,
from_=account.address,
gas_limit=0, # UNKNOWN AT THIS STATE
gas_price=gas_price,
bytecode=storage_contract.bytecode,
)
# ZkSync transaction gas estimation
estimate_gas = zk_web3.zksync.eth_estimate_gas(create_contract.tx)
print(f"Fee for transaction is: {Web3.from_wei(estimate_gas * gas_price, 'ether')} ETH")
# Convert transaction to EIP-712 format
tx_712 = create_contract.tx712(estimate_gas)
# Sign message
signed_message = signer.sign_typed_data(tx_712.to_eip712_struct())
# Encode signed message
msg = tx_712.encode(signed_message)
# Deploy contract
tx_hash = zk_web3.zksync.send_raw_transaction(msg)
# Wait for deployment contract transaction to be included in a block
tx_receipt = zk_web3.zksync.wait_for_transaction_receipt(
tx_hash, timeout=240, poll_latency=0.5
)
print(f"Tx status: {tx_receipt['status']}")
contract_address = tx_receipt["contractAddress"]
print(f"Deployed contract address: {contract_address}")
# Return the contract deployed address
return contract_address
if __name__ == "__main__":
load_dotenv()
zksync_url = os.getenv('ZKSYNC_URL')
if zksync_url is None:
print("Err: ZKSYNC_URL not set")
# Connect to zkSync network
zk_web3 = ZkSyncBuilder.build(zksync_url)
wallets = ReadWallets()
accounts = wallets.get_accounts()
for wallet in accounts:
# Get account object by providing from private key
account: LocalAccount = Account.from_key(bytes.fromhex(remove_0x_prefix(HexStr(wallet['privateKey']))))
# Provide a compiled JSON source contract
contract_path = Path("solidity/storage/build/combined.json")
# Perform contract deployment
deploy_contract(zk_web3, account, contract_path)