diff --git a/examples/02_transfer.py b/examples/02_transfer.py index f207e59..1391230 100644 --- a/examples/02_transfer.py +++ b/examples/02_transfer.py @@ -62,7 +62,7 @@ def transfer_eth( Desired ETH amount that you want to transfer. :return: - The transaction hash of the deposit transaction. + The transaction hash of the transfer transaction. """ diff --git a/examples/03_transfer_erc20_token.py b/examples/03_transfer_erc20_token.py index 539689d..eb8705f 100644 --- a/examples/03_transfer_erc20_token.py +++ b/examples/03_transfer_erc20_token.py @@ -1,90 +1,90 @@ +import os + from eth_account import Account from eth_account.signers.local import LocalAccount -from web3 import Web3 +from eth_typing import HexAddress, HexStr -from examples.utils import EnvPrivateKey -from zksync2.core.types import ZkBlockParams, ADDRESS_DEFAULT, Token -from zksync2.manage_contracts.erc20_contract import ERC20Contract, ERC20Encoder +from zksync2.core.types import EthBlockParams +from zksync2.manage_contracts.erc20_contract import get_erc20_abi from zksync2.module.module_builder import ZkSyncBuilder -from zksync2.signer.eth_signer import PrivateKeyEthSigner -from zksync2.transaction.transaction_builders import TxFunctionCall - -ZKSYNC_TEST_URL = "https://testnet.era.zksync.dev" -ETH_TEST_URL = "https://rpc.ankr.com/eth_goerli" -SERC20_Address = Web3.to_checksum_address("0xd782e03F4818A7eDb0bc5f70748F67B4e59CdB33") - - -class Colors: - HEADER = '\033[95m' - OKBLUE = '\033[94m' - OKCYAN = '\033[96m' - OKGREEN = '\033[92m' - WARNING = '\033[93m' - FAIL = '\033[91m' - ENDC = '\033[0m' - BOLD = '\033[1m' - UNDERLINE = '\033[4m' - - -def transfer_erc20(amount: float): - env1 = EnvPrivateKey("ZKSYNC_TEST_KEY") - env2 = EnvPrivateKey("ZKSYNC_TEST_KEY2") - web3 = ZkSyncBuilder.build(ZKSYNC_TEST_URL) - alice: LocalAccount = Account.from_key(env1.key) - bob: LocalAccount = Account.from_key(env2.key) - chain_id = web3.zksync.chain_id - signer = PrivateKeyEthSigner(alice, chain_id) - - erc20_token = Token(l1_address=ADDRESS_DEFAULT, - l2_address=SERC20_Address, - symbol="SERC20", - decimals=18) - erc20 = ERC20Contract(web3=web3.zksync, - contract_address=erc20_token.l2_address, - account=alice) - - alice_balance_before = erc20.balance_of(alice.address) - bob_balance_before = erc20.balance_of(bob.address) - print(f"Alice {erc20_token.symbol} balance before : {erc20_token.format_token(alice_balance_before)}") - print(f"Bob {erc20_token.symbol} balance before : {erc20_token.format_token(bob_balance_before)}") - - erc20_encoder = ERC20Encoder(web3) - transfer_params = (bob.address, erc20_token.to_int(amount)) - call_data = erc20_encoder.encode_method("transfer", args=transfer_params) - - nonce = web3.zksync.get_transaction_count(alice.address, ZkBlockParams.COMMITTED.value) - - gas_price = web3.zksync.gas_price - func_call = TxFunctionCall(chain_id=chain_id, - nonce=nonce, - from_=alice.address, - to=erc20_token.l2_address, - data=call_data, - gas_limit=0, # UNKNOWN AT THIS STATE - gas_price=gas_price, - max_priority_fee_per_gas=100000000) - - estimate_gas = web3.zksync.eth_estimate_gas(func_call.tx) - print(f"Fee for transaction is: {estimate_gas * gas_price}") - tx_712 = func_call.tx712(estimated_gas=estimate_gas) - singed_message = signer.sign_typed_data(tx_712.to_eip712_struct()) - msg = tx_712.encode(singed_message) - tx_hash = web3.zksync.send_raw_transaction(msg) - tx_receipt = web3.zksync.wait_for_transaction_receipt(tx_hash, timeout=240, poll_latency=0.5) - print(f"Tx status: {tx_receipt['status']}") - print(f"Tx hash: {tx_receipt['transactionHash'].hex()}") - alice_balance_after = erc20.balance_of(alice.address) - bob_balance_after = erc20.balance_of(bob.address) - print(f"Alice {erc20_token.symbol} balance before : {erc20_token.format_token(alice_balance_after)}") - print(f"Bob {erc20_token.symbol} balance before : {erc20_token.format_token(bob_balance_after)}") - if bob_balance_after == bob_balance_before + erc20_token.to_int(amount) and \ - alice_balance_after == alice_balance_before - erc20_token.to_int(amount): - print(f"{Colors.OKGREEN}{amount} of {erc20_token.symbol} tokens have been transferred{Colors.ENDC}") - else: - print(f"{Colors.FAIL}{erc20_token.symbol} transfer has failed{Colors.ENDC}") +def transfer_erc20( + token_contract, + account: LocalAccount, + address: HexAddress, + amount: float) -> HexStr: + """ + Transfer ETH to a desired address on zkSync network + + :param token_contract: + Instance of ERC20 contract + + :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 transfer transaction. + + """ + tx = token_contract.functions.transfer(address, amount).build_transaction({ + "nonce": zk_web3.zksync.get_transaction_count(account.address, EthBlockParams.LATEST.value), + "from": account.address, + "maxPriorityFeePerGas": 1_000_000, + "maxFeePerGas": zk_web3.zksync.gas_price, + }) + + signed = account.sign_transaction(tx) + + # Send transaction to zkSync network + tx_hash = zk_web3.zksync.send_raw_transaction(signed.rawTransaction) + print(f"Tx: {tx_hash.hex()}") + + 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 tx_hash if __name__ == "__main__": - transfer_erc20(1) + # Byte-format private key + # PRIVATE_KEY = bytes.fromhex(os.environ.get("PRIVATE_KEY")) + PRIVATE_KEY = bytes.fromhex("7726827caac94a7f9e1b160f7ea819f172f7b6f9d2a97f992c38edeab82d4110") + + # Set a provider + # PROVIDER = "https://testnet.era.zksync.dev" + PROVIDER = "http://127.0.0.1:3050" + + # Connect to zkSync network + zk_web3 = ZkSyncBuilder.build(PROVIDER) + + # Get account object by providing from private key + account1: LocalAccount = Account.from_key(PRIVATE_KEY) + account2_address = zk_web3.to_checksum_address("0xa61464658AfeAf65CccaaFD3a512b69A83B77618") + + token_address = zk_web3.to_checksum_address("0x2Ed5EfAB90d161DdCC65693bd77c3344200c9a00") + token_contract = zk_web3.zksync.contract(token_address, abi=get_erc20_abi()) + + # Show balance before token transfer + print(f"Account1 Crown balance before transfer: {token_contract.functions.balanceOf(account1.address).call()}") + print(f"Account2 Crown balance before transfer: {token_contract.functions.balanceOf(account2_address).call()}") + + # Perform the ETH transfer + transfer_erc20( + token_contract, + account1, + account2_address, + 3 + ) + + # Show balance after token transfer + print(f"Account1 Crown balance after transfer: {token_contract.functions.balanceOf(account1.address).call()}") + print(f"Account2 Crown balance after transfer: {token_contract.functions.balanceOf(account2_address).call()}") diff --git a/examples/05_deploy_create_with_constructor.py b/examples/05_deploy_create_with_constructor.py index b282b9a..cb4c366 100644 --- a/examples/05_deploy_create_with_constructor.py +++ b/examples/05_deploy_create_with_constructor.py @@ -53,8 +53,7 @@ def deploy_contract( ) # Get deployment nonce - nonce_holder = NonceHolder(zk_web3, account) - deployment_nonce = nonce_holder.get_deployment_nonce(account.address) + deployment_nonce = NonceHolder(zk_web3, account).get_deployment_nonce(account.address) # Precompute the address of smart contract # Use this if there is a case where contract address should be known before deployment @@ -76,7 +75,6 @@ def deploy_contract( chain_id=chain_id, nonce=nonce, from_=account.address, - gas_limit=0, # UNKNOWN AT THIS STATE, gas_price=gas_price, bytecode=incrementer_contract.bytecode, call_data=encoded_constructor, @@ -105,7 +103,7 @@ def deploy_contract( print(f"Tx status: {tx_receipt['status']}") contract_address = tx_receipt["contractAddress"] - print(f"contract address: {contract_address}") + print(f"Contract address: {contract_address}") # Check does precompute address match with deployed address if precomputed_address.lower() != contract_address.lower(): diff --git a/examples/06_deploy_create_with_deps.py b/examples/06_deploy_create_with_deps.py index f39284b..f97baa1 100644 --- a/examples/06_deploy_create_with_deps.py +++ b/examples/06_deploy_create_with_deps.py @@ -66,7 +66,6 @@ def deploy_contract( chain_id=chain_id, nonce=nonce, from_=account.address, - gas_limit=0, gas_price=gas_price, bytecode=demo_contract.bytecode, deps=[foo_contract.bytecode]) @@ -94,7 +93,7 @@ def deploy_contract( print(f"Tx status: {tx_receipt['status']}") contract_address = tx_receipt["contractAddress"] - print(f"contract address: {contract_address}") + print(f"Contract address: {contract_address}") # Check does precompute address match with deployed address if precomputed_address.lower() != contract_address.lower(): diff --git a/examples/07_deploy_create2.py b/examples/07_deploy_create2.py index 295e030..bda5f40 100644 --- a/examples/07_deploy_create2.py +++ b/examples/07_deploy_create2.py @@ -100,7 +100,7 @@ def deploy_contract( print(f"Tx status: {tx_receipt['status']}") contract_address = tx_receipt["contractAddress"] - print(f"contract address: {contract_address}") + print(f"Contract address: {contract_address}") # Check does precompute address match with deployed address if precomputed_address.lower() != contract_address.lower(): diff --git a/examples/08_deploy_create2_deps.py b/examples/08_deploy_create2_deps.py index fb6dabb..d91927e 100644 --- a/examples/08_deploy_create2_deps.py +++ b/examples/08_deploy_create2_deps.py @@ -100,7 +100,7 @@ def deploy_contract( print(f"Tx status: {tx_receipt['status']}") contract_address = tx_receipt["contractAddress"] - print(f"contract address: {contract_address}") + print(f"Contract address: {contract_address}") # Check does precompute address match with deployed address if precomputed_address.lower() != contract_address.lower(): diff --git a/examples/12_deploy_token.py b/examples/12_deploy_token.py new file mode 100644 index 0000000..7ac9f9f --- /dev/null +++ b/examples/12_deploy_token.py @@ -0,0 +1,140 @@ +import os +from pathlib import Path + +from eth_account import Account +from eth_account.signers.local import LocalAccount +from eth_typing import HexAddress +from web3 import Web3 + +from zksync2.core.types import EthBlockParams +from zksync2.manage_contracts.contract_encoder_base import ContractEncoder, JsonConfiguration +from zksync2.manage_contracts.precompute_contract_deployer import PrecomputeContractDeployer +from zksync2.module.module_builder import ZkSyncBuilder +from zksync2.signer.eth_signer import PrivateKeyEthSigner +from zksync2.transaction.transaction_builders import TxCreate2Contract + + +def generate_random_salt() -> bytes: + return os.urandom(32) + + +def deploy_contract( + zk_web3: Web3, account: LocalAccount, compiled_contract: Path, constructor_args: [dict | tuple] +) -> HexAddress: + """Deploy compiled contract on zkSync network using create2() 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. + + :param constructor_args: + Constructor arguments that can be provided via: + dictionary: {"name_": "Crown", "symbol_": "Crown", "decimals": 18} + tuple: ("Crown", "Crown", 18) + + :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 + ) + + # Deployment of same smart contract (same bytecode) without salt cannot be done twice + # Remove salt if you want to deploy contract only once + random_salt = generate_random_salt() + + # Precompute the address of smart contract + # Use this if there is a case where contract address should be known before deployment + deployer = PrecomputeContractDeployer(zk_web3) + + # Get contract ABI and bytecode information + token_contract = ContractEncoder.from_json(zk_web3, compiled_contract, JsonConfiguration.STANDARD) + + # Encode the constructor arguments + encoded_constructor = token_contract.encode_constructor(**constructor_args) + + # Get precomputed contract address + precomputed_address = deployer.compute_l2_create2_address(sender=account.address, + bytecode=token_contract.bytecode, + constructor=encoded_constructor, + salt=random_salt) + + # Get current gas price in Wei + gas_price = zk_web3.zksync.gas_price + + # Create2 deployment contract transaction + create2_contract = TxCreate2Contract(web3=zk_web3, + chain_id=chain_id, + nonce=nonce, + from_=account.address, + gas_limit=0, + gas_price=gas_price, + bytecode=token_contract.bytecode, + salt=random_salt, + call_data=encoded_constructor) + + # ZkSync transaction gas estimation + estimate_gas = zk_web3.zksync.eth_estimate_gas(create2_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 = create2_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"Contract address: {contract_address}") + + # Check does precompute address match with deployed address + if precomputed_address.lower() != contract_address.lower(): + raise RuntimeError("Precomputed contract address does now match with deployed contract address") + + return contract_address + + +if __name__ == "__main__": + # Set a provider + PROVIDER = "https://testnet.era.zksync.dev" + + # Byte-format private key + PRIVATE_KEY = bytes.fromhex(os.environ.get("PRIVATE_KEY")) + + # Connect to zkSync network + zk_web3 = ZkSyncBuilder.build(PROVIDER) + + # Get account object by providing from private key + account: LocalAccount = Account.from_key(PRIVATE_KEY) + + # Provide a compiled JSON source contract + contract_path = Path("solidity/custom_paymaster/build/Token.json") + + constructor_arguments = {"name_": "Crown", "symbol_": "Crown", "decimals_": 18} + + # Perform contract deployment + deploy_contract(zk_web3, account, contract_path, constructor_arguments) diff --git a/examples/13_deploy_account_create.py b/examples/13_deploy_account_create.py new file mode 100644 index 0000000..1b60a3a --- /dev/null +++ b/examples/13_deploy_account_create.py @@ -0,0 +1,133 @@ +import os +from pathlib import Path + +from eth_account import Account +from eth_account.signers.local import LocalAccount +from eth_typing import HexAddress +from web3 import Web3 + +from zksync2.core.types import EthBlockParams +from zksync2.manage_contracts.contract_encoder_base import ContractEncoder, JsonConfiguration +from zksync2.manage_contracts.nonce_holder import NonceHolder +from zksync2.manage_contracts.precompute_contract_deployer import PrecomputeContractDeployer +from zksync2.module.module_builder import ZkSyncBuilder +from zksync2.signer.eth_signer import PrivateKeyEthSigner +from zksync2.transaction.transaction_builders import TxCreateAccount + + +def deploy_account( + zk_web3: Web3, account: LocalAccount, compiled_contract: Path, constructor_args: [dict | tuple] +) -> HexAddress: + """Deploy custom account 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 custom account. + + :param constructor_args: + Constructor arguments that can be provided via: + dictionary: {"_erc20": token_address} + tuple: tuple([token_address]) + + :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 deployment nonce + deployment_nonce = NonceHolder(zk_web3, account).get_deployment_nonce(account.address) + + # Precompute the address of smart contract + # Use this if there is a case where contract address should be known before deployment + deployer = PrecomputeContractDeployer(zk_web3) + precomputed_address = deployer.compute_l2_create_address(account.address, deployment_nonce) + + # Get contract ABI and bytecode information + token_contract = ContractEncoder.from_json(zk_web3, compiled_contract, JsonConfiguration.STANDARD) + + # Encode the constructor arguments + encoded_constructor = token_contract.encode_constructor(**constructor_args) + + # Get current gas price in Wei + gas_price = zk_web3.zksync.gas_price + + # Create deployment contract transaction + create_account = TxCreateAccount( + web3=zk_web3, + chain_id=chain_id, + nonce=nonce, + from_=account.address, + gas_price=gas_price, + bytecode=token_contract.bytecode, + call_data=encoded_constructor, + ) + + # ZkSync transaction gas estimation + estimate_gas = zk_web3.zksync.eth_estimate_gas(create_account.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_account.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"Contract address: {contract_address}") + + # Check does precompute address match with deployed address + if precomputed_address.lower() != contract_address.lower(): + raise RuntimeError("Precomputed contract address does now match with deployed contract address") + + return contract_address + + +if __name__ == "__main__": + # Set a provider + PROVIDER = "https://testnet.era.zksync.dev" + + # Byte-format private key + PRIVATE_KEY = bytes.fromhex(os.environ.get("PRIVATE_KEY")) + + # Connect to zkSync network + zk_web3 = ZkSyncBuilder.build(PROVIDER) + + # Get account object by providing from private key + account: LocalAccount = Account.from_key(PRIVATE_KEY) + + # Provide a compiled JSON source contract + contract_path = Path("solidity/custom_paymaster/build/Paymaster.json") + + # Crown token than can be minted for free + token_address = zk_web3.to_checksum_address("0xCd9BDa1d0FC539043D4C80103bdF4f9cb108931B") + constructor_arguments = {"_erc20": token_address} + + # Perform contract deployment + deploy_account(zk_web3, account, contract_path, constructor_arguments) diff --git a/examples/14_deploy_account_create2.py b/examples/14_deploy_account_create2.py new file mode 100644 index 0000000..8916f17 --- /dev/null +++ b/examples/14_deploy_account_create2.py @@ -0,0 +1,142 @@ +import os +from pathlib import Path + +from eth_account import Account +from eth_account.signers.local import LocalAccount +from eth_typing import HexAddress +from web3 import Web3 + +from zksync2.core.types import EthBlockParams +from zksync2.manage_contracts.contract_encoder_base import ContractEncoder, JsonConfiguration +from zksync2.manage_contracts.precompute_contract_deployer import PrecomputeContractDeployer +from zksync2.module.module_builder import ZkSyncBuilder +from zksync2.signer.eth_signer import PrivateKeyEthSigner +from zksync2.transaction.transaction_builders import TxCreate2Account + + +def generate_random_salt() -> bytes: + return os.urandom(32) + + +def deploy_account( + zk_web3: Web3, account: LocalAccount, compiled_contract: Path, constructor_args: [dict | tuple] +) -> HexAddress: + """Deploy custom account on zkSync network using create2() 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 custom account. + + :param constructor_args: + Constructor arguments that can be provided via: + dictionary: {"_erc20": token_address} + tuple: tuple([token_address]) + + :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 + ) + + # Deployment of same smart contract (same bytecode) without salt cannot be done twice + # Remove salt if you want to deploy contract only once + random_salt = generate_random_salt() + + # Precompute the address of smart contract + # Use this if there is a case where contract address should be known before deployment + deployer = PrecomputeContractDeployer(zk_web3) + + # Get contract ABI and bytecode information + token_contract = ContractEncoder.from_json(zk_web3, compiled_contract, JsonConfiguration.STANDARD) + + # Encode the constructor arguments + encoded_constructor = token_contract.encode_constructor(**constructor_args) + + # Get precomputed contract address + precomputed_address = deployer.compute_l2_create2_address(sender=account.address, + bytecode=token_contract.bytecode, + constructor=encoded_constructor, + salt=random_salt) + + # Get current gas price in Wei + gas_price = zk_web3.zksync.gas_price + + # Create2 account deployment transaction + create2_account = TxCreate2Account(web3=zk_web3, + chain_id=chain_id, + nonce=nonce, + from_=account.address, + gas_limit=0, + gas_price=gas_price, + bytecode=token_contract.bytecode, + salt=random_salt, + call_data=encoded_constructor) + + # ZkSync transaction gas estimation + estimate_gas = zk_web3.zksync.eth_estimate_gas(create2_account.tx) + print(f"Fee for transaction is: {Web3.from_wei(estimate_gas * gas_price, 'ether')} ETH") + + # Convert transaction to EIP-712 format + tx_712 = create2_account.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"Account address: {contract_address}") + + # Check does precompute address match with deployed address + if precomputed_address.lower() != contract_address.lower(): + raise RuntimeError("Precomputed contract address does now match with deployed contract address") + + return contract_address + + +if __name__ == "__main__": + # Set a provider + PROVIDER = "https://testnet.era.zksync.dev" + + # Byte-format private key + PRIVATE_KEY = bytes.fromhex(os.environ.get("PRIVATE_KEY")) + + # Connect to zkSync network + zk_web3 = ZkSyncBuilder.build(PROVIDER) + + # Get account object by providing from private key + account: LocalAccount = Account.from_key(PRIVATE_KEY) + + # Provide a compiled JSON source contract + contract_path = Path("solidity/custom_paymaster/build/Paymaster.json") + + # Crown token than can be minted for free + token_address = zk_web3.to_checksum_address("0xCd9BDa1d0FC539043D4C80103bdF4f9cb108931B") + constructor_arguments = {"_erc20": token_address} + + # Perform contract deployment + deploy_account(zk_web3, account, contract_path, constructor_arguments) diff --git a/examples/15_use_paymaster.py b/examples/15_use_paymaster.py new file mode 100644 index 0000000..d026f0b --- /dev/null +++ b/examples/15_use_paymaster.py @@ -0,0 +1,173 @@ +import json +import os +from pathlib import Path + +from eth_account import Account +from eth_account.signers.local import LocalAccount +from eth_typing import HexStr + +from zksync2.core.types import EthBlockParams, PaymasterParams +from zksync2.manage_contracts.paymaster_utils import PaymasterFlowEncoder +from zksync2.module.module_builder import ZkSyncBuilder +from zksync2.signer.eth_signer import PrivateKeyEthSigner +from zksync2.transaction.transaction_builders import TxFunctionCall + + +def get_abi_from_standard_json(standard_json: Path): + with standard_json.open(mode="r") as json_f: + return json.load(json_f)["abi"] + + +""" +This example demonstrates how to use a paymaster to facilitate fee payment with an ERC20 token. +The user initiates a mint transaction that is configured to be paid with an ERC20 token through the paymaster. +During transaction execution, the paymaster receives the ERC20 token from the user and covers the transaction fee using ETH. +""" +if __name__ == "__main__": + # Set a provider + PROVIDER = "https://testnet.era.zksync.dev" + + # Byte-format private key + PRIVATE_KEY = bytes.fromhex(os.environ.get("PRIVATE_KEY")) + + # Connect to zkSync network + zk_web3 = ZkSyncBuilder.build(PROVIDER) + + # Get account object by providing from private key + account: LocalAccount = Account.from_key(PRIVATE_KEY) + + # Crown token than can be minted for free + token_address = zk_web3.to_checksum_address("0xCd9BDa1d0FC539043D4C80103bdF4f9cb108931B") + # Paymaster for Crown token + paymaster_address = zk_web3.to_checksum_address("0xd660c2F92d3d0634e5A20f26821C43F1b09298fe") + + # Provide a compiled JSON source contract + token_path = Path("solidity/custom_paymaster/build/Token.json") + + token_contract = zk_web3.zksync.contract(token_address, abi=get_abi_from_standard_json(token_path)) + + # MINT TOKEN TO USER ACCOUNT (so user can pay fee with token) + balance = token_contract.functions.balanceOf(account.address).call() + print(f"Crown token balance before mint: {balance}") + + mint_tx = token_contract.functions.mint(account.address, 15).build_transaction({ + "nonce": zk_web3.zksync.get_transaction_count(account.address, EthBlockParams.LATEST.value), + "from": account.address, + "maxPriorityFeePerGas": 1_000_000, + "maxFeePerGas": zk_web3.zksync.gas_price, + }) + + signed = account.sign_transaction(mint_tx) + + # Send mint transaction to zkSync network + tx_hash = zk_web3.zksync.send_raw_transaction(signed.rawTransaction) + + tx_receipt = zk_web3.zksync.wait_for_transaction_receipt( + tx_hash, timeout=240, poll_latency=0.5 + ) + print(f"Tx status: {tx_receipt['status']}") + + balance = token_contract.functions.balanceOf(account.address).call() + print(f"Crown token balance after mint: {balance}") + + # SEND SOME ETH TO PAYMASTER (so it can pay fee with ETH) + + chain_id = zk_web3.zksync.chain_id + gas_price = zk_web3.zksync.gas_price + signer = PrivateKeyEthSigner(account, chain_id) + + tx_func_call = TxFunctionCall( + chain_id=zk_web3.zksync.chain_id, + nonce=zk_web3.zksync.get_transaction_count(account.address, EthBlockParams.LATEST.value), + from_=account.address, + to=paymaster_address, + value=zk_web3.to_wei(1, "ether"), + data=HexStr("0x"), + gas_limit=0, # Unknown at this state, estimation is done in next step + 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']}") + + # USE PAYMASTER TO PAY MINT TRANSACTION WITH CROWN TOKEN + + print(f"Paymaster balance before mint: " + f"{zk_web3.zksync.get_balance(account.address, EthBlockParams.LATEST.value)}") + print(f"User's Crown token balance before mint: {token_contract.functions.balanceOf(account.address).call()}") + print(f"Paymaster balance before mint: " + f"{zk_web3.zksync.get_balance(paymaster_address, EthBlockParams.LATEST.value)}") + print(f"Paymaster Crown token balance before mint: {token_contract.functions.balanceOf(paymaster_address).call()}") + + # Use the paymaster to pay mint transaction with token + calladata = token_contract.encodeABI(fn_name="mint", args=[account.address, 7]) + + # Create paymaster parameters + paymaster_params = PaymasterParams(**{ + "paymaster": paymaster_address, + "paymaster_input": zk_web3.to_bytes( + hexstr=PaymasterFlowEncoder(zk_web3).encode_approval_based(token_address, 1, b'')) + }) + + tx_func_call = TxFunctionCall( + chain_id=zk_web3.zksync.chain_id, + nonce=zk_web3.zksync.get_transaction_count(account.address, EthBlockParams.LATEST.value), + from_=account.address, + to=token_address, + data=calladata, + gas_limit=0, # Unknown at this state, estimation is done in next step + gas_price=gas_price, + max_priority_fee_per_gas=100_000_000, + paymaster_params=paymaster_params + ) + + # 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']}") + + print(f"Paymaster balance after mint: " + f"{zk_web3.zksync.get_balance(account.address, EthBlockParams.LATEST.value)}") + print(f"User's Crown token balance after mint: {token_contract.functions.balanceOf(account.address).call()}") + print(f"Paymaster balance after mint: " + f"{zk_web3.zksync.get_balance(paymaster_address, EthBlockParams.LATEST.value)}") + print(f"Paymaster Crown token balance after mint: {token_contract.functions.balanceOf(paymaster_address).call()}") diff --git a/examples/solidity/custom_paymaster/Paymaster.sol b/examples/solidity/custom_paymaster/Paymaster.sol new file mode 100644 index 0000000..db98ef2 --- /dev/null +++ b/examples/solidity/custom_paymaster/Paymaster.sol @@ -0,0 +1,119 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; + +import {IPaymaster, ExecutionResult, PAYMASTER_VALIDATION_SUCCESS_MAGIC} from "@matterlabs/zksync-contracts/l2/system-contracts/interfaces/IPaymaster.sol"; +import {IPaymasterFlow} from "@matterlabs/zksync-contracts/l2/system-contracts/interfaces/IPaymasterFlow.sol"; +import {TransactionHelper, Transaction} from "@matterlabs/zksync-contracts/l2/system-contracts/libraries/TransactionHelper.sol"; + +import "@matterlabs/zksync-contracts/l2/system-contracts/Constants.sol"; + +contract MyPaymaster is IPaymaster { + uint256 constant PRICE_FOR_PAYING_FEES = 1; + + address public allowedToken; + + modifier onlyBootloader() { + require( + msg.sender == BOOTLOADER_FORMAL_ADDRESS, + "Only bootloader can call this method" + ); + // Continue execution if called from the bootloader. + _; + } + + constructor(address _erc20) { + allowedToken = _erc20; + } + + function validateAndPayForPaymasterTransaction( + bytes32, + bytes32, + Transaction calldata _transaction + ) + external + payable + onlyBootloader + returns (bytes4 magic, bytes memory context) + { + // By default we consider the transaction as accepted. + magic = PAYMASTER_VALIDATION_SUCCESS_MAGIC; + require( + _transaction.paymasterInput.length >= 4, + "The standard paymaster input must be at least 4 bytes long" + ); + + bytes4 paymasterInputSelector = bytes4( + _transaction.paymasterInput[0:4] + ); + if (paymasterInputSelector == IPaymasterFlow.approvalBased.selector) { + // While the transaction data consists of address, uint256 and bytes data, + // the data is not needed for this paymaster + (address token, uint256 amount, bytes memory data) = abi.decode( + _transaction.paymasterInput[4:], + (address, uint256, bytes) + ); + + // Verify if token is the correct one + require(token == allowedToken, "Invalid token"); + + // We verify that the user has provided enough allowance + address userAddress = address(uint160(_transaction.from)); + + address thisAddress = address(this); + + uint256 providedAllowance = IERC20(token).allowance( + userAddress, + thisAddress + ); + require( + providedAllowance >= PRICE_FOR_PAYING_FEES, + "Min allowance too low" + ); + + // Note, that while the minimal amount of ETH needed is tx.gasPrice * tx.gasLimit, + // neither paymaster nor account are allowed to access this context variable. + uint256 requiredETH = _transaction.gasLimit * + _transaction.maxFeePerGas; + + try + IERC20(token).transferFrom(userAddress, thisAddress, amount) + {} catch (bytes memory revertReason) { + // If the revert reason is empty or represented by just a function selector, + // we replace the error with a more user-friendly message + if (revertReason.length <= 4) { + revert("Failed to transferFrom from users' account"); + } else { + assembly { + revert(add(0x20, revertReason), mload(revertReason)) + } + } + } + + // The bootloader never returns any data, so it can safely be ignored here. + (bool success, ) = payable(BOOTLOADER_FORMAL_ADDRESS).call{ + value: requiredETH + }(""); + require( + success, + "Failed to transfer tx fee to the bootloader. Paymaster balance might not be enough." + ); + } else { + revert("Unsupported paymaster flow"); + } + } + + function postTransaction( + bytes calldata _context, + Transaction calldata _transaction, + bytes32, + bytes32, + ExecutionResult _txResult, + uint256 _maxRefundedGas + ) external payable override onlyBootloader { + // Refunds are not supported yet. + } + + receive() external payable {} +} \ No newline at end of file diff --git a/examples/solidity/custom_paymaster/Token.sol b/examples/solidity/custom_paymaster/Token.sol new file mode 100644 index 0000000..cea8272 --- /dev/null +++ b/examples/solidity/custom_paymaster/Token.sol @@ -0,0 +1,26 @@ +// SPDX-License-Identifier: UNLICENSED + +pragma solidity ^0.8.0; + +import "@openzeppelin/contracts/token/ERC20/ERC20.sol"; + +contract Token is ERC20 { + uint8 private _decimals; + + constructor( + string memory name_, + string memory symbol_, + uint8 decimals_ + ) ERC20(name_, symbol_) { + _decimals = decimals_; + } + + function mint(address _to, uint256 _amount) public returns (bool) { + _mint(_to, _amount); + return true; + } + + function decimals() public view override returns (uint8) { + return _decimals; + } +} \ No newline at end of file diff --git a/examples/solidity/custom_paymaster/build/Paymaster.json b/examples/solidity/custom_paymaster/build/Paymaster.json new file mode 100644 index 0000000..106ff37 --- /dev/null +++ b/examples/solidity/custom_paymaster/build/Paymaster.json @@ -0,0 +1,276 @@ +{ + "_format": "hh-zksolc-artifact-1", + "contractName": "MyPaymaster", + "sourceName": "contracts/MyPaymaster.sol", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "_erc20", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [], + "name": "allowedToken", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "_context", + "type": "bytes" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "txType", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "from", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "to", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "gasLimit", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "gasPerPubdataByteLimit", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "maxFeePerGas", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "maxPriorityFeePerGas", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "paymaster", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "nonce", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + }, + { + "internalType": "uint256[4]", + "name": "reserved", + "type": "uint256[4]" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "signature", + "type": "bytes" + }, + { + "internalType": "bytes32[]", + "name": "factoryDeps", + "type": "bytes32[]" + }, + { + "internalType": "bytes", + "name": "paymasterInput", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "reservedDynamic", + "type": "bytes" + } + ], + "internalType": "struct Transaction", + "name": "_transaction", + "type": "tuple" + }, + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + }, + { + "internalType": "enum ExecutionResult", + "name": "_txResult", + "type": "uint8" + }, + { + "internalType": "uint256", + "name": "_maxRefundedGas", + "type": "uint256" + } + ], + "name": "postTransaction", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "txType", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "from", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "to", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "gasLimit", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "gasPerPubdataByteLimit", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "maxFeePerGas", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "maxPriorityFeePerGas", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "paymaster", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "nonce", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + }, + { + "internalType": "uint256[4]", + "name": "reserved", + "type": "uint256[4]" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "signature", + "type": "bytes" + }, + { + "internalType": "bytes32[]", + "name": "factoryDeps", + "type": "bytes32[]" + }, + { + "internalType": "bytes", + "name": "paymasterInput", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "reservedDynamic", + "type": "bytes" + } + ], + "internalType": "struct Transaction", + "name": "_transaction", + "type": "tuple" + } + ], + "name": "validateAndPayForPaymasterTransaction", + "outputs": [ + { + "internalType": "bytes4", + "name": "magic", + "type": "bytes4" + }, + { + "internalType": "bytes", + "name": "context", + "type": "bytes" + } + ], + "stateMutability": "payable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + } + ], + "bytecode": "0x0004000000000002000700000000000200000000030100190000006003300270000000ed0430019700030000004103550002000000010355000000ed0030019d000100000000001f0000000101200190000000340000c13d0000008001000039000000400010043f0000000002000031000000040120008c000000430000413d0000000201000367000000000301043b000000e003300270000000f30430009c0000007c0000613d000000f40430009c000000d40000613d000000f50130009c000000fc0000c13d0000000001000416000000000110004c000000fc0000c13d000000040100008a0000000001100031000000ef02000041000000000310004c00000000030000190000000003024019000000ef01100197000000000410004c000000000200a019000000ef0110009c00000000010300190000000001026019000000000110004c000000fc0000c13d000000000100041a000000f001100197000000400200043d0000000000120435000000ed01000041000000ed0320009c00000000010240190000004001100210000000f6011001c7000003ae0001042e0000000001000416000000000110004c000000fc0000c13d00000000010000310000009f02100039000000200300008a000000000232016f000000ee0320009c000000470000413d000001040100004100000000001004350000004101000039000000040010043f0000010501000041000003af00010430000000000120004c000000fc0000c13d0000000001000019000003ae0001042e000000400020043f0000001f0210018f00000002030003670000000504100272000000550000613d00000000050000190000000506500210000000000763034f000000000707043b000000800660003900000000007604350000000105500039000000000645004b0000004d0000413d000000000520004c000000640000613d0000000504400210000000000343034f00000003022002100000008004400039000000000504043300000000052501cf000000000525022f000000000303043b0000010002200089000000000323022f00000000022301cf000000000252019f0000000000240435000000ef02000041000000200310008c00000000030000190000000003024019000000ef01100197000000000410004c000000000200a019000000ef0110009c00000000010300190000000001026019000000000110004c000000fc0000c13d000000800100043d000000f00210009c000000fc0000213d000000000200041a000000f102200197000000000112019f000000000010041b000000200100003900000100001004430000012000000443000000f201000041000003ae0001042e000000040320008a000000ef04000041000000600530008c00000000050000190000000005044019000000ef03300197000000000630004c000000000400a019000000ef0330009c00000000030500190000000003046019000000000330004c000000fc0000c13d0000004403100370000000000a03043b000000f703a0009c000000fc0000213d0000000403a000390000000004320049000000ef05000041000002600640008c00000000060000190000000006054019000000ef04400197000000000740004c000000000500a019000000ef0440009c00000000040600190000000004056019000000000440004c000000fc0000c13d0000000004000411000080010440008c000000fe0000c13d0000022404a00039000000000441034f0000000005a20049000000230550008a000000000404043b000000ef06000041000000000754004b00000000070000190000000007068019000000ef05500197000000ef08400197000000000958004b0000000006008019000000000558013f000000ef0550009c00000000050700190000000005066019000000000550004c000000fc0000c13d0000000003340019000000000431034f000000000404043b000000f70540009c000000fc0000213d00000000054200490000002002300039000000ef06000041000000000752004b00000000070000190000000007062019000000ef05500197000000ef08200197000000000958004b0000000006008019000000000558013f000000ef0550009c00000000050700190000000005066019000000000550004c000000fc0000c13d000000030540008c000001220000213d000000f801000041000000800010043f0000002001000039000000840010043f0000003a01000039000000a40010043f0000010a01000041000000c40010043f0000010b01000041000000e40010043f000000fb01000041000003af00010430000000040320008a000000ef04000041000000c00530008c00000000050000190000000005044019000000ef06300197000000000760004c000000000400a019000000ef0660009c000000000405c019000000000440004c000000fc0000c13d0000000404100370000000000404043b000000f70540009c000000fc0000213d0000002305400039000000ef06000041000000000725004b00000000070000190000000007068019000000ef08200197000000ef05500197000000000985004b0000000006008019000000000585013f000000ef0550009c00000000050700190000000005066019000000000550004c000000fc0000c13d0000000405400039000000000551034f000000000505043b000000f70650009c000000fc0000213d00000000045400190000002404400039000000000224004b0000010a0000a13d0000000001000019000003af00010430000000f801000041000000800010043f0000002001000039000000840010043f0000002401000039000000a40010043f000000f901000041000000c40010043f000000fa01000041000000e40010043f000000fb01000041000003af000104300000002402100370000000000202043b000000f70420009c000000fc0000213d0000000002230049000000ef03000041000002600420008c00000000040000190000000004034019000000ef02200197000000000520004c000000000300a019000000ef0220009c00000000020400190000000002036019000000000220004c000000fc0000c13d0000008401100370000000000101043b000000010110008c000000fc0000213d03ad038a0000040f0000000001000019000003ae0001042e000000000221034f000000000202043b000000fc02200197000000fd0220009c000001970000c13d000000040240008a000000600420008c000000fc0000413d0000002404300039000000000541034f000000000505043b000700000005001d000000f00550009c000000fc0000213d0000006405300039000000000551034f0000004403300039000000000331034f000000000303043b000600000003001d000000000305043b000000f70530009c000000fc0000213d000000000242001900000000034300190000001f04300039000000ef05000041000000000624004b00000000060000190000000006058019000000ef04400197000000ef07200197000000000874004b0000000005008019000000000474013f000000ef0440009c00000000040600190000000004056019000000000440004c000000fc0000c13d00050000000a001d000000000131034f000000000101043b000000f70410009c0000003d0000213d000000bf04100039000000200500008a000000000454016f000000f70540009c0000003d0000213d000000400040043f000000800010043f00000020033000390000000004310019000000000224004b000000fc0000213d0000001f0210018f00000002033003670000000504100272000001670000613d00000000050000190000000506500210000000000763034f000000000707043b000000a00660003900000000007604350000000105500039000000000645004b0000015f0000413d000000000520004c000001760000613d0000000504400210000000000343034f0000000302200210000000a004400039000000000504043300000000052501cf000000000525022f000000000303043b0000010002200089000000000323022f00000000022301cf000000000252019f0000000000240435000000a0011000390000000000010435000000000100041a000000f0011001970000000702000029000000000112004b000001a10000c13d000000050100002900000024011000390000000201100367000000000101043b000000400400043d000001020200004100000000002404350000000002000410000000f0032001970000002402400039000100000003001d0000000000320435000000f002100197000400000004001d0000000401400039000200000002001d000000000021043500000000010004140000000702000029000000040220008c000001b30000c13d0000000103000031000000200130008c00000020040000390000000004034019000001e60000013d000000f801000041000000800010043f0000002001000039000000840010043f0000001a01000039000000a40010043f000000fe01000041000000c40010043f000000ff01000041000003af00010430000000400100043d00000044021000390000010003000041000000000032043500000024021000390000000d030000390000000000320435000000f8020000410000000000210435000000040210003900000020030000390000000000320435000000ed02000041000000ed0310009c0000000001028019000000400110021000000101011001c7000003af00010430000000ed02000041000000ed0310009c00000000010280190000000404000029000000ed0340009c00000000020440190000004002200210000000c001100210000000000121019f00000103011001c7000000070200002903ad03a80000040f000000040a00002900000000030100190000006003300270000000ed03300197000000200430008c000000200400003900000000040340190000001f0540018f0000000506400272000001d20000613d0000000007000019000000050870021000000000098a0019000000000881034f000000000808043b00000000008904350000000107700039000000000867004b000001ca0000413d000000000750004c000001e20000613d0000000506600210000000000761034f000000040800002900000000066800190000000305500210000000000806043300000000085801cf000000000858022f000000000707043b0000010005500089000000000757022f00000000055701cf000000000585019f0000000000560435000100000003001f000300000001035500000001022001900000020c0000613d0000001f01400039000000600110018f00000004020000290000000002210019000000000112004b00000000010000190000000101004039000300000002001d000000f70220009c0000003d0000213d00000001011001900000003d0000c13d0000000301000029000000400010043f000000200130008c000000fc0000413d00000004010000290000000001010433000000000110004c000002320000c13d0000000303000029000000440130003900000109020000410000000000210435000000240130003900000015020000390000000000210435000000f8010000410000000000130435000000040130003900000020020000390000000000210435000000ed01000041000000ed0230009c0000000001034019000000400110021000000101011001c7000003af00010430000000400200043d0000001f0430018f0000000503300272000002190000613d000000000500001900000005065002100000000007620019000000000661034f000000000606043b00000000006704350000000105500039000000000635004b000002110000413d000000000540004c000002280000613d0000000503300210000000000131034f00000000033200190000000304400210000000000503043300000000054501cf000000000545022f000000000101043b0000010004400089000000000141022f00000000014101cf000000000151019f0000000000130435000000ed010000410000000103000031000000ed0430009c0000000003018019000000ed0420009c000000000102401900000040011002100000006002300210000000000112019f000003af00010430000000050400002900000064014000390000000202000367000000000312034f000000a401400039000000000112034f000000000101043b000000000203043b00000000341200a9000500000004001d000000000320004c000002420000613d000000050300002900000000322300d9000000000112004b000002c10000c13d00000003030000290000004401300039000000060200002900000000002104350000002401300039000000010200002900000000002104350000010601000041000000000013043500000004013000390000000202000029000000000021043500000000010004140000000702000029000000040220008c000002570000c13d0000000103000031000000200130008c000000200400003900000000040340190000028a0000013d000000ed02000041000000ed0310009c00000000010280190000000304000029000000ed0340009c00000000020440190000004002200210000000c001100210000000000121019f00000101011001c7000000070200002903ad03a30000040f000000030a00002900000000030100190000006003300270000000ed03300197000000200430008c000000200400003900000000040340190000001f0540018f0000000506400272000002760000613d0000000007000019000000050870021000000000098a0019000000000881034f000000000808043b00000000008904350000000107700039000000000867004b0000026e0000413d000000000750004c000002860000613d0000000506600210000000000761034f000000030800002900000000066800190000000305500210000000000806043300000000085801cf000000000858022f000000000707043b0000010005500089000000000757022f00000000055701cf000000000585019f0000000000560435000100000003001f00030000000103550000000101200190000002c70000613d0000001f01400039000000600110018f00000003020000290000000001210019000000f70210009c0000003d0000213d000000400010043f000000200130008c000000fc0000413d00000003010000290000000001010433000000000210004c0000000002000019000000010200c039000000000121004b000000fc0000c13d000000ed03000041000700000003001d0000000001000414000000ed0210009c0000000001038019000000c00110021000000108021001c70000000503000029000000000430004c000000000102c019000080090200003900008001020060390000800104000039000000000500001903ad03a30000040f000600000002001d00000000020100190000006002200270000100ed0020019d000300000001035503ad032b0000040f0000000601000029000000010110018f03ad036f0000040f000000400100043d000600000001001d03ad03110000040f00000006040000290000000001410049000000ed0210009c00000007030000290000000001038019000000ed0240009c0000000002030019000000000204401900000040022002100000006001100210000000000121019f000003ae0001042e000001040100004100000000001004350000001101000039000000040010043f0000010501000041000003af000104300000006001000039000000000230004c000002f40000613d0000003f013000390000010702100197000000400100043d0000000002210019000000000412004b00000000040000190000000104004039000000f70520009c0000003d0000213d00000001044001900000003d0000c13d000000400020043f0000000002310436000000030300036700000001050000310000001f0450018f0000000505500272000002e50000613d000000000600001900000005076002100000000008720019000000000773034f000000000707043b00000000007804350000000106600039000000000756004b000002dd0000413d000000000640004c000002f40000613d0000000505500210000000000353034f00000000025200190000000304400210000000000502043300000000054501cf000000000545022f000000000303043b0000010004400089000000000343022f00000000034301cf000000000353019f00000000003204350000000021010434000000050310008c000003000000413d000000ed03000041000000ed0420009c0000000002038019000000ed0410009c000000000103801900000060011002100000004002200210000000000121019f000003af00010430000000400200043d000700000002001d000000f8010000410000000000120435000000040120003903ad03620000040f00000007040000290000000001410049000000ed02000041000000ed0310009c0000000001028019000000ed0340009c000000000204401900000040022002100000006001100210000000000121019f000003af000104300000002002100039000000400300003900000000003204350000010c0200004100000000002104350000004003100039000000600200043d00000000002304350000006001100039000000000320004c000003240000613d000000000300001900000000043100190000008005300039000000000505043300000000005404350000002003300039000000000423004b0000031d0000413d000000000321001900000000000304350000001f02200039000000200300008a000000000232016f0000000001210019000000000001042d000000600100003900000001020000320000035b0000613d000000ee0120009c0000035c0000813d0000003f01200039000000200300008a000000000331016f000000400100043d0000000003310019000000000413004b00000000040000190000000104004039000000f70530009c0000035c0000213d00000001044001900000035c0000c13d000000400030043f0000000002210436000000030300036700000001050000310000001f0450018f00000005055002720000034c0000613d000000000600001900000005076002100000000008720019000000000773034f000000000707043b00000000007804350000000106600039000000000756004b000003440000413d000000000640004c0000035b0000613d0000000505500210000000000353034f00000000025200190000000304400210000000000502043300000000054501cf000000000545022f000000000303043b0000010004400089000000000343022f00000000034301cf000000000353019f0000000000320435000000000001042d000001040100004100000000001004350000004101000039000000040010043f0000010501000041000003af0001043000000060021000390000010d03000041000000000032043500000040021000390000010e03000041000000000032043500000020021000390000002a030000390000000000320435000000200200003900000000002104350000008001100039000000000001042d000000000110004c000003720000613d000000000001042d000000400100043d00000084021000390000010f030000410000000000320435000000640210003900000110030000410000000000320435000000440210003900000111030000410000000000320435000000240210003900000053030000390000000000320435000000f8020000410000000000210435000000040210003900000020030000390000000000320435000000ed02000041000000ed0310009c0000000001028019000000400110021000000112011001c7000003af000104300000000001000411000080010110008c0000038e0000c13d000000000001042d000000400100043d0000006402100039000000fa0300004100000000003204350000004402100039000000f9030000410000000000320435000000240210003900000024030000390000000000320435000000f8020000410000000000210435000000040210003900000020030000390000000000320435000000ed02000041000000ed0310009c0000000001028019000000400110021000000113011001c7000003af00010430000003a6002104210000000102000039000000000001042d0000000002000019000000000001042d000003ab002104230000000102000039000000000001042d0000000002000019000000000001042d000003ad00000432000003ae0001042e000003af00010430000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffff00000000000000000000000000000000000000000000000100000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000000000000000000000000000000000020000000000000000000000000000004000000100000000000000000000000000000000000000000000000000000000000000000000000000038a24bc00000000000000000000000000000000000000000000000000000000817b17f00000000000000000000000000000000000000000000000000000000085fa292f0000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffff08c379a0000000000000000000000000000000000000000000000000000000004f6e6c7920626f6f746c6f616465722063616e2063616c6c2074686973206d6574686f64000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000084000000800000000000000000ffffffff00000000000000000000000000000000000000000000000000000000949431dc00000000000000000000000000000000000000000000000000000000556e737570706f72746564207061796d617374657220666c6f770000000000000000000000000000000000000000000000000064000000800000000000000000496e76616c696420746f6b656e000000000000000000000000000000000000000000000000000000000000000000000000000064000000000000000000000000dd62ed3e0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000440000000000000000000000004e487b7100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002400000000000000000000000023b872dd0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001ffffffe002000000000000000000000000000000000000000000000000000000000000004d696e20616c6c6f77616e636520746f6f206c6f770000000000000000000000546865207374616e64617264207061796d617374657220696e707574206d757374206265206174206c656173742034206279746573206c6f6e67000000000000038a24bc000000000000000000000000000000000000000000000000000000007327206163636f756e74000000000000000000000000000000000000000000004661696c656420746f207472616e7366657246726f6d2066726f6d207573657269676874206e6f7420626520656e6f7567682e0000000000000000000000000020626f6f746c6f616465722e205061796d61737465722062616c616e6365206d4661696c656420746f207472616e736665722074782066656520746f2074686500000000000000000000000000000000000000a40000000000000000000000000000000000000000000000000000000000000084000000000000000000000000434a265b4e19f3e86ad50cc06218d532431413c7e6ec41818ab568730a6a8c79", + "deployedBytecode": "0x0004000000000002000700000000000200000000030100190000006003300270000000ed0430019700030000004103550002000000010355000000ed0030019d000100000000001f0000000101200190000000340000c13d0000008001000039000000400010043f0000000002000031000000040120008c000000430000413d0000000201000367000000000301043b000000e003300270000000f30430009c0000007c0000613d000000f40430009c000000d40000613d000000f50130009c000000fc0000c13d0000000001000416000000000110004c000000fc0000c13d000000040100008a0000000001100031000000ef02000041000000000310004c00000000030000190000000003024019000000ef01100197000000000410004c000000000200a019000000ef0110009c00000000010300190000000001026019000000000110004c000000fc0000c13d000000000100041a000000f001100197000000400200043d0000000000120435000000ed01000041000000ed0320009c00000000010240190000004001100210000000f6011001c7000003ae0001042e0000000001000416000000000110004c000000fc0000c13d00000000010000310000009f02100039000000200300008a000000000232016f000000ee0320009c000000470000413d000001040100004100000000001004350000004101000039000000040010043f0000010501000041000003af00010430000000000120004c000000fc0000c13d0000000001000019000003ae0001042e000000400020043f0000001f0210018f00000002030003670000000504100272000000550000613d00000000050000190000000506500210000000000763034f000000000707043b000000800660003900000000007604350000000105500039000000000645004b0000004d0000413d000000000520004c000000640000613d0000000504400210000000000343034f00000003022002100000008004400039000000000504043300000000052501cf000000000525022f000000000303043b0000010002200089000000000323022f00000000022301cf000000000252019f0000000000240435000000ef02000041000000200310008c00000000030000190000000003024019000000ef01100197000000000410004c000000000200a019000000ef0110009c00000000010300190000000001026019000000000110004c000000fc0000c13d000000800100043d000000f00210009c000000fc0000213d000000000200041a000000f102200197000000000112019f000000000010041b000000200100003900000100001004430000012000000443000000f201000041000003ae0001042e000000040320008a000000ef04000041000000600530008c00000000050000190000000005044019000000ef03300197000000000630004c000000000400a019000000ef0330009c00000000030500190000000003046019000000000330004c000000fc0000c13d0000004403100370000000000a03043b000000f703a0009c000000fc0000213d0000000403a000390000000004320049000000ef05000041000002600640008c00000000060000190000000006054019000000ef04400197000000000740004c000000000500a019000000ef0440009c00000000040600190000000004056019000000000440004c000000fc0000c13d0000000004000411000080010440008c000000fe0000c13d0000022404a00039000000000441034f0000000005a20049000000230550008a000000000404043b000000ef06000041000000000754004b00000000070000190000000007068019000000ef05500197000000ef08400197000000000958004b0000000006008019000000000558013f000000ef0550009c00000000050700190000000005066019000000000550004c000000fc0000c13d0000000003340019000000000431034f000000000404043b000000f70540009c000000fc0000213d00000000054200490000002002300039000000ef06000041000000000752004b00000000070000190000000007062019000000ef05500197000000ef08200197000000000958004b0000000006008019000000000558013f000000ef0550009c00000000050700190000000005066019000000000550004c000000fc0000c13d000000030540008c000001220000213d000000f801000041000000800010043f0000002001000039000000840010043f0000003a01000039000000a40010043f0000010a01000041000000c40010043f0000010b01000041000000e40010043f000000fb01000041000003af00010430000000040320008a000000ef04000041000000c00530008c00000000050000190000000005044019000000ef06300197000000000760004c000000000400a019000000ef0660009c000000000405c019000000000440004c000000fc0000c13d0000000404100370000000000404043b000000f70540009c000000fc0000213d0000002305400039000000ef06000041000000000725004b00000000070000190000000007068019000000ef08200197000000ef05500197000000000985004b0000000006008019000000000585013f000000ef0550009c00000000050700190000000005066019000000000550004c000000fc0000c13d0000000405400039000000000551034f000000000505043b000000f70650009c000000fc0000213d00000000045400190000002404400039000000000224004b0000010a0000a13d0000000001000019000003af00010430000000f801000041000000800010043f0000002001000039000000840010043f0000002401000039000000a40010043f000000f901000041000000c40010043f000000fa01000041000000e40010043f000000fb01000041000003af000104300000002402100370000000000202043b000000f70420009c000000fc0000213d0000000002230049000000ef03000041000002600420008c00000000040000190000000004034019000000ef02200197000000000520004c000000000300a019000000ef0220009c00000000020400190000000002036019000000000220004c000000fc0000c13d0000008401100370000000000101043b000000010110008c000000fc0000213d03ad038a0000040f0000000001000019000003ae0001042e000000000221034f000000000202043b000000fc02200197000000fd0220009c000001970000c13d000000040240008a000000600420008c000000fc0000413d0000002404300039000000000541034f000000000505043b000700000005001d000000f00550009c000000fc0000213d0000006405300039000000000551034f0000004403300039000000000331034f000000000303043b000600000003001d000000000305043b000000f70530009c000000fc0000213d000000000242001900000000034300190000001f04300039000000ef05000041000000000624004b00000000060000190000000006058019000000ef04400197000000ef07200197000000000874004b0000000005008019000000000474013f000000ef0440009c00000000040600190000000004056019000000000440004c000000fc0000c13d00050000000a001d000000000131034f000000000101043b000000f70410009c0000003d0000213d000000bf04100039000000200500008a000000000454016f000000f70540009c0000003d0000213d000000400040043f000000800010043f00000020033000390000000004310019000000000224004b000000fc0000213d0000001f0210018f00000002033003670000000504100272000001670000613d00000000050000190000000506500210000000000763034f000000000707043b000000a00660003900000000007604350000000105500039000000000645004b0000015f0000413d000000000520004c000001760000613d0000000504400210000000000343034f0000000302200210000000a004400039000000000504043300000000052501cf000000000525022f000000000303043b0000010002200089000000000323022f00000000022301cf000000000252019f0000000000240435000000a0011000390000000000010435000000000100041a000000f0011001970000000702000029000000000112004b000001a10000c13d000000050100002900000024011000390000000201100367000000000101043b000000400400043d000001020200004100000000002404350000000002000410000000f0032001970000002402400039000100000003001d0000000000320435000000f002100197000400000004001d0000000401400039000200000002001d000000000021043500000000010004140000000702000029000000040220008c000001b30000c13d0000000103000031000000200130008c00000020040000390000000004034019000001e60000013d000000f801000041000000800010043f0000002001000039000000840010043f0000001a01000039000000a40010043f000000fe01000041000000c40010043f000000ff01000041000003af00010430000000400100043d00000044021000390000010003000041000000000032043500000024021000390000000d030000390000000000320435000000f8020000410000000000210435000000040210003900000020030000390000000000320435000000ed02000041000000ed0310009c0000000001028019000000400110021000000101011001c7000003af00010430000000ed02000041000000ed0310009c00000000010280190000000404000029000000ed0340009c00000000020440190000004002200210000000c001100210000000000121019f00000103011001c7000000070200002903ad03a80000040f000000040a00002900000000030100190000006003300270000000ed03300197000000200430008c000000200400003900000000040340190000001f0540018f0000000506400272000001d20000613d0000000007000019000000050870021000000000098a0019000000000881034f000000000808043b00000000008904350000000107700039000000000867004b000001ca0000413d000000000750004c000001e20000613d0000000506600210000000000761034f000000040800002900000000066800190000000305500210000000000806043300000000085801cf000000000858022f000000000707043b0000010005500089000000000757022f00000000055701cf000000000585019f0000000000560435000100000003001f000300000001035500000001022001900000020c0000613d0000001f01400039000000600110018f00000004020000290000000002210019000000000112004b00000000010000190000000101004039000300000002001d000000f70220009c0000003d0000213d00000001011001900000003d0000c13d0000000301000029000000400010043f000000200130008c000000fc0000413d00000004010000290000000001010433000000000110004c000002320000c13d0000000303000029000000440130003900000109020000410000000000210435000000240130003900000015020000390000000000210435000000f8010000410000000000130435000000040130003900000020020000390000000000210435000000ed01000041000000ed0230009c0000000001034019000000400110021000000101011001c7000003af00010430000000400200043d0000001f0430018f0000000503300272000002190000613d000000000500001900000005065002100000000007620019000000000661034f000000000606043b00000000006704350000000105500039000000000635004b000002110000413d000000000540004c000002280000613d0000000503300210000000000131034f00000000033200190000000304400210000000000503043300000000054501cf000000000545022f000000000101043b0000010004400089000000000141022f00000000014101cf000000000151019f0000000000130435000000ed010000410000000103000031000000ed0430009c0000000003018019000000ed0420009c000000000102401900000040011002100000006002300210000000000112019f000003af00010430000000050400002900000064014000390000000202000367000000000312034f000000a401400039000000000112034f000000000101043b000000000203043b00000000341200a9000500000004001d000000000320004c000002420000613d000000050300002900000000322300d9000000000112004b000002c10000c13d00000003030000290000004401300039000000060200002900000000002104350000002401300039000000010200002900000000002104350000010601000041000000000013043500000004013000390000000202000029000000000021043500000000010004140000000702000029000000040220008c000002570000c13d0000000103000031000000200130008c000000200400003900000000040340190000028a0000013d000000ed02000041000000ed0310009c00000000010280190000000304000029000000ed0340009c00000000020440190000004002200210000000c001100210000000000121019f00000101011001c7000000070200002903ad03a30000040f000000030a00002900000000030100190000006003300270000000ed03300197000000200430008c000000200400003900000000040340190000001f0540018f0000000506400272000002760000613d0000000007000019000000050870021000000000098a0019000000000881034f000000000808043b00000000008904350000000107700039000000000867004b0000026e0000413d000000000750004c000002860000613d0000000506600210000000000761034f000000030800002900000000066800190000000305500210000000000806043300000000085801cf000000000858022f000000000707043b0000010005500089000000000757022f00000000055701cf000000000585019f0000000000560435000100000003001f00030000000103550000000101200190000002c70000613d0000001f01400039000000600110018f00000003020000290000000001210019000000f70210009c0000003d0000213d000000400010043f000000200130008c000000fc0000413d00000003010000290000000001010433000000000210004c0000000002000019000000010200c039000000000121004b000000fc0000c13d000000ed03000041000700000003001d0000000001000414000000ed0210009c0000000001038019000000c00110021000000108021001c70000000503000029000000000430004c000000000102c019000080090200003900008001020060390000800104000039000000000500001903ad03a30000040f000600000002001d00000000020100190000006002200270000100ed0020019d000300000001035503ad032b0000040f0000000601000029000000010110018f03ad036f0000040f000000400100043d000600000001001d03ad03110000040f00000006040000290000000001410049000000ed0210009c00000007030000290000000001038019000000ed0240009c0000000002030019000000000204401900000040022002100000006001100210000000000121019f000003ae0001042e000001040100004100000000001004350000001101000039000000040010043f0000010501000041000003af000104300000006001000039000000000230004c000002f40000613d0000003f013000390000010702100197000000400100043d0000000002210019000000000412004b00000000040000190000000104004039000000f70520009c0000003d0000213d00000001044001900000003d0000c13d000000400020043f0000000002310436000000030300036700000001050000310000001f0450018f0000000505500272000002e50000613d000000000600001900000005076002100000000008720019000000000773034f000000000707043b00000000007804350000000106600039000000000756004b000002dd0000413d000000000640004c000002f40000613d0000000505500210000000000353034f00000000025200190000000304400210000000000502043300000000054501cf000000000545022f000000000303043b0000010004400089000000000343022f00000000034301cf000000000353019f00000000003204350000000021010434000000050310008c000003000000413d000000ed03000041000000ed0420009c0000000002038019000000ed0410009c000000000103801900000060011002100000004002200210000000000121019f000003af00010430000000400200043d000700000002001d000000f8010000410000000000120435000000040120003903ad03620000040f00000007040000290000000001410049000000ed02000041000000ed0310009c0000000001028019000000ed0340009c000000000204401900000040022002100000006001100210000000000121019f000003af000104300000002002100039000000400300003900000000003204350000010c0200004100000000002104350000004003100039000000600200043d00000000002304350000006001100039000000000320004c000003240000613d000000000300001900000000043100190000008005300039000000000505043300000000005404350000002003300039000000000423004b0000031d0000413d000000000321001900000000000304350000001f02200039000000200300008a000000000232016f0000000001210019000000000001042d000000600100003900000001020000320000035b0000613d000000ee0120009c0000035c0000813d0000003f01200039000000200300008a000000000331016f000000400100043d0000000003310019000000000413004b00000000040000190000000104004039000000f70530009c0000035c0000213d00000001044001900000035c0000c13d000000400030043f0000000002210436000000030300036700000001050000310000001f0450018f00000005055002720000034c0000613d000000000600001900000005076002100000000008720019000000000773034f000000000707043b00000000007804350000000106600039000000000756004b000003440000413d000000000640004c0000035b0000613d0000000505500210000000000353034f00000000025200190000000304400210000000000502043300000000054501cf000000000545022f000000000303043b0000010004400089000000000343022f00000000034301cf000000000353019f0000000000320435000000000001042d000001040100004100000000001004350000004101000039000000040010043f0000010501000041000003af0001043000000060021000390000010d03000041000000000032043500000040021000390000010e03000041000000000032043500000020021000390000002a030000390000000000320435000000200200003900000000002104350000008001100039000000000001042d000000000110004c000003720000613d000000000001042d000000400100043d00000084021000390000010f030000410000000000320435000000640210003900000110030000410000000000320435000000440210003900000111030000410000000000320435000000240210003900000053030000390000000000320435000000f8020000410000000000210435000000040210003900000020030000390000000000320435000000ed02000041000000ed0310009c0000000001028019000000400110021000000112011001c7000003af000104300000000001000411000080010110008c0000038e0000c13d000000000001042d000000400100043d0000006402100039000000fa0300004100000000003204350000004402100039000000f9030000410000000000320435000000240210003900000024030000390000000000320435000000f8020000410000000000210435000000040210003900000020030000390000000000320435000000ed02000041000000ed0310009c0000000001028019000000400110021000000113011001c7000003af00010430000003a6002104210000000102000039000000000001042d0000000002000019000000000001042d000003ab002104230000000102000039000000000001042d0000000002000019000000000001042d000003ad00000432000003ae0001042e000003af00010430000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffff00000000000000000000000000000000000000000000000100000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000000000000000000000000000000000020000000000000000000000000000004000000100000000000000000000000000000000000000000000000000000000000000000000000000038a24bc00000000000000000000000000000000000000000000000000000000817b17f00000000000000000000000000000000000000000000000000000000085fa292f0000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffff08c379a0000000000000000000000000000000000000000000000000000000004f6e6c7920626f6f746c6f616465722063616e2063616c6c2074686973206d6574686f64000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000084000000800000000000000000ffffffff00000000000000000000000000000000000000000000000000000000949431dc00000000000000000000000000000000000000000000000000000000556e737570706f72746564207061796d617374657220666c6f770000000000000000000000000000000000000000000000000064000000800000000000000000496e76616c696420746f6b656e000000000000000000000000000000000000000000000000000000000000000000000000000064000000000000000000000000dd62ed3e0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000440000000000000000000000004e487b7100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002400000000000000000000000023b872dd0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001ffffffe002000000000000000000000000000000000000000000000000000000000000004d696e20616c6c6f77616e636520746f6f206c6f770000000000000000000000546865207374616e64617264207061796d617374657220696e707574206d757374206265206174206c656173742034206279746573206c6f6e67000000000000038a24bc000000000000000000000000000000000000000000000000000000007327206163636f756e74000000000000000000000000000000000000000000004661696c656420746f207472616e7366657246726f6d2066726f6d207573657269676874206e6f7420626520656e6f7567682e0000000000000000000000000020626f6f746c6f616465722e205061796d61737465722062616c616e6365206d4661696c656420746f207472616e736665722074782066656520746f2074686500000000000000000000000000000000000000a40000000000000000000000000000000000000000000000000000000000000084000000000000000000000000434a265b4e19f3e86ad50cc06218d532431413c7e6ec41818ab568730a6a8c79", + "linkReferences": {}, + "deployedLinkReferences": {}, + "factoryDeps": {} +} diff --git a/examples/solidity/custom_paymaster/build/Token.json b/examples/solidity/custom_paymaster/build/Token.json new file mode 100644 index 0000000..de8a6c6 --- /dev/null +++ b/examples/solidity/custom_paymaster/build/Token.json @@ -0,0 +1,327 @@ +{ + "_format": "hh-zksolc-artifact-1", + "contractName": "Token", + "sourceName": "contracts/Token.sol", + "abi": [ + { + "inputs": [ + { + "internalType": "string", + "name": "name_", + "type": "string" + }, + { + "internalType": "string", + "name": "symbol_", + "type": "string" + }, + { + "internalType": "uint8", + "name": "decimals_", + "type": "uint8" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Approval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "address", + "name": "spender", + "type": "address" + } + ], + "name": "allowance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "approve", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "balanceOf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "decimals", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "subtractedValue", + "type": "uint256" + } + ], + "name": "decreaseAllowance", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "addedValue", + "type": "uint256" + } + ], + "name": "increaseAllowance", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "mint", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "name", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "symbol", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "transfer", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "transferFrom", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + } + ], + "bytecode": "0x0002000000000002000900000000000200010000000103550000006001100270000001980010019d0000008001000039000000400010043f0000000101200190000000340000c13d0000000001000031000000040110008c000003670000413d0000000101000367000000000101043b000000e0011002700000019d0210009c000001420000213d000001a50210009c000001720000213d000001a90210009c000001fd0000613d000001aa0210009c000002210000613d000001ab0110009c000003670000c13d0000000001000416000000000110004c000003670000c13d000000040100008a00000000011000310000019a02000041000000000310004c000000000300001900000000030240190000019a01100197000000000410004c000000000200a0190000019a0110009c00000000010300190000000001026019000000000110004c000003670000c13d0000000201000039000000000101041a000000400200043d00000000001204350000019801000041000001980320009c00000000010240190000004001100210000001ad011001c70000065c0001042e0000000001000416000000000110004c000003670000c13d00000000020000310000001f01200039000000200a00008a0000000004a1016f000000400100043d0000000003140019000000000443004b00000000040000190000000104004039000001990530009c000003c90000213d0000000104400190000003c90000c13d000000400030043f0000001f0320018f00000001040003670000000505200272000000520000613d000000000600001900000005076002100000000008710019000000000774034f000000000707043b00000000007804350000000106600039000000000756004b0000004a0000413d000000000630004c000000610000613d0000000505500210000000000454034f00000000055100190000000303300210000000000605043300000000063601cf000000000636022f000000000404043b0000010003300089000000000434022f00000000033401cf000000000363019f00000000003504350000019a03000041000000600420008c000000000400001900000000040340190000019a05200197000000000650004c000000000300a0190000019a0550009c000000000304c019000000000330004c000003670000c13d0000000034010434000001990540009c000003670000213d000000000221001900000000041400190000001f054000390000019a06000041000000000725004b000000000700001900000000070680190000019a055001970000019a08200197000000000985004b0000000006008019000000000585013f0000019a0550009c00000000050700190000000005066019000000000550004c000003670000c13d0000000005040433000001990650009c000003c90000213d0000003f065000390000000006a6016f000000400b00043d00000000066b00190000000007b6004b00000000070000190000000107004039000001990860009c000003c90000213d0000000107700190000003c90000c13d000000400060043f000000000c5b043600000020065000390000000007460019000000000727004b000003670000213d000000000750004c0000009e0000613d000000000700001900000020077000390000000008b70019000000000947001900000000090904330000000000980435000000000857004b000000970000413d00000000046b001900000000000404350000000003030433000001990430009c000003670000213d00000000031300190000001f043000390000019a05000041000000000624004b000000000600001900000000060580190000019a044001970000019a07200197000000000874004b0000000005008019000000000474013f0000019a0440009c00000000040600190000000004056019000000000440004c000003670000c13d0000000004030433000001990540009c000003c90000213d0000003f054000390000000005a5016f000000400800043d0000000005580019000000000685004b00000000060000190000000106004039000001990750009c000003c90000213d0000000106600190000003c90000c13d000000400050043f0000000005480436000800000005001d00000020054000390000000006350019000000000226004b000003670000213d00060000000c001d00090000000b001d00070000000a001d000000000240004c000000d50000613d000000000200001900000020022000390000000006820019000000000732001900000000070704330000000000760435000000000642004b000000ce0000413d0000000002580019000000000002043500000040011000390000000001010433000500000001001d000000ff0110008c0000000901000029000003670000213d0000000001010433000400000001001d000001990110009c000003c90000213d000100000008001d0000000301000039000300000001001d000000000101041a000000010210019000000001011002700000007f0310018f0000000001036019000200000001001d0000001f0110008c00000000010000190000000101002039000000010110018f000000000112004b0000021b0000c13d0000000201000029000000200110008c000001100000413d0000000301000029000000000010043500000198010000410000000002000414000001980320009c0000000001024019000000c0011002100000019b011001c70000801002000039065b06560000040f0000000102200190000003670000613d00000004030000290000001f023000390000000502200270000000200330008c0000000002004019000000000301043b00000002010000290000001f01100039000000050110027000000000011300190000000002230019000000000312004b000001100000813d000000000002041b0000000102200039000000000312004b0000010c0000413d00000004010000290000001f0110008c000004990000a13d0000000301000029000000000010043500000198010000410000000002000414000001980320009c0000000001024019000000c0011002100000019b011001c70000801002000039065b06560000040f000000010220019000000007020000290000000906000029000003670000613d000000040300002900000000032301700000002002000039000000000101043b000001300000613d0000002002000039000000000400001900000000056200190000000005050433000000000051041b000000200220003900000001011000390000002004400039000000000534004b000001280000413d0000000404000029000000000343004b0000013e0000813d00000004030000290000000303300210000000f80330018f000000010400008a000000000334022f000000000343013f000000090400002900000000024200190000000002020433000000000232016f000000000021041b0000000401000029000000010110021000000001011001bf000004a70000013d0000019e0210009c000001c60000213d000001a20210009c000002440000613d000001a30210009c000002700000613d000001a40110009c000003670000c13d0000000001000416000000000110004c000003670000c13d000000040100008a00000000011000310000019a02000041000000000310004c000000000300001900000000030240190000019a01100197000000000410004c000000000200a0190000019a0110009c00000000010300190000000001026019000000000110004c000003670000c13d0000000405000039000000000405041a000000010640019000000001014002700000007f0210018f00000000010260190000001f0210008c00000000020000190000000102002039000000000224013f00000001022001900000021b0000c13d000000400200043d0000000003120436000000000660004c000003800000c13d000001000500008a000000000454016f0000000000430435000000000110004c000000200400003900000000040060190000038d0000013d000001a60210009c000002940000613d000001a70210009c000002e30000613d000001a80110009c000003670000c13d0000000001000416000000000110004c000003670000c13d000000040100008a00000000011000310000019a02000041000000400310008c000000000300001900000000030240190000019a01100197000000000410004c000000000200a0190000019a0110009c00000000010300190000000001026019000000000110004c000003670000c13d00000004010000390000000101100367000000000101043b000900000001001d000001ac0110009c000003670000213d0000000001000411000700000001001d00000000001004350000000101000039000800000001001d000000200010043f00000198010000410000000002000414000001980320009c0000000001024019000000c001100210000001ae011001c70000801002000039065b06560000040f0000000102200190000003670000613d000000000101043b00000009020000290000000000200435000000200010043f00000024010000390000000101100367000000000101043b000600000001001d00000198010000410000000002000414000001980320009c0000000001024019000000c001100210000001ae011001c70000801002000039065b06560000040f0000000102200190000003670000613d000000000101043b000000000101041a00000006020000290000000003210019000000000113004b000000000100001900000001010040390000000101100190000003ae0000c13d00000007010000290000000902000029065b05ea0000040f000000400100043d000000080200002900000000002104350000019802000041000001980310009c00000000010280190000004001100210000001ad011001c70000065c0001042e0000019f0210009c000002ff0000613d000001a00210009c000003510000613d000001a10110009c000003670000c13d0000000001000416000000000110004c000003670000c13d000000040100008a00000000011000310000019a02000041000000400310008c000000000300001900000000030240190000019a01100197000000000410004c000000000200a0190000019a0110009c00000000010300190000000001026019000000000110004c000003670000c13d00000001020003670000000401200370000000000101043b000001ac0310009c000003670000213d0000002402200370000000000302043b000001ac0230009c000003670000213d00000000001004350000000101000039000000200010043f0000004002000039000900000002001d0000000001000019000800000003001d065b052b0000040f00000008020000290000000000200435000000200010043f00000000010000190000000902000029065b052b0000040f000000000101041a000000400200043d00000000001204350000019801000041000001980320009c00000000010240190000004001100210000001ad011001c70000065c0001042e0000000001000416000000000110004c000003670000c13d000000040100008a00000000011000310000019a02000041000000000310004c000000000300001900000000030240190000019a01100197000000000410004c000000000200a0190000019a0110009c00000000010300190000000001026019000000000110004c000003670000c13d0000000303000039000000000203041a000000010420019000000001012002700000007f0510018f000000000601001900000000060560190000001f0560008c00000000050000190000000105002039000000000552013f0000000105500190000003690000613d000001b70100004100000000001004350000002201000039000000040010043f000001b8010000410000065d000104300000000001000416000000000110004c000003670000c13d000000040100008a00000000011000310000019a02000041000000400310008c000000000300001900000000030240190000019a01100197000000000410004c000000000200a0190000019a0110009c00000000010300190000000001026019000000000110004c000003670000c13d00000001010003670000000402100370000000000202043b000001ac0320009c000003670000213d0000002401100370000000000301043b0000000001000411065b05ea0000040f0000000101000039000000400200043d00000000001204350000019801000041000001980320009c00000000010240190000004001100210000001ad011001c70000065c0001042e0000000001000416000000000110004c000003670000c13d000000040100008a00000000011000310000019a02000041000000400310008c000000000300001900000000030240190000019a01100197000000000410004c000000000200a0190000019a0110009c00000000010300190000000001026019000000000110004c000003670000c13d00000001010003670000000402100370000000000402043b000001ac0240009c000003670000213d0000002401100370000000000501043b000000000140004c000003a60000c13d000000400100043d0000004402100039000001b503000041000000000032043500000024021000390000001f030000390000000000320435000001b10200004100000000002104350000000402100039000000200300003900000000003204350000019802000041000001980310009c00000000010280190000004001100210000001b6011001c70000065d000104300000000001000416000000000110004c000003670000c13d000000040100008a00000000011000310000019a02000041000000200310008c000000000300001900000000030240190000019a01100197000000000410004c000000000200a0190000019a0110009c00000000010300190000000001026019000000000110004c000003670000c13d00000004010000390000000101100367000000000101043b000001ac0210009c000003670000213d0000000000100435000000200000043f00000040020000390000000001000019065b052b0000040f000000000101041a000000400200043d00000000001204350000019801000041000001980320009c00000000010240190000004001100210000001ad011001c70000065c0001042e0000000001000416000000000110004c000003670000c13d000000040100008a00000000011000310000019a02000041000000600310008c000000000300001900000000030240190000019a01100197000000000410004c000000000200a0190000019a0110009c00000000010300190000000001026019000000000110004c000003670000c13d00000001010003670000000402100370000000000402043b000001ac0240009c000003670000213d0000002402100370000000000202043b000900000002001d000001ac0220009c000003670000213d0000004401100370000000000101043b000700000001001d00000000004004350000000101000039000600000001001d000000200010043f00000198010000410000000002000414000001980320009c0000000001024019000000c001100210000001ae011001c70000801002000039000800000004001d065b06560000040f0000000102200190000003670000613d000000000101043b0000000002000411000500000002001d0000000000200435000000200010043f00000198010000410000000002000414000001980320009c0000000001024019000000c001100210000001ae011001c70000801002000039065b06560000040f00000008030000290000000102200190000003670000613d000000000101043b000000000201041a000000010100008a000000000112004b0000041c0000c13d000000000103001900000009020000290000000703000029065b05570000040f000000400100043d000000060200002900000000002104350000019802000041000001980310009c00000000010280190000004001100210000001ad011001c70000065c0001042e0000000001000416000000000110004c000003670000c13d000000040100008a00000000011000310000019a02000041000000000310004c000000000300001900000000030240190000019a01100197000000000410004c000000000200a0190000019a0110009c00000000010300190000000001026019000000000110004c000003670000c13d0000000501000039000000000101041a000000ff0110018f000000400200043d00000000001204350000019801000041000001980320009c00000000010240190000004001100210000001ad011001c70000065c0001042e0000000001000416000000000110004c000003670000c13d000000040100008a00000000011000310000019a02000041000000400310008c000000000300001900000000030240190000019a01100197000000000410004c000000000200a0190000019a0110009c00000000010300190000000001026019000000000110004c000003670000c13d00000001010003670000000402100370000000000202043b000900000002001d000001ac0220009c000003670000213d0000002401100370000000000101043b000800000001001d0000000001000411000600000001001d00000000001004350000000101000039000700000001001d000000200010043f00000198010000410000000002000414000001980320009c0000000001024019000000c001100210000001ae011001c70000801002000039065b06560000040f0000000102200190000003670000613d000000000101043b00000009020000290000000000200435000000200010043f00000198010000410000000002000414000001980320009c0000000001024019000000c001100210000001ae011001c70000801002000039065b06560000040f0000000102200190000003670000613d000000000101043b000000000101041a0000000803000029000000000231004b0000040f0000813d000000400100043d0000006402100039000001af0300004100000000003204350000004402100039000001b0030000410000000000320435000000240210003900000025030000390000000000320435000001b10200004100000000002104350000000402100039000000200300003900000000003204350000019802000041000001980310009c00000000010280190000004001100210000001b2011001c70000065d000104300000000001000416000000000110004c000003670000c13d000000040100008a00000000011000310000019a02000041000000400310008c000000000300001900000000030240190000019a01100197000000000410004c000000000200a0190000019a0110009c00000000010300190000000001026019000000000110004c000003670000c13d00000001010003670000000402100370000000000202043b000001ac0320009c000003730000a13d00000000010000190000065d00010430000000800060043f000000000440004c000003b40000c13d000001000300008a000000000232016f000000a00020043f000000000160004c000000c001000039000000a001006039000003c30000013d0000002401100370000000000301043b0000000001000411065b05570000040f0000000101000039000000400200043d00000000001204350000019801000041000001980320009c00000000010240190000004001100210000001ad011001c70000065c0001042e0000000000500435000000000410004c00000000040000190000038d0000613d000001b30500004100000000040000190000000006430019000000000705041a000000000076043500000001055000390000002004400039000000000614004b000003860000413d0000003f01400039000000200300008a000000000331016f0000000001230019000000000331004b00000000040000190000000104004039000001990310009c000003c90000213d0000000103400190000003c90000c13d000000400010043f000900000001001d065b05410000040f000000090400002900000000014100490000019802000041000001980310009c0000000001028019000001980340009c000000000204401900000040022002100000006001100210000000000121019f0000065c0001042e0000000201000039000000000301041a0000000002530019000000000332004b000000000300001900000001030040390000000103300190000003de0000613d000001b70100004100000000001004350000001101000039000000040010043f000001b8010000410000065d000104300000000000300435000000a001000039000000000260004c000003cf0000613d000001bf0200004100000000040000190000000003040019000000000402041a000000a005300039000000000045043500000001022000390000002004300039000000000564004b000003ba0000413d000000c0013000390000001f01100039000000200200008a000000000121016f000001c002100041000001c10220009c000003cf0000813d000001b70100004100000000001004350000004101000039000000040010043f000001b8010000410000065d00010430000900000001001d000000400010043f0000008002000039065b05410000040f000000090400002900000000014100490000019802000041000001980310009c0000000001028019000001980340009c000000000204401900000040022002100000006001100210000000000121019f0000065c0001042e000800000005001d000000000021041b0000000000400435000000200000043f00000198010000410000000002000414000001980320009c0000000001024019000000c001100210000001ae011001c70000801002000039000900000004001d065b06560000040f00000009060000290000000102200190000003670000613d000000000101043b000000000201041a00000008030000290000000002320019000000000021041b000000400100043d000000000031043500000198020000410000000003000414000001980430009c0000000003028019000001980410009c00000000010280190000004001100210000000c002300210000000000112019f0000019b011001c70000800d020000390000000303000039000001b4040000410000000005000019065b06510000040f0000000101200190000003670000613d000000400100043d000000010200003900000000002104350000019802000041000001980310009c00000000010280190000004001100210000001ad011001c70000065c0001042e000000000331004900000006010000290000000902000029065b05ea0000040f000000400100043d000000070200002900000000002104350000019802000041000001980310009c00000000010280190000004001100210000001ad011001c70000065c0001042e0000000701000029000000000112004b000004310000813d000000400100043d0000004402100039000001be03000041000000000032043500000024021000390000001d030000390000000000320435000001b10200004100000000002104350000000402100039000000200300003900000000003204350000019802000041000001980310009c00000000010280190000004001100210000001b6011001c70000065d00010430000400000002001d000000000130004c000004490000c13d000000400100043d0000006402100039000001bc0300004100000000003204350000004402100039000001bd030000410000000000320435000000240210003900000024030000390000000000320435000001b10200004100000000002104350000000402100039000000200300003900000000003204350000019802000041000001980310009c00000000010280190000004001100210000001b2011001c70000065d000104300000000501000029000001ac01100198000500000001001d000004620000c13d000000400100043d0000006402100039000001ba0300004100000000003204350000004402100039000001bb030000410000000000320435000000240210003900000022030000390000000000320435000001b10200004100000000002104350000000402100039000000200300003900000000003204350000019802000041000001980310009c00000000010280190000004001100210000001b2011001c70000065d00010430000000080100002900000000001004350000000601000029000000200010043f00000198010000410000000002000414000001980320009c0000000001024019000000c001100210000001ae011001c70000801002000039065b06560000040f0000000102200190000003670000613d000000000101043b00000005020000290000000000200435000000200010043f00000198010000410000000002000414000001980320009c0000000001024019000000c001100210000001ae011001c70000801002000039065b06560000040f00000004030000290000000102200190000003670000613d00000007020000290000000002230049000000000101043b000000000021041b000000400100043d000000000021043500000198020000410000000003000414000001980430009c0000000003028019000001980410009c00000000010280190000004001100210000000c002300210000000000112019f0000019b011001c70000800d020000390000000303000039000001b90400004100000008050000290000000506000029065b06510000040f00000008030000290000000101200190000002d60000c13d000003670000013d0000000401000029000000000110004c00000000010000190000049f0000613d0000000601000029000000000101043300000004040000290000000302400210000000010300008a000000000223022f000000000232013f000000000121016f0000000102400210000000000121019f0000000302000029000000000012041b00000001010000290000000001010433000900000001001d000001990110009c000003c90000213d0000000401000039000600000001001d000000000101041a000000010210019000000001021002700000007f0320018f0000000002036019000400000002001d0000001f0220008c00000000020000190000000102002039000000000121013f00000001011001900000021b0000c13d0000000401000029000000200110008c000004dc0000413d0000000601000029000000000010043500000198010000410000000002000414000001980320009c0000000001024019000000c0011002100000019b011001c70000801002000039065b06560000040f0000000102200190000003670000613d00000009030000290000001f023000390000000502200270000000200330008c0000000002004019000000000301043b00000004010000290000001f01100039000000050110027000000000011300190000000002230019000000000312004b000004dc0000813d000000000002041b0000000102200039000000000312004b000004d80000413d00000009010000290000001f0110008c0000050e0000a13d0000000601000029000000000010043500000198010000410000000002000414000001980320009c0000000001024019000000c0011002100000019b011001c70000801002000039065b06560000040f000000010220019000000007020000290000000106000029000003670000613d000000090300002900000000032301700000002002000039000000000101043b000004fc0000613d0000002002000039000000000400001900000000056200190000000005050433000000000051041b000000200220003900000001011000390000002004400039000000000534004b000004f40000413d0000000904000029000000000343004b0000050a0000813d00000009030000290000000303300210000000f80330018f000000010400008a000000000334022f000000000343013f000000010400002900000000024200190000000002020433000000000232016f000000000021041b0000000101000039000000090200002900000001022002100000051b0000013d0000000901000029000000000110004c0000000001000019000005140000613d0000000801000029000000000101043300000009040000290000000302400210000000010300008a000000000223022f000000000232013f000000000221016f0000000101400210000000000112019f0000000602000029000000000012041b0000000501000039000000000201041a000001000300008a000000000232016f0000000503000029000000ff0330018f000000000232019f000000000021041b0000002001000039000001000010044300000120000004430000019c010000410000065c0001042e0000019803000041000001980410009c00000000010380190000004001100210000001980420009c00000000020380190000006002200210000000000112019f0000000002000414000001980420009c0000000002038019000000c002200210000000000112019f000001c2011001c70000801002000039065b06560000040f00000001022001900000053f0000613d000000000101043b000000000001042d00000000010000190000065d0001043000000020030000390000000004310436000000000302043300000000003404350000004001100039000000000430004c000005500000613d000000000400001900000000054100190000002004400039000000000624001900000000060604330000000000650435000000000534004b000005490000413d000000000231001900000000000204350000001f02300039000000200300008a000000000232016f0000000001210019000000000001042d0004000000000002000400000003001d000001ac01100198000005ab0000613d000001ac02200198000200000002001d000005c00000613d000300000001001d0000000000100435000000200000043f00000198010000410000000002000414000001980320009c0000000001024019000000c001100210000001ae011001c70000801002000039065b06560000040f0000000102200190000005a90000613d000000000101043b000000000201041a0000000401000029000100000002001d000000000112004b000005d50000413d00000003010000290000000000100435000000200000043f00000198010000410000000002000414000001980320009c0000000001024019000000c001100210000001ae011001c70000801002000039065b06560000040f0000000102200190000005a90000613d000000040200002900000001030000290000000002230049000000000101043b000000000021041b0000000201000029000000000010043500000198010000410000000002000414000001980320009c0000000001024019000000c001100210000001ae011001c70000801002000039065b06560000040f0000000102200190000005a90000613d000000000101043b000000000201041a00000004030000290000000002320019000000000021041b000000400100043d000000000031043500000198020000410000000003000414000001980430009c0000000003028019000001980410009c00000000010280190000004001100210000000c002300210000000000112019f0000019b011001c70000800d020000390000000303000039000001b40400004100000003050000290000000206000029065b06510000040f0000000101200190000005a90000613d000000000001042d00000000010000190000065d00010430000000400100043d0000006402100039000001c70300004100000000003204350000004402100039000001c8030000410000000000320435000000240210003900000025030000390000000000320435000001b10200004100000000002104350000000402100039000000200300003900000000003204350000019802000041000001980310009c00000000010280190000004001100210000001b2011001c70000065d00010430000000400100043d0000006402100039000001c50300004100000000003204350000004402100039000001c6030000410000000000320435000000240210003900000023030000390000000000320435000001b10200004100000000002104350000000402100039000000200300003900000000003204350000019802000041000001980310009c00000000010280190000004001100210000001b2011001c70000065d00010430000000400100043d0000006402100039000001c30300004100000000003204350000004402100039000001c4030000410000000000320435000000240210003900000026030000390000000000320435000001b10200004100000000002104350000000402100039000000200300003900000000003204350000019802000041000001980310009c00000000010280190000004001100210000001b2011001c70000065d000104300003000000000002000001ac01100198000006270000613d000200000003001d000001ac02200198000300000002001d0000063c0000613d000100000001001d00000000001004350000000101000039000000200010043f00000198010000410000000002000414000001980320009c0000000001024019000000c001100210000001ae011001c70000801002000039065b06560000040f00000001022001900000000304000029000006250000613d000000000101043b0000000000400435000000200010043f00000198010000410000000002000414000001980320009c0000000001024019000000c001100210000001ae011001c70000801002000039065b06560000040f00000003060000290000000102200190000006250000613d000000000101043b0000000202000029000000000021041b000000400100043d000000000021043500000198020000410000000003000414000001980430009c0000000003028019000001980410009c00000000010280190000004001100210000000c002300210000000000112019f0000019b011001c70000800d020000390000000303000039000001b9040000410000000105000029065b06510000040f0000000101200190000006250000613d000000000001042d00000000010000190000065d00010430000000400100043d0000006402100039000001bc0300004100000000003204350000004402100039000001bd030000410000000000320435000000240210003900000024030000390000000000320435000001b10200004100000000002104350000000402100039000000200300003900000000003204350000019802000041000001980310009c00000000010280190000004001100210000001b2011001c70000065d00010430000000400100043d0000006402100039000001ba0300004100000000003204350000004402100039000001bb030000410000000000320435000000240210003900000022030000390000000000320435000001b10200004100000000002104350000000402100039000000200300003900000000003204350000019802000041000001980310009c00000000010280190000004001100210000001b2011001c70000065d0001043000000654002104210000000102000039000000000001042d0000000002000019000000000001042d00000659002104230000000102000039000000000001042d0000000002000019000000000001042d0000065b000004320000065c0001042e0000065d000104300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffff000000000000000000000000000000000000000000000000ffffffffffffffff8000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000002000000000000000000000000000000002000000000000000000000000000000400000010000000000000000000000000000000000000000000000000000000000000000000000000040c10f1800000000000000000000000000000000000000000000000000000000a457c2d600000000000000000000000000000000000000000000000000000000a457c2d700000000000000000000000000000000000000000000000000000000a9059cbb00000000000000000000000000000000000000000000000000000000dd62ed3e0000000000000000000000000000000000000000000000000000000040c10f190000000000000000000000000000000000000000000000000000000070a082310000000000000000000000000000000000000000000000000000000095d89b410000000000000000000000000000000000000000000000000000000023b872dc0000000000000000000000000000000000000000000000000000000023b872dd00000000000000000000000000000000000000000000000000000000313ce56700000000000000000000000000000000000000000000000000000000395093510000000000000000000000000000000000000000000000000000000006fdde0300000000000000000000000000000000000000000000000000000000095ea7b30000000000000000000000000000000000000000000000000000000018160ddd000000000000000000000000ffffffffffffffffffffffffffffffffffffffff00000000000000000000000000000000000000200000000000000000000000000200000000000000000000000000000000000040000000000000000000000000207a65726f00000000000000000000000000000000000000000000000000000045524332303a2064656372656173656420616c6c6f77616e63652062656c6f7708c379a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000840000000000000000000000008a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19bddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef45524332303a206d696e7420746f20746865207a65726f20616464726573730000000000000000000000000000000000000000640000000000000000000000004e487b710000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000240000000000000000000000008c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925737300000000000000000000000000000000000000000000000000000000000045524332303a20617070726f766520746f20746865207a65726f206164647265726573730000000000000000000000000000000000000000000000000000000045524332303a20617070726f76652066726f6d20746865207a65726f2061646445524332303a20696e73756666696369656e7420616c6c6f77616e6365000000c2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85bffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000ffffffffffffffffffffffffffffffffffffffffffffffff00000000000000800200000000000000000000000000000000000000000000000000000000000000616c616e6365000000000000000000000000000000000000000000000000000045524332303a207472616e7366657220616d6f756e7420657863656564732062657373000000000000000000000000000000000000000000000000000000000045524332303a207472616e7366657220746f20746865207a65726f2061646472647265737300000000000000000000000000000000000000000000000000000045524332303a207472616e736665722066726f6d20746865207a65726f206164000000000000000000000000000000000000000000000000000000000000000018469939d00da7016fd24775544e09a6a1ad29697146a060aa4a0baa144c2ede", + "deployedBytecode": "0x0002000000000002000900000000000200010000000103550000006001100270000001980010019d0000008001000039000000400010043f0000000101200190000000340000c13d0000000001000031000000040110008c000003670000413d0000000101000367000000000101043b000000e0011002700000019d0210009c000001420000213d000001a50210009c000001720000213d000001a90210009c000001fd0000613d000001aa0210009c000002210000613d000001ab0110009c000003670000c13d0000000001000416000000000110004c000003670000c13d000000040100008a00000000011000310000019a02000041000000000310004c000000000300001900000000030240190000019a01100197000000000410004c000000000200a0190000019a0110009c00000000010300190000000001026019000000000110004c000003670000c13d0000000201000039000000000101041a000000400200043d00000000001204350000019801000041000001980320009c00000000010240190000004001100210000001ad011001c70000065c0001042e0000000001000416000000000110004c000003670000c13d00000000020000310000001f01200039000000200a00008a0000000004a1016f000000400100043d0000000003140019000000000443004b00000000040000190000000104004039000001990530009c000003c90000213d0000000104400190000003c90000c13d000000400030043f0000001f0320018f00000001040003670000000505200272000000520000613d000000000600001900000005076002100000000008710019000000000774034f000000000707043b00000000007804350000000106600039000000000756004b0000004a0000413d000000000630004c000000610000613d0000000505500210000000000454034f00000000055100190000000303300210000000000605043300000000063601cf000000000636022f000000000404043b0000010003300089000000000434022f00000000033401cf000000000363019f00000000003504350000019a03000041000000600420008c000000000400001900000000040340190000019a05200197000000000650004c000000000300a0190000019a0550009c000000000304c019000000000330004c000003670000c13d0000000034010434000001990540009c000003670000213d000000000221001900000000041400190000001f054000390000019a06000041000000000725004b000000000700001900000000070680190000019a055001970000019a08200197000000000985004b0000000006008019000000000585013f0000019a0550009c00000000050700190000000005066019000000000550004c000003670000c13d0000000005040433000001990650009c000003c90000213d0000003f065000390000000006a6016f000000400b00043d00000000066b00190000000007b6004b00000000070000190000000107004039000001990860009c000003c90000213d0000000107700190000003c90000c13d000000400060043f000000000c5b043600000020065000390000000007460019000000000727004b000003670000213d000000000750004c0000009e0000613d000000000700001900000020077000390000000008b70019000000000947001900000000090904330000000000980435000000000857004b000000970000413d00000000046b001900000000000404350000000003030433000001990430009c000003670000213d00000000031300190000001f043000390000019a05000041000000000624004b000000000600001900000000060580190000019a044001970000019a07200197000000000874004b0000000005008019000000000474013f0000019a0440009c00000000040600190000000004056019000000000440004c000003670000c13d0000000004030433000001990540009c000003c90000213d0000003f054000390000000005a5016f000000400800043d0000000005580019000000000685004b00000000060000190000000106004039000001990750009c000003c90000213d0000000106600190000003c90000c13d000000400050043f0000000005480436000800000005001d00000020054000390000000006350019000000000226004b000003670000213d00060000000c001d00090000000b001d00070000000a001d000000000240004c000000d50000613d000000000200001900000020022000390000000006820019000000000732001900000000070704330000000000760435000000000642004b000000ce0000413d0000000002580019000000000002043500000040011000390000000001010433000500000001001d000000ff0110008c0000000901000029000003670000213d0000000001010433000400000001001d000001990110009c000003c90000213d000100000008001d0000000301000039000300000001001d000000000101041a000000010210019000000001011002700000007f0310018f0000000001036019000200000001001d0000001f0110008c00000000010000190000000101002039000000010110018f000000000112004b0000021b0000c13d0000000201000029000000200110008c000001100000413d0000000301000029000000000010043500000198010000410000000002000414000001980320009c0000000001024019000000c0011002100000019b011001c70000801002000039065b06560000040f0000000102200190000003670000613d00000004030000290000001f023000390000000502200270000000200330008c0000000002004019000000000301043b00000002010000290000001f01100039000000050110027000000000011300190000000002230019000000000312004b000001100000813d000000000002041b0000000102200039000000000312004b0000010c0000413d00000004010000290000001f0110008c000004990000a13d0000000301000029000000000010043500000198010000410000000002000414000001980320009c0000000001024019000000c0011002100000019b011001c70000801002000039065b06560000040f000000010220019000000007020000290000000906000029000003670000613d000000040300002900000000032301700000002002000039000000000101043b000001300000613d0000002002000039000000000400001900000000056200190000000005050433000000000051041b000000200220003900000001011000390000002004400039000000000534004b000001280000413d0000000404000029000000000343004b0000013e0000813d00000004030000290000000303300210000000f80330018f000000010400008a000000000334022f000000000343013f000000090400002900000000024200190000000002020433000000000232016f000000000021041b0000000401000029000000010110021000000001011001bf000004a70000013d0000019e0210009c000001c60000213d000001a20210009c000002440000613d000001a30210009c000002700000613d000001a40110009c000003670000c13d0000000001000416000000000110004c000003670000c13d000000040100008a00000000011000310000019a02000041000000000310004c000000000300001900000000030240190000019a01100197000000000410004c000000000200a0190000019a0110009c00000000010300190000000001026019000000000110004c000003670000c13d0000000405000039000000000405041a000000010640019000000001014002700000007f0210018f00000000010260190000001f0210008c00000000020000190000000102002039000000000224013f00000001022001900000021b0000c13d000000400200043d0000000003120436000000000660004c000003800000c13d000001000500008a000000000454016f0000000000430435000000000110004c000000200400003900000000040060190000038d0000013d000001a60210009c000002940000613d000001a70210009c000002e30000613d000001a80110009c000003670000c13d0000000001000416000000000110004c000003670000c13d000000040100008a00000000011000310000019a02000041000000400310008c000000000300001900000000030240190000019a01100197000000000410004c000000000200a0190000019a0110009c00000000010300190000000001026019000000000110004c000003670000c13d00000004010000390000000101100367000000000101043b000900000001001d000001ac0110009c000003670000213d0000000001000411000700000001001d00000000001004350000000101000039000800000001001d000000200010043f00000198010000410000000002000414000001980320009c0000000001024019000000c001100210000001ae011001c70000801002000039065b06560000040f0000000102200190000003670000613d000000000101043b00000009020000290000000000200435000000200010043f00000024010000390000000101100367000000000101043b000600000001001d00000198010000410000000002000414000001980320009c0000000001024019000000c001100210000001ae011001c70000801002000039065b06560000040f0000000102200190000003670000613d000000000101043b000000000101041a00000006020000290000000003210019000000000113004b000000000100001900000001010040390000000101100190000003ae0000c13d00000007010000290000000902000029065b05ea0000040f000000400100043d000000080200002900000000002104350000019802000041000001980310009c00000000010280190000004001100210000001ad011001c70000065c0001042e0000019f0210009c000002ff0000613d000001a00210009c000003510000613d000001a10110009c000003670000c13d0000000001000416000000000110004c000003670000c13d000000040100008a00000000011000310000019a02000041000000400310008c000000000300001900000000030240190000019a01100197000000000410004c000000000200a0190000019a0110009c00000000010300190000000001026019000000000110004c000003670000c13d00000001020003670000000401200370000000000101043b000001ac0310009c000003670000213d0000002402200370000000000302043b000001ac0230009c000003670000213d00000000001004350000000101000039000000200010043f0000004002000039000900000002001d0000000001000019000800000003001d065b052b0000040f00000008020000290000000000200435000000200010043f00000000010000190000000902000029065b052b0000040f000000000101041a000000400200043d00000000001204350000019801000041000001980320009c00000000010240190000004001100210000001ad011001c70000065c0001042e0000000001000416000000000110004c000003670000c13d000000040100008a00000000011000310000019a02000041000000000310004c000000000300001900000000030240190000019a01100197000000000410004c000000000200a0190000019a0110009c00000000010300190000000001026019000000000110004c000003670000c13d0000000303000039000000000203041a000000010420019000000001012002700000007f0510018f000000000601001900000000060560190000001f0560008c00000000050000190000000105002039000000000552013f0000000105500190000003690000613d000001b70100004100000000001004350000002201000039000000040010043f000001b8010000410000065d000104300000000001000416000000000110004c000003670000c13d000000040100008a00000000011000310000019a02000041000000400310008c000000000300001900000000030240190000019a01100197000000000410004c000000000200a0190000019a0110009c00000000010300190000000001026019000000000110004c000003670000c13d00000001010003670000000402100370000000000202043b000001ac0320009c000003670000213d0000002401100370000000000301043b0000000001000411065b05ea0000040f0000000101000039000000400200043d00000000001204350000019801000041000001980320009c00000000010240190000004001100210000001ad011001c70000065c0001042e0000000001000416000000000110004c000003670000c13d000000040100008a00000000011000310000019a02000041000000400310008c000000000300001900000000030240190000019a01100197000000000410004c000000000200a0190000019a0110009c00000000010300190000000001026019000000000110004c000003670000c13d00000001010003670000000402100370000000000402043b000001ac0240009c000003670000213d0000002401100370000000000501043b000000000140004c000003a60000c13d000000400100043d0000004402100039000001b503000041000000000032043500000024021000390000001f030000390000000000320435000001b10200004100000000002104350000000402100039000000200300003900000000003204350000019802000041000001980310009c00000000010280190000004001100210000001b6011001c70000065d000104300000000001000416000000000110004c000003670000c13d000000040100008a00000000011000310000019a02000041000000200310008c000000000300001900000000030240190000019a01100197000000000410004c000000000200a0190000019a0110009c00000000010300190000000001026019000000000110004c000003670000c13d00000004010000390000000101100367000000000101043b000001ac0210009c000003670000213d0000000000100435000000200000043f00000040020000390000000001000019065b052b0000040f000000000101041a000000400200043d00000000001204350000019801000041000001980320009c00000000010240190000004001100210000001ad011001c70000065c0001042e0000000001000416000000000110004c000003670000c13d000000040100008a00000000011000310000019a02000041000000600310008c000000000300001900000000030240190000019a01100197000000000410004c000000000200a0190000019a0110009c00000000010300190000000001026019000000000110004c000003670000c13d00000001010003670000000402100370000000000402043b000001ac0240009c000003670000213d0000002402100370000000000202043b000900000002001d000001ac0220009c000003670000213d0000004401100370000000000101043b000700000001001d00000000004004350000000101000039000600000001001d000000200010043f00000198010000410000000002000414000001980320009c0000000001024019000000c001100210000001ae011001c70000801002000039000800000004001d065b06560000040f0000000102200190000003670000613d000000000101043b0000000002000411000500000002001d0000000000200435000000200010043f00000198010000410000000002000414000001980320009c0000000001024019000000c001100210000001ae011001c70000801002000039065b06560000040f00000008030000290000000102200190000003670000613d000000000101043b000000000201041a000000010100008a000000000112004b0000041c0000c13d000000000103001900000009020000290000000703000029065b05570000040f000000400100043d000000060200002900000000002104350000019802000041000001980310009c00000000010280190000004001100210000001ad011001c70000065c0001042e0000000001000416000000000110004c000003670000c13d000000040100008a00000000011000310000019a02000041000000000310004c000000000300001900000000030240190000019a01100197000000000410004c000000000200a0190000019a0110009c00000000010300190000000001026019000000000110004c000003670000c13d0000000501000039000000000101041a000000ff0110018f000000400200043d00000000001204350000019801000041000001980320009c00000000010240190000004001100210000001ad011001c70000065c0001042e0000000001000416000000000110004c000003670000c13d000000040100008a00000000011000310000019a02000041000000400310008c000000000300001900000000030240190000019a01100197000000000410004c000000000200a0190000019a0110009c00000000010300190000000001026019000000000110004c000003670000c13d00000001010003670000000402100370000000000202043b000900000002001d000001ac0220009c000003670000213d0000002401100370000000000101043b000800000001001d0000000001000411000600000001001d00000000001004350000000101000039000700000001001d000000200010043f00000198010000410000000002000414000001980320009c0000000001024019000000c001100210000001ae011001c70000801002000039065b06560000040f0000000102200190000003670000613d000000000101043b00000009020000290000000000200435000000200010043f00000198010000410000000002000414000001980320009c0000000001024019000000c001100210000001ae011001c70000801002000039065b06560000040f0000000102200190000003670000613d000000000101043b000000000101041a0000000803000029000000000231004b0000040f0000813d000000400100043d0000006402100039000001af0300004100000000003204350000004402100039000001b0030000410000000000320435000000240210003900000025030000390000000000320435000001b10200004100000000002104350000000402100039000000200300003900000000003204350000019802000041000001980310009c00000000010280190000004001100210000001b2011001c70000065d000104300000000001000416000000000110004c000003670000c13d000000040100008a00000000011000310000019a02000041000000400310008c000000000300001900000000030240190000019a01100197000000000410004c000000000200a0190000019a0110009c00000000010300190000000001026019000000000110004c000003670000c13d00000001010003670000000402100370000000000202043b000001ac0320009c000003730000a13d00000000010000190000065d00010430000000800060043f000000000440004c000003b40000c13d000001000300008a000000000232016f000000a00020043f000000000160004c000000c001000039000000a001006039000003c30000013d0000002401100370000000000301043b0000000001000411065b05570000040f0000000101000039000000400200043d00000000001204350000019801000041000001980320009c00000000010240190000004001100210000001ad011001c70000065c0001042e0000000000500435000000000410004c00000000040000190000038d0000613d000001b30500004100000000040000190000000006430019000000000705041a000000000076043500000001055000390000002004400039000000000614004b000003860000413d0000003f01400039000000200300008a000000000331016f0000000001230019000000000331004b00000000040000190000000104004039000001990310009c000003c90000213d0000000103400190000003c90000c13d000000400010043f000900000001001d065b05410000040f000000090400002900000000014100490000019802000041000001980310009c0000000001028019000001980340009c000000000204401900000040022002100000006001100210000000000121019f0000065c0001042e0000000201000039000000000301041a0000000002530019000000000332004b000000000300001900000001030040390000000103300190000003de0000613d000001b70100004100000000001004350000001101000039000000040010043f000001b8010000410000065d000104300000000000300435000000a001000039000000000260004c000003cf0000613d000001bf0200004100000000040000190000000003040019000000000402041a000000a005300039000000000045043500000001022000390000002004300039000000000564004b000003ba0000413d000000c0013000390000001f01100039000000200200008a000000000121016f000001c002100041000001c10220009c000003cf0000813d000001b70100004100000000001004350000004101000039000000040010043f000001b8010000410000065d00010430000900000001001d000000400010043f0000008002000039065b05410000040f000000090400002900000000014100490000019802000041000001980310009c0000000001028019000001980340009c000000000204401900000040022002100000006001100210000000000121019f0000065c0001042e000800000005001d000000000021041b0000000000400435000000200000043f00000198010000410000000002000414000001980320009c0000000001024019000000c001100210000001ae011001c70000801002000039000900000004001d065b06560000040f00000009060000290000000102200190000003670000613d000000000101043b000000000201041a00000008030000290000000002320019000000000021041b000000400100043d000000000031043500000198020000410000000003000414000001980430009c0000000003028019000001980410009c00000000010280190000004001100210000000c002300210000000000112019f0000019b011001c70000800d020000390000000303000039000001b4040000410000000005000019065b06510000040f0000000101200190000003670000613d000000400100043d000000010200003900000000002104350000019802000041000001980310009c00000000010280190000004001100210000001ad011001c70000065c0001042e000000000331004900000006010000290000000902000029065b05ea0000040f000000400100043d000000070200002900000000002104350000019802000041000001980310009c00000000010280190000004001100210000001ad011001c70000065c0001042e0000000701000029000000000112004b000004310000813d000000400100043d0000004402100039000001be03000041000000000032043500000024021000390000001d030000390000000000320435000001b10200004100000000002104350000000402100039000000200300003900000000003204350000019802000041000001980310009c00000000010280190000004001100210000001b6011001c70000065d00010430000400000002001d000000000130004c000004490000c13d000000400100043d0000006402100039000001bc0300004100000000003204350000004402100039000001bd030000410000000000320435000000240210003900000024030000390000000000320435000001b10200004100000000002104350000000402100039000000200300003900000000003204350000019802000041000001980310009c00000000010280190000004001100210000001b2011001c70000065d000104300000000501000029000001ac01100198000500000001001d000004620000c13d000000400100043d0000006402100039000001ba0300004100000000003204350000004402100039000001bb030000410000000000320435000000240210003900000022030000390000000000320435000001b10200004100000000002104350000000402100039000000200300003900000000003204350000019802000041000001980310009c00000000010280190000004001100210000001b2011001c70000065d00010430000000080100002900000000001004350000000601000029000000200010043f00000198010000410000000002000414000001980320009c0000000001024019000000c001100210000001ae011001c70000801002000039065b06560000040f0000000102200190000003670000613d000000000101043b00000005020000290000000000200435000000200010043f00000198010000410000000002000414000001980320009c0000000001024019000000c001100210000001ae011001c70000801002000039065b06560000040f00000004030000290000000102200190000003670000613d00000007020000290000000002230049000000000101043b000000000021041b000000400100043d000000000021043500000198020000410000000003000414000001980430009c0000000003028019000001980410009c00000000010280190000004001100210000000c002300210000000000112019f0000019b011001c70000800d020000390000000303000039000001b90400004100000008050000290000000506000029065b06510000040f00000008030000290000000101200190000002d60000c13d000003670000013d0000000401000029000000000110004c00000000010000190000049f0000613d0000000601000029000000000101043300000004040000290000000302400210000000010300008a000000000223022f000000000232013f000000000121016f0000000102400210000000000121019f0000000302000029000000000012041b00000001010000290000000001010433000900000001001d000001990110009c000003c90000213d0000000401000039000600000001001d000000000101041a000000010210019000000001021002700000007f0320018f0000000002036019000400000002001d0000001f0220008c00000000020000190000000102002039000000000121013f00000001011001900000021b0000c13d0000000401000029000000200110008c000004dc0000413d0000000601000029000000000010043500000198010000410000000002000414000001980320009c0000000001024019000000c0011002100000019b011001c70000801002000039065b06560000040f0000000102200190000003670000613d00000009030000290000001f023000390000000502200270000000200330008c0000000002004019000000000301043b00000004010000290000001f01100039000000050110027000000000011300190000000002230019000000000312004b000004dc0000813d000000000002041b0000000102200039000000000312004b000004d80000413d00000009010000290000001f0110008c0000050e0000a13d0000000601000029000000000010043500000198010000410000000002000414000001980320009c0000000001024019000000c0011002100000019b011001c70000801002000039065b06560000040f000000010220019000000007020000290000000106000029000003670000613d000000090300002900000000032301700000002002000039000000000101043b000004fc0000613d0000002002000039000000000400001900000000056200190000000005050433000000000051041b000000200220003900000001011000390000002004400039000000000534004b000004f40000413d0000000904000029000000000343004b0000050a0000813d00000009030000290000000303300210000000f80330018f000000010400008a000000000334022f000000000343013f000000010400002900000000024200190000000002020433000000000232016f000000000021041b0000000101000039000000090200002900000001022002100000051b0000013d0000000901000029000000000110004c0000000001000019000005140000613d0000000801000029000000000101043300000009040000290000000302400210000000010300008a000000000223022f000000000232013f000000000221016f0000000101400210000000000112019f0000000602000029000000000012041b0000000501000039000000000201041a000001000300008a000000000232016f0000000503000029000000ff0330018f000000000232019f000000000021041b0000002001000039000001000010044300000120000004430000019c010000410000065c0001042e0000019803000041000001980410009c00000000010380190000004001100210000001980420009c00000000020380190000006002200210000000000112019f0000000002000414000001980420009c0000000002038019000000c002200210000000000112019f000001c2011001c70000801002000039065b06560000040f00000001022001900000053f0000613d000000000101043b000000000001042d00000000010000190000065d0001043000000020030000390000000004310436000000000302043300000000003404350000004001100039000000000430004c000005500000613d000000000400001900000000054100190000002004400039000000000624001900000000060604330000000000650435000000000534004b000005490000413d000000000231001900000000000204350000001f02300039000000200300008a000000000232016f0000000001210019000000000001042d0004000000000002000400000003001d000001ac01100198000005ab0000613d000001ac02200198000200000002001d000005c00000613d000300000001001d0000000000100435000000200000043f00000198010000410000000002000414000001980320009c0000000001024019000000c001100210000001ae011001c70000801002000039065b06560000040f0000000102200190000005a90000613d000000000101043b000000000201041a0000000401000029000100000002001d000000000112004b000005d50000413d00000003010000290000000000100435000000200000043f00000198010000410000000002000414000001980320009c0000000001024019000000c001100210000001ae011001c70000801002000039065b06560000040f0000000102200190000005a90000613d000000040200002900000001030000290000000002230049000000000101043b000000000021041b0000000201000029000000000010043500000198010000410000000002000414000001980320009c0000000001024019000000c001100210000001ae011001c70000801002000039065b06560000040f0000000102200190000005a90000613d000000000101043b000000000201041a00000004030000290000000002320019000000000021041b000000400100043d000000000031043500000198020000410000000003000414000001980430009c0000000003028019000001980410009c00000000010280190000004001100210000000c002300210000000000112019f0000019b011001c70000800d020000390000000303000039000001b40400004100000003050000290000000206000029065b06510000040f0000000101200190000005a90000613d000000000001042d00000000010000190000065d00010430000000400100043d0000006402100039000001c70300004100000000003204350000004402100039000001c8030000410000000000320435000000240210003900000025030000390000000000320435000001b10200004100000000002104350000000402100039000000200300003900000000003204350000019802000041000001980310009c00000000010280190000004001100210000001b2011001c70000065d00010430000000400100043d0000006402100039000001c50300004100000000003204350000004402100039000001c6030000410000000000320435000000240210003900000023030000390000000000320435000001b10200004100000000002104350000000402100039000000200300003900000000003204350000019802000041000001980310009c00000000010280190000004001100210000001b2011001c70000065d00010430000000400100043d0000006402100039000001c30300004100000000003204350000004402100039000001c4030000410000000000320435000000240210003900000026030000390000000000320435000001b10200004100000000002104350000000402100039000000200300003900000000003204350000019802000041000001980310009c00000000010280190000004001100210000001b2011001c70000065d000104300003000000000002000001ac01100198000006270000613d000200000003001d000001ac02200198000300000002001d0000063c0000613d000100000001001d00000000001004350000000101000039000000200010043f00000198010000410000000002000414000001980320009c0000000001024019000000c001100210000001ae011001c70000801002000039065b06560000040f00000001022001900000000304000029000006250000613d000000000101043b0000000000400435000000200010043f00000198010000410000000002000414000001980320009c0000000001024019000000c001100210000001ae011001c70000801002000039065b06560000040f00000003060000290000000102200190000006250000613d000000000101043b0000000202000029000000000021041b000000400100043d000000000021043500000198020000410000000003000414000001980430009c0000000003028019000001980410009c00000000010280190000004001100210000000c002300210000000000112019f0000019b011001c70000800d020000390000000303000039000001b9040000410000000105000029065b06510000040f0000000101200190000006250000613d000000000001042d00000000010000190000065d00010430000000400100043d0000006402100039000001bc0300004100000000003204350000004402100039000001bd030000410000000000320435000000240210003900000024030000390000000000320435000001b10200004100000000002104350000000402100039000000200300003900000000003204350000019802000041000001980310009c00000000010280190000004001100210000001b2011001c70000065d00010430000000400100043d0000006402100039000001ba0300004100000000003204350000004402100039000001bb030000410000000000320435000000240210003900000022030000390000000000320435000001b10200004100000000002104350000000402100039000000200300003900000000003204350000019802000041000001980310009c00000000010280190000004001100210000001b2011001c70000065d0001043000000654002104210000000102000039000000000001042d0000000002000019000000000001042d00000659002104230000000102000039000000000001042d0000000002000019000000000001042d0000065b000004320000065c0001042e0000065d000104300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffff000000000000000000000000000000000000000000000000ffffffffffffffff8000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000002000000000000000000000000000000002000000000000000000000000000000400000010000000000000000000000000000000000000000000000000000000000000000000000000040c10f1800000000000000000000000000000000000000000000000000000000a457c2d600000000000000000000000000000000000000000000000000000000a457c2d700000000000000000000000000000000000000000000000000000000a9059cbb00000000000000000000000000000000000000000000000000000000dd62ed3e0000000000000000000000000000000000000000000000000000000040c10f190000000000000000000000000000000000000000000000000000000070a082310000000000000000000000000000000000000000000000000000000095d89b410000000000000000000000000000000000000000000000000000000023b872dc0000000000000000000000000000000000000000000000000000000023b872dd00000000000000000000000000000000000000000000000000000000313ce56700000000000000000000000000000000000000000000000000000000395093510000000000000000000000000000000000000000000000000000000006fdde0300000000000000000000000000000000000000000000000000000000095ea7b30000000000000000000000000000000000000000000000000000000018160ddd000000000000000000000000ffffffffffffffffffffffffffffffffffffffff00000000000000000000000000000000000000200000000000000000000000000200000000000000000000000000000000000040000000000000000000000000207a65726f00000000000000000000000000000000000000000000000000000045524332303a2064656372656173656420616c6c6f77616e63652062656c6f7708c379a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000840000000000000000000000008a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19bddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef45524332303a206d696e7420746f20746865207a65726f20616464726573730000000000000000000000000000000000000000640000000000000000000000004e487b710000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000240000000000000000000000008c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925737300000000000000000000000000000000000000000000000000000000000045524332303a20617070726f766520746f20746865207a65726f206164647265726573730000000000000000000000000000000000000000000000000000000045524332303a20617070726f76652066726f6d20746865207a65726f2061646445524332303a20696e73756666696369656e7420616c6c6f77616e6365000000c2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85bffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000ffffffffffffffffffffffffffffffffffffffffffffffff00000000000000800200000000000000000000000000000000000000000000000000000000000000616c616e6365000000000000000000000000000000000000000000000000000045524332303a207472616e7366657220616d6f756e7420657863656564732062657373000000000000000000000000000000000000000000000000000000000045524332303a207472616e7366657220746f20746865207a65726f2061646472647265737300000000000000000000000000000000000000000000000000000045524332303a207472616e736665722066726f6d20746865207a65726f206164000000000000000000000000000000000000000000000000000000000000000018469939d00da7016fd24775544e09a6a1ad29697146a060aa4a0baa144c2ede", + "linkReferences": {}, + "deployedLinkReferences": {}, + "factoryDeps": {} +} diff --git a/pyproject.toml b/pyproject.toml index 904a4cc..131a092 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "zksync2" -version = "0.5.0" +version = "0.6.0-beta.1" authors = [ { name="Danijel Radakovic", email="danijel@txfusion.io" }, ] diff --git a/zksync2/core/types.py b/zksync2/core/types.py index 55ca73e..2897735 100644 --- a/zksync2/core/types.py +++ b/zksync2/core/types.py @@ -87,3 +87,8 @@ class VmDebugTrace: class PaymasterParams(dict): paymaster: HexStr paymaster_input: bytes + + +class AccountAbstractionVersion(Enum): + NONE = 0 + VERSION_1 = 1 diff --git a/zksync2/manage_contracts/contract_abi/ContractDeployer.json b/zksync2/manage_contracts/contract_abi/ContractDeployer.json index 55dfa54..15dfc3d 100644 --- a/zksync2/manage_contracts/contract_abi/ContractDeployer.json +++ b/zksync2/manage_contracts/contract_abi/ContractDeployer.json @@ -1,5 +1,43 @@ { "abi": [ + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "accountAddress", + "type": "address" + }, + { + "indexed": false, + "internalType": "enum IContractDeployer.AccountNonceOrdering", + "name": "nonceOrdering", + "type": "uint8" + } + ], + "name": "AccountNonceOrderingUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "accountAddress", + "type": "address" + }, + { + "indexed": false, + "internalType": "enum IContractDeployer.AccountAbstractionVersion", + "name": "aaVersion", + "type": "uint8" + } + ], + "name": "AccountVersionUpdated", + "type": "event" + }, { "anonymous": false, "inputs": [ @@ -29,7 +67,7 @@ "inputs": [ { "internalType": "bytes32", - "name": "", + "name": "_salt", "type": "bytes32" }, { @@ -341,7 +379,7 @@ "type": "address" } ], - "stateMutability": "pure", + "stateMutability": "view", "type": "function" }, { diff --git a/zksync2/manage_contracts/contract_abi/IAllowList.json b/zksync2/manage_contracts/contract_abi/IAllowList.json new file mode 100644 index 0000000..abc5a14 --- /dev/null +++ b/zksync2/manage_contracts/contract_abi/IAllowList.json @@ -0,0 +1,283 @@ +{ + "abi": [ + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "target", + "type": "address" + }, + { + "indexed": false, + "internalType": "enum IAllowList.AccessMode", + "name": "previousMode", + "type": "uint8" + }, + { + "indexed": false, + "internalType": "enum IAllowList.AccessMode", + "name": "newMode", + "type": "uint8" + } + ], + "name": "UpdateAccessMode", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "caller", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "target", + "type": "address" + }, + { + "indexed": true, + "internalType": "bytes4", + "name": "functionSig", + "type": "bytes4" + }, + { + "indexed": false, + "internalType": "bool", + "name": "status", + "type": "bool" + } + ], + "name": "UpdateCallPermission", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_caller", + "type": "address" + }, + { + "internalType": "address", + "name": "_target", + "type": "address" + }, + { + "internalType": "bytes4", + "name": "_functionSig", + "type": "bytes4" + } + ], + "name": "canCall", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_target", + "type": "address" + } + ], + "name": "getAccessMode", + "outputs": [ + { + "internalType": "enum IAllowList.AccessMode", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_l1Token", + "type": "address" + } + ], + "name": "getTokenDepositLimitData", + "outputs": [ + { + "components": [ + { + "internalType": "bool", + "name": "depositLimitation", + "type": "bool" + }, + { + "internalType": "uint256", + "name": "depositCap", + "type": "uint256" + } + ], + "internalType": "struct IAllowList.Deposit", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_caller", + "type": "address" + }, + { + "internalType": "address", + "name": "_target", + "type": "address" + }, + { + "internalType": "bytes4", + "name": "_functionSig", + "type": "bytes4" + } + ], + "name": "hasSpecialAccessToCall", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_target", + "type": "address" + }, + { + "internalType": "enum IAllowList.AccessMode", + "name": "_accessMode", + "type": "uint8" + } + ], + "name": "setAccessMode", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address[]", + "name": "_targets", + "type": "address[]" + }, + { + "internalType": "enum IAllowList.AccessMode[]", + "name": "_accessMode", + "type": "uint8[]" + } + ], + "name": "setBatchAccessMode", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address[]", + "name": "_callers", + "type": "address[]" + }, + { + "internalType": "address[]", + "name": "_targets", + "type": "address[]" + }, + { + "internalType": "bytes4[]", + "name": "_functionSigs", + "type": "bytes4[]" + }, + { + "internalType": "bool[]", + "name": "_enables", + "type": "bool[]" + } + ], + "name": "setBatchPermissionToCall", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_l1Token", + "type": "address" + }, + { + "internalType": "bool", + "name": "_depositLimitation", + "type": "bool" + }, + { + "internalType": "uint256", + "name": "_depositCap", + "type": "uint256" + } + ], + "name": "setDepositLimit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_caller", + "type": "address" + }, + { + "internalType": "address", + "name": "_target", + "type": "address" + }, + { + "internalType": "bytes4", + "name": "_functionSig", + "type": "bytes4" + }, + { + "internalType": "bool", + "name": "_enable", + "type": "bool" + } + ], + "name": "setPermissionToCall", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } + ] +} diff --git a/zksync2/manage_contracts/contract_abi/IERC1271.json b/zksync2/manage_contracts/contract_abi/IERC1271.json new file mode 100644 index 0000000..5e15311 --- /dev/null +++ b/zksync2/manage_contracts/contract_abi/IERC1271.json @@ -0,0 +1,28 @@ +{ + "abi": [ + { + "inputs": [ + { + "internalType": "bytes32", + "name": "hash", + "type": "bytes32" + }, + { + "internalType": "bytes", + "name": "signature", + "type": "bytes" + } + ], + "name": "isValidSignature", + "outputs": [ + { + "internalType": "bytes4", + "name": "magicValue", + "type": "bytes4" + } + ], + "stateMutability": "view", + "type": "function" + } + ] +} \ No newline at end of file diff --git a/zksync2/manage_contracts/contract_abi/IL1Bridge.json b/zksync2/manage_contracts/contract_abi/IL1Bridge.json index f0cb575..8908bec 100644 --- a/zksync2/manage_contracts/contract_abi/IL1Bridge.json +++ b/zksync2/manage_contracts/contract_abi/IL1Bridge.json @@ -28,6 +28,12 @@ { "anonymous": false, "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "l2DepositTxHash", + "type": "bytes32" + }, { "indexed": true, "internalType": "address", @@ -41,7 +47,7 @@ "type": "address" }, { - "indexed": true, + "indexed": false, "internalType": "address", "name": "l1Token", "type": "address" @@ -150,6 +156,11 @@ "internalType": "uint256", "name": "_l2TxGasPerPubdataByte", "type": "uint256" + }, + { + "internalType": "address", + "name": "_refundRecipient", + "type": "address" } ], "name": "deposit", @@ -220,6 +231,19 @@ "stateMutability": "view", "type": "function" }, + { + "inputs": [], + "name": "l2Bridge", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, { "inputs": [ { diff --git a/zksync2/manage_contracts/contract_abi/IL1Messenger.json b/zksync2/manage_contracts/contract_abi/IL1Messenger.json new file mode 100644 index 0000000..b2bbdd5 --- /dev/null +++ b/zksync2/manage_contracts/contract_abi/IL1Messenger.json @@ -0,0 +1,48 @@ +{ + "abi": [ + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "_sender", + "type": "address" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "_hash", + "type": "bytes32" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "_message", + "type": "bytes" + } + ], + "name": "L1MessageSent", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "_message", + "type": "bytes" + } + ], + "name": "sendToL1", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "nonpayable", + "type": "function" + } + ] +} diff --git a/zksync2/manage_contracts/contract_abi/IL2Bridge.json b/zksync2/manage_contracts/contract_abi/IL2Bridge.json index e62a099..d6ca3ce 100644 --- a/zksync2/manage_contracts/contract_abi/IL2Bridge.json +++ b/zksync2/manage_contracts/contract_abi/IL2Bridge.json @@ -92,7 +92,7 @@ ], "name": "finalizeDeposit", "outputs": [], - "stateMutability": "nonpayable", + "stateMutability": "payable", "type": "function" }, { diff --git a/zksync2/manage_contracts/contract_encoder_base.py b/zksync2/manage_contracts/contract_encoder_base.py index ab82574..22ed5a8 100644 --- a/zksync2/manage_contracts/contract_encoder_base.py +++ b/zksync2/manage_contracts/contract_encoder_base.py @@ -1,4 +1,5 @@ import json +from enum import Enum from pathlib import Path from typing import Any, Optional from eth_typing import HexStr @@ -8,13 +9,21 @@ from web3._utils.contracts import encode_abi +class JsonConfiguration(Enum): + COMBINED = "combined" + STANDARD = "standard" + + class BaseContractEncoder: @classmethod - def from_json(cls, web3: Web3, compiled_contract: Path): + def from_json(cls, web3: Web3, compiled_contract: Path, conf_type: JsonConfiguration = JsonConfiguration.COMBINED): with compiled_contract.open(mode='r') as json_f: data = json.load(json_f) - return cls(web3, abi=data["abi"]) + if conf_type == JsonConfiguration.COMBINED: + return [cls(web3, abi=v["abi"], bytecode=v["bin"]) for k, v in data["contracts"].items()] + else: + return cls(web3, abi=data["abi"], bytecode=data["bytecode"]) def __init__(self, web3: Web3, abi, bytecode: Optional[bytes] = None): self.web3 = web3 @@ -34,14 +43,6 @@ def contract(self): class ContractEncoder(BaseContractEncoder): - @classmethod - def from_json(cls, web3: Web3, compiled_contract: Path): - with compiled_contract.open(mode='r') as json_f: - data = json.load(json_f) - # bytecode = bytes.fromhex(remove_0x_prefix(data["bytecode"])) - # return cls(web3, abi=data["abi"], bytecode=bytecode) - return [cls(web3, abi=v["abi"], bytecode=v["bin"]) for k, v in data["contracts"].items()] - def __init__(self, web3: Web3, abi, bytecode): super(ContractEncoder, self).__init__(web3, abi, bytecode) diff --git a/zksync2/manage_contracts/erc20_contract.py b/zksync2/manage_contracts/erc20_contract.py index dff899e..ccef7a6 100644 --- a/zksync2/manage_contracts/erc20_contract.py +++ b/zksync2/manage_contracts/erc20_contract.py @@ -12,7 +12,7 @@ erc_20_abi_cache = None -def _erc_20_abi_default(): +def get_erc20_abi(): global erc_20_abi_cache if erc_20_abi_cache is None: @@ -33,7 +33,7 @@ def __init__(self, web3: Module, check_sum_address = Web3.to_checksum_address(contract_address) self.contract_address = check_sum_address self.module = web3 - self.contract = self.module.contract(self.contract_address, abi=_erc_20_abi_default()) + self.contract = self.module.contract(self.contract_address, abi=get_erc20_abi()) self.account = account def _nonce(self) -> int: @@ -85,5 +85,5 @@ class ERC20Encoder(BaseContractEncoder): def __init__(self, web3: Web3, abi: Optional[dict] = None): if abi is None: - abi = _erc_20_abi_default() + abi = get_erc20_abi() super(ERC20Encoder, self).__init__(web3, abi) diff --git a/zksync2/manage_contracts/paymaster_utils.py b/zksync2/manage_contracts/paymaster_utils.py index eeac8b4..c37935e 100644 --- a/zksync2/manage_contracts/paymaster_utils.py +++ b/zksync2/manage_contracts/paymaster_utils.py @@ -25,7 +25,7 @@ def __init__(self, web3: Web3): super(PaymasterFlowEncoder, self).__init__(web3, abi=_paymaster_flow_abi_default()) def encode_approval_based(self, address: HexStr, min_allowance: int, inner_input: bytes) -> HexStr: - return self.encode_method(fn_name="approvalBased", args=[address, min_allowance, inner_input]) + return self.encode_method(fn_name="approvalBased", args=(address, min_allowance, inner_input)) def encode_general(self, inputs: bytes) -> HexStr: - return self.encode_method(fn_name="general", args=[inputs]) + return self.encode_method(fn_name="general", args=tuple([inputs])) diff --git a/zksync2/manage_contracts/precompute_contract_deployer.py b/zksync2/manage_contracts/precompute_contract_deployer.py index d19d0f5..6c91e23 100644 --- a/zksync2/manage_contracts/precompute_contract_deployer.py +++ b/zksync2/manage_contracts/precompute_contract_deployer.py @@ -1,14 +1,16 @@ import importlib.resources as pkg_resources -from eth_typing import HexStr -from web3 import Web3 -from typing import Optional import json +from typing import Optional +from eth_typing import HexStr +from eth_utils.crypto import keccak +from web3 import Web3 from web3.logs import DISCARD from web3.types import Nonce, TxReceipt -from eth_utils.crypto import keccak -from zksync2.manage_contracts import contract_abi + +from zksync2.core.types import AccountAbstractionVersion from zksync2.core.utils import pad_front_bytes, to_bytes, int_to_bytes, hash_byte_code +from zksync2.manage_contracts import contract_abi from zksync2.manage_contracts.contract_encoder_base import BaseContractEncoder icontract_deployer_abi_cache = None @@ -29,6 +31,8 @@ class PrecomputeContractDeployer: DEFAULT_SALT = b'\0' * 32 CREATE_FUNC = "create" CREATE2_FUNC = "create2" + CREATE_ACCOUNT_FUNC = "createAccount" + CREATE2_ACCOUNT_FUNC = "create2Account" MAX_BYTE_CODE_LENGTH = 2 ** 16 EMPTY_BYTES = b'' @@ -58,19 +62,44 @@ def encode_create2(self, bytecode: bytes, return self.contract_encoder.encode_method(fn_name=self.CREATE2_FUNC, args=args) - def encode_create(self, bytecode: bytes, call_data: Optional[bytes] = None, salt_data: Optional[bytes] = None): - if salt_data is None: - salt_data = self.DEFAULT_SALT + def encode_create(self, bytecode: bytes, call_data: Optional[bytes] = None) -> HexStr: if call_data is None: call_data = self.EMPTY_BYTES - if len(salt_data) != 32: + bytecode_hash = hash_byte_code(bytecode) + args = self.DEFAULT_SALT, bytecode_hash, call_data + + return self.contract_encoder.encode_method(fn_name=self.CREATE_FUNC, args=args) + + def encode_create2_account(self, bytecode: bytes, + call_data: Optional[bytes] = None, + salt: Optional[bytes] = None, + version: AccountAbstractionVersion = AccountAbstractionVersion.VERSION_1 + ) -> HexStr: + if salt is None: + salt = self.DEFAULT_SALT + if call_data is None: + call_data = self.EMPTY_BYTES + + if len(salt) != 32: raise OverflowError("Salt data must be 32 length") bytecode_hash = hash_byte_code(bytecode) - args = salt_data, bytecode_hash, call_data + args = salt, bytecode_hash, call_data, version.value - return self.contract_encoder.encode_method(fn_name=self.CREATE_FUNC, args=args) + return self.contract_encoder.encode_method(fn_name=self.CREATE2_ACCOUNT_FUNC, args=args) + + def encode_create_account(self, bytecode: bytes, + call_data: Optional[bytes] = None, + version: AccountAbstractionVersion = AccountAbstractionVersion.VERSION_1 + ) -> HexStr: + if call_data is None: + call_data = self.EMPTY_BYTES + + bytecode_hash = hash_byte_code(bytecode) + args = self.DEFAULT_SALT, bytecode_hash, call_data, version.value + + return self.contract_encoder.encode_method(fn_name=self.CREATE_ACCOUNT_FUNC, args=args) def compute_l2_create_address(self, sender: HexStr, nonce: Nonce) -> HexStr: sender_bytes = to_bytes(sender) @@ -87,7 +116,7 @@ def compute_l2_create2_address(self, sender: HexStr, bytecode: bytes, constructor: bytes, - salt: bytes): + salt: bytes) -> HexStr: if len(salt) != 32: raise OverflowError("Salt data must be 32 length") @@ -106,4 +135,3 @@ def extract_contract_address(self, receipt: TxReceipt) -> HexStr: entry = result[1]["args"] addr = entry["contractAddress"] return addr - diff --git a/zksync2/provider/eth_provider.py b/zksync2/provider/eth_provider.py index 8fe2688..5f4095f 100644 --- a/zksync2/provider/eth_provider.py +++ b/zksync2/provider/eth_provider.py @@ -106,7 +106,7 @@ def deposit(self, operator_tip: int = 0, bridge_address: HexStr = None, approve_erc20: bool = False, - l2_gas_limit: int = RECOMMENDED_DEPOSIT_L2_GAS_LIMIT, + l2_gas_limit: int = RecommendedGasLimit.DEPOSIT.value, gas_per_pubdata_byte: int = DEPOSIT_GAS_PER_PUBDATA_LIMIT, gas_price: int = None, gas_limit: int = None @@ -127,7 +127,7 @@ def deposit(self, base_cost = self.get_base_cost(gas_price=gas_price, gas_per_pubdata_byte=gas_per_pubdata_byte, - gas_limit=l2_gas_limit) + l2_gas_limit=l2_gas_limit) if token.is_eth(): value = base_cost + operator_tip + amount @@ -178,7 +178,7 @@ def request_execute(self, base_cost = self.get_base_cost(gas_price=gas_price, gas_per_pubdata_byte=gas_per_pubdata_byte, - gas_limit=l2_gas_limit) + l2_gas_limit=l2_gas_limit) value = base_cost + operator_tip + l2_value check_base_cost(base_cost, value) diff --git a/zksync2/transaction/transaction_builders.py b/zksync2/transaction/transaction_builders.py index 55f66f8..d76973f 100644 --- a/zksync2/transaction/transaction_builders.py +++ b/zksync2/transaction/transaction_builders.py @@ -1,16 +1,18 @@ from abc import ABC from typing import Optional, List + from eth_account.signers.base import BaseAccount from eth_typing import HexStr from web3 import Web3 from web3.types import Nonce + from zksync2.core.types import Token, BridgeAddresses, L2_ETH_TOKEN_ADDRESS -from zksync2.manage_contracts.precompute_contract_deployer import PrecomputeContractDeployer from zksync2.manage_contracts.deploy_addresses import ZkSyncAddresses from zksync2.manage_contracts.eth_token import EthToken from zksync2.manage_contracts.l2_bridge import L2Bridge -from zksync2.transaction.transaction712 import Transaction712 +from zksync2.manage_contracts.precompute_contract_deployer import PrecomputeContractDeployer from zksync2.module.request_types import EIP712Meta, TransactionType, Transaction as ZkTx +from zksync2.transaction.transaction712 import Transaction712 class TxBase(ABC): @@ -46,8 +48,14 @@ def __init__(self, data: HexStr = HexStr("0x"), gas_limit: int = 0, gas_price: int = 0, - max_priority_fee_per_gas=100000000): - default_meta = EIP712Meta() + max_priority_fee_per_gas=100_000_000, + paymaster_params=None, + custom_signature=None): + eip712_meta = EIP712Meta(gas_per_pub_data=EIP712Meta.GAS_PER_PUB_DATA_DEFAULT, + custom_signature=custom_signature, + factory_deps=None, + paymaster_params=paymaster_params) + super(TxFunctionCall, self).__init__( trans={ "chain_id": chain_id, @@ -60,7 +68,7 @@ def __init__(self, "value": value, "data": data, "transactionType": TransactionType.EIP_712_TX_TYPE.value, - "eip712Meta": default_meta + "eip712Meta": eip712_meta }) @@ -71,19 +79,16 @@ def __init__(self, chain_id: int, nonce: int, from_: HexStr, - gas_limit: int, - gas_price: int, bytecode: bytes, + gas_price: int, + gas_limit: int = 0, deps: List[bytes] = None, call_data: Optional[bytes] = None, value: int = 0, - max_priority_fee_per_gas=100000000, - salt: Optional[bytes] = None): - + max_priority_fee_per_gas=100_000_000 + ): contract_deployer = PrecomputeContractDeployer(web3) - generated_call_data = contract_deployer.encode_create(bytecode=bytecode, - call_data=call_data, - salt_data=salt) + generated_call_data = contract_deployer.encode_create(bytecode=bytecode, call_data=call_data) factory_deps = [] if deps is not None: for dep in deps: @@ -122,7 +127,7 @@ def __init__(self, deps: List[bytes] = None, call_data: Optional[bytes] = None, value: int = 0, - max_priority_fee_per_gas=100000000, + max_priority_fee_per_gas=100_000_000, salt: Optional[bytes] = None ): contract_deployer = PrecomputeContractDeployer(web3) @@ -154,6 +159,93 @@ def __init__(self, }) +class TxCreateAccount(TxBase, ABC): + + def __init__(self, + web3: Web3, + chain_id: int, + nonce: int, + from_: HexStr, + bytecode: bytes, + gas_price: int, + gas_limit: int = 0, + deps: List[bytes] = None, + call_data: Optional[bytes] = None, + value: int = 0, + max_priority_fee_per_gas=100_000_000 + ): + contract_deployer = PrecomputeContractDeployer(web3) + generated_call_data = contract_deployer.encode_create_account(bytecode=bytecode, call_data=call_data) + factory_deps = [] + if deps is not None: + for dep in deps: + factory_deps.append(dep) + factory_deps.append(bytecode) + eip712_meta = EIP712Meta(gas_per_pub_data=EIP712Meta.GAS_PER_PUB_DATA_DEFAULT, + custom_signature=None, + factory_deps=factory_deps, + paymaster_params=None) + + super(TxCreateAccount, self).__init__(trans={ + "chain_id": chain_id, + "nonce": nonce, + "from": from_, + "to": Web3.to_checksum_address(ZkSyncAddresses.CONTRACT_DEPLOYER_ADDRESS.value), + "gas": gas_limit, + "gasPrice": gas_price, + "maxPriorityFeePerGas": max_priority_fee_per_gas, + "value": value, + "data": HexStr(generated_call_data), + "transactionType": TransactionType.EIP_712_TX_TYPE.value, + "eip712Meta": eip712_meta + }) + + +class TxCreate2Account(TxBase, ABC): + + def __init__(self, + web3: Web3, + chain_id: int, + nonce: int, + from_: HexStr, + gas_limit: int, + gas_price: int, + bytecode: bytes, + deps: List[bytes] = None, + call_data: Optional[bytes] = None, + value: int = 0, + max_priority_fee_per_gas=100_000_000, + salt: Optional[bytes] = None + ): + contract_deployer = PrecomputeContractDeployer(web3) + generated_call_data = contract_deployer.encode_create2_account(bytecode=bytecode, + call_data=call_data, + salt=salt) + factory_deps = [] + if deps is not None: + for dep in deps: + factory_deps.append(dep) + factory_deps.append(bytecode) + + eip712_meta = EIP712Meta(gas_per_pub_data=EIP712Meta.GAS_PER_PUB_DATA_DEFAULT, + custom_signature=None, + factory_deps=factory_deps, + paymaster_params=None) + super(TxCreate2Account, self).__init__(trans={ + "chain_id": chain_id, + "nonce": nonce, + "from": from_, + "to": Web3.to_checksum_address(ZkSyncAddresses.CONTRACT_DEPLOYER_ADDRESS.value), + "gas": gas_limit, + "gasPrice": gas_price, + "maxPriorityFeePerGas": max_priority_fee_per_gas, + "value": value, + "data": HexStr(generated_call_data), + "transactionType": TransactionType.EIP_712_TX_TYPE.value, + "eip712Meta": eip712_meta + }) + + class TxWithdraw(TxBase, ABC): def __init__(self,