Package: eth-tester
eth-testerTools for testing Ethereum applicationsRead more in the documentation below.View the change log.Quick Startpython-mpipinstalleth-tester>>>frometh_testerimportEthereumTester>>>t=EthereumTester()>>>t.get_accounts()('0x7E5F4552091A69125d5DfCb7b8C2659029395Bdf','0x2B5AD5c4795c026514f8317c7a215E218DcCD6cF','0x6813Eb9362372EEF6200f3b1dbC3f819671cBA69','0x1efF47bc3a10a45D4B230B5d10E37751FE6AA718','0xe1AB8145F7E55DC933d51a18c793F901A3A0b276','0xE57bFE9F44b819898F47BF37E5AF72a0783e1141','0xd41c057fd1c78805AAC12B0A94a405c0461A6FBb','0xF1F6619B38A98d6De0800F1DefC0a6399eB6d30C','0xF7Edc8FA1eCc32967F827C9043FcAe6ba73afA5c','0x4CCeBa2d7D2B4fdcE4304d3e09a1fea9fbEb1528')>>>t.get_balance('0x7E5F4552091A69125d5DfCb7b8C2659029395Bdf')1000000000000000000000000>>>t.send_transaction({...'from':'0x7E5F4552091A69125d5DfCb7b8C2659029395Bdf',...'to':'0x2B5AD5c4795c026514f8317c7a215E218DcCD6cF',...'gas':30000,...'value':1,...'max_fee_per_gas':1000000000,...'max_priority_fee_per_gas':1000000000,...'chain_id':131277322940537,...'access_list':(...{...'address':'0xde0b295669a9fd93d5f28d9ec85e40f4cb697bae',...'storage_keys':(...'0x0000000000000000000000000000000000000000000000000000000000000003',...'0x0000000000000000000000000000000000000000000000000000000000000007',...)...},...{...'address':'0xbb9bc244d798123fde783fcc1c72d3bb8c189413',...'storage_keys':()...},...)...})'0xc20b90af87bc65c3d748cf0a1fa54f3a86ffc94348e0fd91a70f1c5ba6ef4109'>>>t.get_transaction_by_hash('0xc20b90af87bc65c3d748cf0a1fa54f3a86ffc94348e0fd91a70f1c5ba6ef4109'){'type':'0x2','hash':'0xc20b90af87bc65c3d748cf0a1fa54f3a86ffc94348e0fd91a70f1c5ba6ef4109','nonce':0,'block_hash':'0x28b95514984b0abbd91d88f1a542eaeeb810c24e0234e09891b7d6b3f94f47ed','block_number':1,'transaction_index':0,'from':'0x7E5F4552091A69125d5DfCb7b8C2659029395Bdf','to':'0x2B5AD5c4795c026514f8317c7a215E218DcCD6cF','value':1,'gas':30000,'data':'0x','r':60071646517429056848243893841817235885102606421189844318110381014348740252962,'s':55731679314783756278323646144996847004593793888590884914350251538533006990589,'v':0,'chain_id':131277322940537,'max_fee_per_gas':1000000000,'max_priority_fee_per_gas':1000000000,'access_list':({'address':'0xde0B295669a9FD93d5F28D9Ec85E40f4cb697BAe','storage_keys':('0x0000000000000000000000000000000000000000000000000000000000000003','0x0000000000000000000000000000000000000000000000000000000000000007')},{'address':'0xBB9bc244D798123fDe783fCc1C72d3Bb8C189413','storage_keys':()}),'gas_price':1000000000}>>>t.get_transaction_receipt('0xc20b90af87bc65c3d748cf0a1fa54f3a86ffc94348e0fd91a70f1c5ba6ef4109'){'transaction_hash':'0xc20b90af87bc65c3d748cf0a1fa54f3a86ffc94348e0fd91a70f1c5ba6ef4109','transaction_index':0,'block_number':1,'block_hash':'0x28b95514984b0abbd91d88f1a542eaeeb810c24e0234e09891b7d6b3f94f47ed','cumulative_gas_used':29600,'gas_used':29600,'effective_gas_price':1000000000,'contract_address':None,'logs':(),'type':'0x2','status':1}DocumentationInput and output data formatsThe ethereum tester library strictly enforces the following input formats and
types.Hexadecimal valuesmustbe text (not byte) strings.  The0xprefix is optional.Any address which contains mixed-case alpha characters will be validated as a checksummed address as specified byEIP-5532-byte hashesmustbe hexadecimal encoded.Numeric valuesmustbe in their integer representation.Similarly, ethereum tester ensures that return values conform to similar rules.32-byte hashes will be returned in their hexadecimal encoded representation.Addresses will be returned in their hexadecimal representation and EIP55 checksummed.Numeric values will be returned as integers.Block NumbersAnyblock_numberparameter will accept the following string values.'latest': for the latest mined block.'pending': for the current un-mined block.'earliest': for the genesis block.'safe': for the last block that has passed 2/3 of attestations post-merge.'finalized': for the last finalized block post-merge.Note: Thesemustbe text strings (not byte stringS)eth_tester.EthereumTesterAPIInstantiationeth_tester.EthereumTester(backend=None, validator=None, normalizer=None, auto_mine_transactions=True, fork_blocks=None)TheEthereumTesterobject is the sole API entrypoint.  Instantiation of this
object accepts the following parameters.backend: The chain backend being used.  See thechain backendsvalidator: The validator being used.  See thevalidatorsnormalizer: The normalizer being used.  See thenormalizersauto_mine_transactions: Iftruthytransactions will be automatically mined at the time they are submitted.  Seeenable_auto_mine_transactionsanddisable_auto_mine_transactions.fork_blocks: configures which block numbers the various network hard fork rules will be activated.  Seefork-rules>>>frometh_testerimportEthereumTester>>>t=EthereumTester()>>>t<eth_tester.main.EthereumTesterat0x102255710>Fork RulesEthereum tester uses the Paris (PoS) fork rules, starting at block 0.Time TravelThe chain can only time travel forward in time.EthereumTester.time_travel(timestamp)Thetimestampmust be an integer, strictly greater than the current timestamp
of the latest block.Note: Time traveling will result in a new block being mined.MiningManually mining blocks can be done with the following API.  Thecoinbaseparameter of these methodsmustbe a hexadecimal encoded address.EthereumTester.mine_blocks(num_blocks=1, coinbase=ZERO_ADDRESS)Minesnum_blocksnew blocks, returning an iterable of the newly mined block hashes.EthereumTester.mine_block(coinbase=ZERO_ADDRESS)Mines a single new block, returning the mined block's hash.Auto-mining transactionsBy default, all transactions are mined immediately.  This means that each transaction you send will result in a new block being mined, and that all blocks will only ever have at most a single transaction.  This behavior can be controlled with the following methods.EthereumTester.enable_auto_mine_transactions()Turns on auto-mining of transactions.EthereumTester.disable_auto_mine_transactions()Turnsoffauto-mining of transactions.AccountsThe following API can be used to interact with account data.  Theaccountparameter in these methodsmustbe a hexadecimal encode address.EthereumTester.get_accounts()Returns an iterable of the accounts that the tester knows about.  All accounts
in this list will be EIP55 checksummed.>>>t.get_accounts()('0x82A978B3f5962A5b0957d9ee9eEf472EE55B42F1','0x7d577a597B2742b498Cb5Cf0C26cDCD726d39E6e',...'0x90F0B1EBbbA1C1936aFF7AAf20a7878FF9e04B6c')EthereumTester.add_account(private_key, password=None)Adds a new account for the given private key.  Returns the hex encoded address
of the added account.>>>t.add_account('0x58d23b55bc9cdce1f18c2500f40ff4ab7245df9a89505e9b1fa4851f623d241d')'0xdc544d1aa88ff8bbd2f2aec754b1f1e99e1812fd'By default, added accounts are unlocked and do not have a password.  If you
would like to add an account which has a password, you can supply the password
as the second parameter.>>>t.add_account('0x58d23b55bc9cdce1f18c2500f40ff4ab7245df9a89505e9b1fa4851f623d241d','my-secret')'0xdc544d1aa88ff8bbd2f2aec754b1f1e99e1812fd'EthereumTester.unlock_account(account, password, unlock_seconds=None)Unlocks the given account if the provided password matches.Raises aValidationErrorif:The account is not known.The password does not match.The account was created without a password.>>>t.unlock_account('0xdc544d1aa88ff8bbd2f2aec754b1f1e99e1812fd','my-secret')By default, accounts will be unlocked indefinitely.  You can however unlock an
account for a specified amount of time by providing the desired duration in
seconds.# unlock for 1 hour.>>>t.unlock_account('0xdc544d1aa88ff8bbd2f2aec754b1f1e99e1812fd','my-secret',60*60)EthereumTester.lock_account(account)Locks the provided account.Raises aValidationErrorif:The account is not knownThe account does not have a password.EthereumTester.get_balance(account) -> integerReturns the balance, in wei, for the provided account.>>>t.get_balance('0x82A978B3f5962A5b0957d9ee9eEf472EE55B42F1')1000004999999999999999999EthereumTester.get_nonce(account) -> integerReturns the nonce for the provided account.>>>t.get_nonce('0x82A978B3f5962A5b0957d9ee9eEf472EE55B42F1')1EthereumTester.get_code(account) -> hex stringReturns the code for the given account.>>>t.get_code('0x82A978B3f5962A5b0957d9ee9eEf472EE55B42F1')"0x"Blocks, Transactions, and ReceiptsEthereumTester.get_transaction_by_hash(transaction_hash) -> transaction-objectReturns the transaction for the given hash, raising aTransactionNotFoundexception if the
transaction cannot be found.>>>t.get_transaction_by_hash('0x21ae665f707e12a5f1bb13ef8c706b65cc5accfd03e7067ce683d831f51122e6'){'type':'0x2','hash':'0x21ae665f707e12a5f1bb13ef8c706b65cc5accfd03e7067ce683d831f51122e6','nonce':0,'block_hash':'0x810731efeb7498fc0ac3bc7c72a71571b672c9fdbfbfd8b435f483e368e8ef7e','block_number':1,'transaction_index':0,'from':'0x2B5AD5c4795c026514f8317c7a215E218DcCD6cF','to':'0x7E5F4552091A69125d5DfCb7b8C2659029395Bdf','value':1337,'gas':21000,'data':'0x','r':1713666669454033023988006960017431058214051587080823768269189498559514600280,'s':32003859822305799628524852194521134173285969678963273753063458725692016415033,'v':0,'chain_id':131277322940537,'max_fee_per_gas':2000000000,'max_priority_fee_per_gas':500000000,'access_list':(),'gas_price':1375000000}Note: For unmined transaction,transaction_index,block_numberandblock_hashwill all beNone.EthereumTester.get_block_by_number(block_number, full_transactions=False) -> block-objectReturns the block for the givenblock_number.  Seeblock
numbersfor named block numbers you can use.  Iffull_transactionsis truthy, then the transactions array will be populated
with full transaction objects as opposed to their hashes.RaisesBlockNotFoundif a block for the given number
cannot be found.>>>t.get_block_by_number(1){'number':1,'hash':'0xd481955268d1f3db58ee61685a899a35e33e8fd35b9cc0812f85b9f06757140e','parent_hash':'0x5be984ab842071903ee443a5dee92603bef42de35b4e10928e753f7e88a7163a','nonce':'0x0000000000000000','sha3_uncles':'0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347','logs_bloom':0,'transactions_root':'0xef1e11d99f7db22fd93c6a10d44753d4a93e9f6ecb2f1e5030a0a91f1d3b07ac','receipts_root':'0x611e48488cf80b4c31f01ad45b6ebea533a68255a6d0240d434d9366a3582010','state_root':'0x9ce568dcaa6f130d733b333304f2c26a19334ed328a7eb9bb31707306381ba65','coinbase':'0x0000000000000000000000000000000000000000','difficulty':0,'total_difficulty':0,'mix_hash':'0x0000000000000000000000000000000000000000000000000000000000000000','size':751,'extra_data':'0x0000000000000000000000000000000000000000000000000000000000000000','gas_limit':3141592,'gas_used':29600,'timestamp':1633669276,'transactions':('0xc20b90af87bc65c3d748cf0a1fa54f3a86ffc94348e0fd91a70f1c5ba6ef4109',),'uncles':(),'base_fee_per_gas':875000000}EthereumTester.get_block_by_hash(block_hash, full_transactions=True) -> block-objectReturns the block for the givenblock_hash.  Thefull_transactionsparameter behaves the same as inget_block_by_number.RaisesBlockNotFoundif a block for the given hash
cannot be found.>>>t.get_block_by_hash('0x0f50c8ea0f67ce0b7bff51ae866159edc443bde87de2ab26010a15b777244ddd'){'number':1,'hash':'0xd481955268d1f3db58ee61685a899a35e33e8fd35b9cc0812f85b9f06757140e','parent_hash':'0x5be984ab842071903ee443a5dee92603bef42de35b4e10928e753f7e88a7163a','nonce':'0x0000000000000000','sha3_uncles':'0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347','logs_bloom':0,'transactions_root':'0xef1e11d99f7db22fd93c6a10d44753d4a93e9f6ecb2f1e5030a0a91f1d3b07ac','receipts_root':'0x611e48488cf80b4c31f01ad45b6ebea533a68255a6d0240d434d9366a3582010','state_root':'0x9ce568dcaa6f130d733b333304f2c26a19334ed328a7eb9bb31707306381ba65','coinbase':'0x0000000000000000000000000000000000000000','difficulty':0,'total_difficulty':0,'mix_hash':'0x0000000000000000000000000000000000000000000000000000000000000000','size':751,'extra_data':'0x0000000000000000000000000000000000000000000000000000000000000000','gas_limit':3141592,'gas_used':29600,'timestamp':1633669276,'transactions':('0xc20b90af87bc65c3d748cf0a1fa54f3a86ffc94348e0fd91a70f1c5ba6ef4109',),'uncles':(),'base_fee_per_gas':875000000}EthereumTester.get_transaction_receipt(transaction_hash)Returns the receipt for the giventransaction_hash, raisingTransactionNotFoundif no transaction can be
found for the given hash.>>>t.get_transaction_receipt('0x9a7cc8b7accf54ecb1901bf4d0178f28ca457bb9f9c245692c0ca8fabef08d3b'){'block_hash':'0x878f779d8bb25b25fb78fc16b8d64d70a5961310ef1689571aec632e9424290c','block_number':2,'contract_address':None,'cumulative_gas_used':23154,'gas_used':23154,'logs':({'address':'0xd6F084Ee15E38c4f7e091f8DD0FE6Fe4a0E203Ef','block_hash':'0x878f779d8bb25b25fb78fc16b8d64d70a5961310ef1689571aec632e9424290c','block_number':2,'data':'0x','log_index':0,'topics':('0xf70fe689e290d8ce2b2a388ac28db36fbb0e16a6d89c6804c461f65a1b40bb15','0x0000000000000000000000000000000000000000000000000000000000003039'),'transaction_hash':'0x9a7cc8b7accf54ecb1901bf4d0178f28ca457bb9f9c245692c0ca8fabef08d3b','transaction_index':0,'type':'mined'},),'transaction_hash':'0x9a7cc8b7accf54ecb1901bf4d0178f28ca457bb9f9c245692c0ca8fabef08d3b','transaction_index':0}Receipts for unmined transactions will have all ofblock_hash,block_numberandtransaction_indexset toNone.Receipts for transactions which create a contract will have the created contract address in thecontract_addressfield.Transaction SendingA transaction is a formatted as a dictionary with the following keys and
values.from: The address of the account sending the transaction (hexadecimal string).to: The address of the account the transaction is being sent to.  Empty string should be used to trigger contract creation (hexadecimal string).gas: Sets the gas limit for transaction execution (integer).value: The amount of ether in wei that should be sent with the transaction (integer).data: The data for the transaction (hexadecimal string).chain_id: The integer id for the chain the transaction is meant to interact with.In addition to the above, the following parameters are added based on the type of transaction being sent:Legacy transactionsgas_price: Sets the price per unit of gas in wei that will be paid for transaction execution (integer).Access list transactions (EIP-2930)gas_price: Sets the price per unit of gas in wei that will be paid for transaction execution (integer).access_list(optional): Specifies accounts and storage slots expected to be accessed, based on the transaction, in order to
gain a discount on the gas for those executions (see quickstart example for usage).Dynamic fee transactions (EIP-1559)max_fee_per_gas: Sets the maximum fee per unit of gas in wei that will be paid for transaction execution (integer).max_priority_fee_per_gas: Sets the fee per unit of gas in wei that is sent to the coinbase address as an incentive for including the transaction (integer).access_list(optional): Specifies accounts and storage slots expected to be accessed, based on the transaction, in order to
gain a discount on the gas for those executions (see quickstart example for usage).MethodsEthereumTester.send_transaction(transaction) -> transaction_hashSends the providedtransactionobject, returning thetransaction_hashfor
the sent transaction.EthereumTester.call(transaction, block_number='latest')Executes the providedtransactionobject at the evm state from the block
denoted by theblock_numberparameter, returning the resulting bytes return
value from the evm.EthereumTester.estimate_gas(transaction)Executes the providedtransactionobject, measuring and returning the gas
consumption.EthereumTester.get_fee_history(block_count=1, newest_block='latest', reward_percentiles=[])Return the historical gas information for the number of blocks specified as theblock_countstarting fromnewest_block.
Note that specifyingreward_percentileshas no effect on the response and sorewardwill always return an empty list.Logs and FiltersEthereumTester.create_block_filter() -> integerCreates a new filter for newly mined blocks.  Returns thefilter_idwhich can
be used to retrieve the block hashes for the mined blocks.>>>filter_id=t.create_block_filter()>>>filter_id=t.create_block_filter()>>>t.mine_blocks(3)>>>t.get_only_filter_changes(filter_id)('0x07004287f82c1a7ab15d7b8baa03ac14d7e9167ab74e47e1dc4bd2213dd18431','0x5e3222c506585e1202da08c7231afdc5e472c777c245b822f44f141d335c744a','0x4051c3ba3dcca95da5db1be38e44f5b47fd1a855ba522123e3254fe3f8e271ea')>>>t.mine_blocks(2)>>>t.get_only_filter_changes(filter_id)('0x6649c3a7cb3c7ede3a4fd10ae9dd63775eccdafe39ace5f5a9ae81d360089fba','0x04890a08bca0ed2f1496eb29c5dc7aa66014c85377c6d9d9c2c315f85204b39c')>>>t.get_all_filter_logs(filter_id)('0x07004287f82c1a7ab15d7b8baa03ac14d7e9167ab74e47e1dc4bd2213dd18431','0x5e3222c506585e1202da08c7231afdc5e472c777c245b822f44f141d335c744a','0x4051c3ba3dcca95da5db1be38e44f5b47fd1a855ba522123e3254fe3f8e271ea','0x6649c3a7cb3c7ede3a4fd10ae9dd63775eccdafe39ace5f5a9ae81d360089fba','0x04890a08bca0ed2f1496eb29c5dc7aa66014c85377c6d9d9c2c315f85204b39c')EthereumTester.create_pending_transaction_filter() -> integerCreates a new filter for pending transactions.  Returns thefilter_idwhich
can be used to retrieve the transaction hashes for the pending transactions.>>>filter_id=t.create_pending_transaction_filter()>>>t.send_transaction({...})'0x07f20bf9586e373ac914a40e99119c4932bee343d89ba852ccfc9af1fd541566'>>>t.send_transaction({...})'0xff85f7751d132b66c03e548e736f870797b0f24f3ed41dfe5fc628eb2cbc3505'>>>t.get_only_filter_changes(filter_id)('0x07f20bf9586e373ac914a40e99119c4932bee343d89ba852ccfc9af1fd541566','0xff85f7751d132b66c03e548e736f870797b0f24f3ed41dfe5fc628eb2cbc3505')>>>t.send_transaction({...})'0xb07801f7e8b1cfa52b64271fa2673c4b8d64cc21cdbc5fde51d5858c94c2d26a'>>>t.get_only_filter_changes(filter_id)('0xb07801f7e8b1cfa52b64271fa2673c4b8d64cc21cdbc5fde51d5858c94c2d26a',)>>>t.get_all_filter_logs(filter_id)('0x07f20bf9586e373ac914a40e99119c4932bee343d89ba852ccfc9af1fd541566','0xff85f7751d132b66c03e548e736f870797b0f24f3ed41dfe5fc628eb2cbc3505','0xb07801f7e8b1cfa52b64271fa2673c4b8d64cc21cdbc5fde51d5858c94c2d26a')EthereumTester.create_log_filter(from_block=None, to_block=None, address=None, topics=None) -> integerCreates a new filter for logs produced by transactions.  The parameters for
this function can be used to filter the log entries.>>>filter_id=t.create_log_filter()>>>t.send_transaction({...})# something that produces a log entry'0x728bf75fc7d23845f328d2223df7fe9cafc6e7d23792457b625d5b60d2b22b7c'>>>t.send_transaction({...})# something that produces a log entry'0x63f5b381ffd09940ce22c45a3f4e163bd743851cb6b4f43771fbf0b3c14b2f8a'>>>t.get_only_filter_changes(filter_id)({'address':'0xd6F084Ee15E38c4f7e091f8DD0FE6Fe4a0E203Ef','block_hash':'0x68c0f318388003b652eae334efbed8bd345c469bd0ca77469183fc9693c23e13','block_number':11,'data':'0x','log_index':0,'topics':('0xf70fe689e290d8ce2b2a388ac28db36fbb0e16a6d89c6804c461f65a1b40bb15','0x0000000000000000000000000000000000000000000000000000000000003039'),'transaction_hash':'0x728bf75fc7d23845f328d2223df7fe9cafc6e7d23792457b625d5b60d2b22b7c','transaction_index':0,'type':'mined'},{'address':'0xd6F084Ee15E38c4f7e091f8DD0FE6Fe4a0E203Ef','block_hash':'0x07d7e46be6f9ba53ecd4323fb99ec656e652c4b14f4b8e8a244ee7f997464725','block_number':12,'data':'0x','log_index':0,'topics':('0xf70fe689e290d8ce2b2a388ac28db36fbb0e16a6d89c6804c461f65a1b40bb15','0x0000000000000000000000000000000000000000000000000000000000010932'),'transaction_hash':'0x63f5b381ffd09940ce22c45a3f4e163bd743851cb6b4f43771fbf0b3c14b2f8a','transaction_index':0,'type':'mined'})EthereumTester.delete_filter(filter_id)Removes the filter for the providedfilter_id.  If no filter is found for the
givenfilter_id, raisesFilterNotFound.EthereumTester.get_only_filter_changes(filter_id) -> transaction_hash or block_hash or log_entryReturns all new values for the providedfilter_idthat have not previously
been returned through this API.  RaisesFilterNotFoundif no filter is found for the givenfilter_id.EthereumTester.get_all_filter_logs(filter_id) -> transaction_hash or block_hash or log_entryReturns all values for the providedfilter_id. RaisesFilterNotFoundif no filter is found for the givenfilter_id.Snapshots and ResettingEthereumTester.take_snapshot() -> snapshot_idTakes a snapshot of the current chain state and returns the snapshot id.EthereumTester.revert_to_snapshot(snapshot_id)Reverts the chain to the chain state associated with the givensnapshot_id.
RaisesSnapshotNotFoundif no snapshot is known
for the given id.Errors and Exceptionseth_tester.exceptions.TransactionNotFoundRaised in cases where a transaction cannot be found for the provided transaction hash.eth_tester.exceptions.BlockNotFoundRaised in cases where a block cannot be found for either a provided number or
hash.eth_tester.exceptions.FilterNotFoundRaised in cases where a filter cannot be found for the provided filter id.eth_tester.exceptions.SnapshotNotFoundRaised in cases where a snapshot cannot be found for the provided snapshot id.BackendsEthereum tester is written using a pluggable backend system.Backend DependenciesEthereum tester does not install any of the dependencies needed to use the
various backends by default.  You can however install ethereum tester with the
necessary dependencies using the following method.$python-mpipinstalleth-tester[<backend-name>]You should replace<backend-name>with the name of the desired testing
backend.  Available backends are:py-evm:PyEVM (alpha)(experimental)Selecting a BackendYou can select which backend in a few different ways.The most direct way is to manually pass in the backend instance you wish to
use.>>>frometh_testerimportEthereumTester,MockBackend>>>t=EthereumTester(backend=MockBackend())Ethereum tester also supports configuration using the environment variableETHEREUM_TESTER_CHAIN_BACKEND.  This should be set to the import path for the
backend class you wish to use.Available BackendsEthereum tester can be used with the following backends.MockBackendPyEVM (experimental)MockBackendThis backend has limited functionality.  It cannot perform any VM computations.
It mocks out all of the objects and interactions.>>>frometh_testerimportEthereumTester,MockBackend>>>t=EthereumTester(MockBackend())PyEVM (experimental)WARNINGPy-EVM is experimental and should not be relied on for mission critical testing at this stage.Uses the experimental Py-EVM library.>>>frometh_testerimportEthereumTester,PyEVMBackend>>>t=EthereumTester(PyEVMBackend())PyEVM Genesis Parameters and StateIf you need to specify custom genesis parameters and state, you can build your own parametersdictto use instead of the default
when initializing a backend.  Only default values can be overridden or aValueErrorwill be raised.# Default Genesis Parameters

default_genesis_params = {
    "coinbase": GENESIS_COINBASE,
    "difficulty": GENESIS_DIFFICULTY,
    "extra_data": GENESIS_EXTRA_DATA,
    "gas_limit": GENESIS_GAS_LIMIT,
    "mix_hash": GENESIS_MIX_HASH,
    "nonce": GENESIS_NONCE,
    "receipt_root": BLANK_ROOT_HASH,
    "timestamp": int(time.time()),
    "transaction_root": BLANK_ROOT_HASH,
}To generate a genesis parametersdictwith an overridden parameters, pass agenesis_overridesdicttoPyEVM.generate_genesis_params.>>>frometh_testerimportPyEVMBackend,EthereumTester>>>genesis_overrides={'gas_limit':4500000}>>>custom_genesis_params=PyEVMBackend.generate_genesis_params(overrides=genesis_overrides)# Generates the following `dict`:# custom_genesis_params = {#     "coinbase": GENESIS_COINBASE,#     "difficulty": GENESIS_DIFFICULTY,#     "extra_data": GENESIS_EXTRA_DATA,#     "gas_limit": 4500000    # <<< Overridden Value <<<#     "mix_hash": GENESIS_MIX_HASH,#     "nonce": GENESIS_NONCE,#     "receipt_root": BLANK_ROOT_HASH,#     "timestamp": int(time.time()),#     "transaction_root": BLANK_ROOT_HASH,# }Then pass the generatedcustom_genesis_paramsdictto the backend's__init__>>>frometh_testerimportPyEVMBackend,EthereumTester>>>pyevm_backend=PyEVMBackend(genesis_parameters=custom_genesis_params)>>>t=EthereumTester(backend=pyevm_backend)Similarly togenesis_parameters, override the genesis state by passing in anoverridesdicttoPyEVMBackend.generate_genesis_state. Optionally, providenum_accountsto set the number of accounts.For more control on which accounts the backend generates, use thefrom_mnemonic()classmethod. Give it
amnemonic(and optionally the number of accounts) and it will use that information to generate the accounts.
Optionally, provide agenesis_state_overridesdictto adjust thegenesis_state.>>>frometh_testerimportPyEVMBackend,EthereumTester>>>frometh_utilsimportto_wei>>>fromhexbytesimportHexBytes>>>>>>pyevm_backend=PyEVMBackend.from_mnemonic(>>>'test test test test test test test test test test test junk',>>>genesis_state_overrides={'balance':to_wei(1000000,'ether')}>>>)>>>t=EthereumTester(backend=pyevm_backend)>>>print(t.get_accounts()[0])# Outputs 0x1e59ce931B4CFea3fe4B875411e280e173cB7A9C>>>print(t.get_balance('0x1e59ce931B4CFea3fe4B875411e280e173cB7A9C'))# Outputs 1000000000000000000000000NOTE: The same state is applied to all generated test accounts.# Default Account Genesis State

default_account_state = {
    'balance': to_wei(1000000, 'ether'),
    'storage': {},
    'code': b'',
    'nonce': 0,
}For Example, to create 3 test accounts, each with a balance of 100 ETH each:>>>frometh_testerimportEthereumTester,PyEVMBackend>>>frometh_utilsimportto_wei>>>state_overrides={'balance':to_wei(100,'ether')}>>>custom_genesis_state=PyEVMBackend.generate_genesis_state(overrides=state_overrides,num_accounts=3)# Then pass the generated `custom_genesis_state` `dict` to the backend's `__init__`>>>pyevm_backend=PyEVMBackend(genesis_state=custom_genesis_state)>>>t=EthereumTester(backend=pyevm_backend)Implementing Custom BackendsThe base classeth_tester.backends.base.BaseChainBackendis the recommended
base class to begin with if you wish to write your own backend.Details on implementation are beyond the scope of this document.Data FormatsEthereum tester uses two formats for data.Thenormalformat is the data format the is expected as input arguments to allEthereumTestermethods as well as the return types from all method calls.Thecanonicalformat is the data format that is used internally by the backend class.Ethereum tester enforces strict validation rules on these formats.Canonical FormatsThe canonical format is intended for low level handling by backends.32 byte hashes:bytesof length 32Arbitrary length strings:bytesAddresses:bytesof length 20Integers:intArray Types:tupleNormal FormatsThe normal format is intended for use by end users.32 byte hashes:0xprefixed hexadecimal encoded text strings (not byte strings)Arbitrary length strings:0xprefixed hexadecimal encoded text strings (not byte strings)Addresses:0xprefixed and EIP55 checksummed hexadecimal encoded text strings (not byte strings)Integers:intArray Types:tupleNormalization and ValidationBeware! Here there be dragons...  This section of the documentation is only
relevant if you intend to build tooling on top of this library.The ethereum tester provides strong guarantees that backends can be swapped out
seamlessly without effecting the data formats of both the input arguments and
return values.  This is accomplished using a two-step process of strictnormalizationandvalidation.All inputs to the methods of theEthereumTesterare first validated then
normalized to acanonicalformat.  Return values are put through this process
as well, first validating the data returned by the backend, and then
normalizing it from thecanonicalformat to thenormalform before being
returned.NormalizationTheEthereumTesterdelegates normalization to whatevernormalizerwas
passed in during instantiation.  If no value was provided, the default
normalizer will be used frometh_tester.normalization.default.DefaultNormalizer.The specifics of this object are beyond the scope of this document.ValidationTheEthereumTesterdelegates validation to whatevervalidatorwas
passed in during instantiation.  If no value was provided, the default
validator will be used frometh_tester.validation.default.DefaultValidator.The specifics of this object are beyond the scope of this document.Use with Web3.pySee theweb3.py documentationfor
information on theEthereumTesterprovider which integrates with this
library.Developer SetupIf you would like to hack on eth-tester, please check out theSnake Charmers
Tactical Manualfor information on how we do:TestingPull RequestsDocumentationWe usepre-committo maintain consistent code style. Once
installed, it will run automatically with every commit. You can also run it manually
withmake lint. If you need to make a commit that skips thepre-commitchecks, you
can do so withgit commit --no-verify.Development Environment SetupYou can set up your dev environment with:gitclonegit@github.com:ethereum/eth-tester.gitcdeth-tester
virtualenv-ppython3venv
.venv/bin/activate
python-mpipinstall-e".[dev]"pre-commitinstallRelease setupTo release a new version:makereleasebump=$$VERSION_PART_TO_BUMP$$How to bumpversionThe version format for this repo is{major}.{minor}.{patch}for stable, and{major}.{minor}.{patch}-{stage}.{devnum}for unstable (stagecan be alpha or beta).To issue the next version in line, specify which part to bump,
likemake release bump=minorormake release bump=devnum. This is typically done from the
main branch, except when releasing a beta (in which case the beta is released from main,
and the previous stable branch is released from said branch).If you are in a beta version,make release bump=stagewill switch to a stable.To issue an unstable version when the current version is stable, specify the
new version explicitly, likemake release bump="--new-version 4.0.0-alpha.1 devnum"