-
Notifications
You must be signed in to change notification settings - Fork 5
/
05_zksync2_transfer.py
153 lines (115 loc) · 4.29 KB
/
05_zksync2_transfer.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
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
import os
from dotenv import load_dotenv
from eth_account import Account
from eth_account.signers.local import LocalAccount
from eth_typing import HexStr, HexAddress
from eth_utils import to_checksum_address, remove_0x_prefix
from web3 import Web3
from zksync2.core.types import ZkBlockParams, EthBlockParams
from zksync2.module.module_builder import ZkSyncBuilder
from zksync2.signer.eth_signer import PrivateKeyEthSigner
from zksync2.transaction.transaction_builders import TxFunctionCall
from utils.read_wallets import ReadWallets
def get_eth_balance(zk_web3: Web3, address: HexAddress) -> float:
"""
Get ETH balance of ETH address on zkSync network
:param zk_web3:
Instance of ZkSyncBuilder that interacts with zkSync network
:param address:
ETH address that you want to get balance of.
:return:
Balance of ETH address.
"""
# Get WEI balance of ETH address
balance_wei = zk_web3.zksync.get_balance(
address,
EthBlockParams.LATEST.value
)
# Convert WEI balance to ETH
balance_eth = Web3.from_wei(balance_wei, "ether")
# Return the ETH balance of the ETH address
return balance_eth
def transfer_eth(
zk_web3: Web3,
account: LocalAccount,
address: HexAddress,
amount: float
) -> bytes:
"""
Transfer ETH to a desired address on zkSync network
:param zk_web3:
Instance of ZkSyncBuilder that interacts with zkSync network
:param account:
From which account the transfer will be made
:param address:
Desired ETH address that you want to transfer to.
:param amount:
Desired ETH amount that you want to transfer.
:return:
The transaction hash of the deposit transaction.
"""
# 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, ZkBlockParams.COMMITTED.value
)
# Get current gas price in Wei
gas_price = zk_web3.zksync.gas_price
# Create transaction
tx_func_call = TxFunctionCall(
chain_id=chain_id,
nonce=nonce,
from_=account.address,
to=to_checksum_address(address),
value=zk_web3.to_wei(amount, "ether"),
data=HexStr("0x"),
gas_limit=0, # UNKNOWN AT THIS STATE
gas_price=gas_price,
max_priority_fee_per_gas=100_000_000,
)
# ZkSync transaction gas estimation
estimate_gas = zk_web3.zksync.eth_estimate_gas(tx_func_call.tx)
print(f"Fee for transaction is: {estimate_gas * gas_price}")
# Convert transaction to EIP-712 format
tx_712 = tx_func_call.tx712(estimate_gas)
# Sign message & encode it
signed_message = signer.sign_typed_data(tx_712.to_eip712_struct())
# Encode signed message
msg = tx_712.encode(signed_message)
# Transfer ETH
tx_hash = zk_web3.zksync.send_raw_transaction(msg)
print(f"Transaction hash is : {tx_hash.hex()}")
# Wait for 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']}")
# Return the transaction hash of the transfer
return tx_hash
# Set a provider
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']))))
# Show balance before ETH transfer
print(f"Balance before transfer : {get_eth_balance(zk_web3, account.address)} ETH")
# Perform the ETH transfer
transfer_eth(
zk_web3,
account,
account.address,
0.0001
)
# Show balance after ETH transfer
print(f"Balance after transfer : {get_eth_balance(zk_web3, account.address)} ETH")