{"id":13604842,"url":"https://github.com/ethereum/eth-tester","last_synced_at":"2025-05-14T07:08:23.619Z","repository":{"id":22478310,"uuid":"96364578","full_name":"ethereum/eth-tester","owner":"ethereum","description":"Tool suite for testing ethereum applications.","archived":false,"fork":false,"pushed_at":"2025-05-12T21:39:37.000Z","size":1308,"stargazers_count":375,"open_issues_count":58,"forks_count":154,"subscribers_count":22,"default_branch":"main","last_synced_at":"2025-05-12T22:23:50.736Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ethereum.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.rst","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2017-07-05T22:00:02.000Z","updated_at":"2025-04-23T21:02:36.000Z","dependencies_parsed_at":"2022-09-04T23:21:12.738Z","dependency_job_id":"5c2f5850-507a-40fc-93af-8c6cac403a85","html_url":"https://github.com/ethereum/eth-tester","commit_stats":{"total_commits":824,"total_committers":50,"mean_commits":16.48,"dds":0.7463592233009708,"last_synced_commit":"a779238520ce0bec987259145c6e629b33ea5800"},"previous_names":["ethereum/ethereum-tester"],"tags_count":79,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ethereum%2Feth-tester","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ethereum%2Feth-tester/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ethereum%2Feth-tester/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ethereum%2Feth-tester/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ethereum","download_url":"https://codeload.github.com/ethereum/eth-tester/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":253832536,"owners_count":21971280,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-08-01T19:00:51.859Z","updated_at":"2025-05-14T07:08:23.585Z","avatar_url":"https://github.com/ethereum.png","language":"Python","funding_links":[],"categories":["dApps directory","Roadmap","[Ethereum](https://ethereum.org/en/)","Smart Contract Platforms"],"sub_categories":["Web3 Testing Tools","Whitepapers"],"readme":"# eth-tester\n\n[![Join the conversation on Discord](https://img.shields.io/discord/809793915578089484?color=blue\u0026label=chat\u0026logo=discord\u0026logoColor=white)](https://discord.gg/GHryRvPB84)\n[![Build Status](https://circleci.com/gh/ethereum/eth-tester.svg?style=shield)](https://circleci.com/gh/ethereum/eth-tester)\n[![PyPI version](https://badge.fury.io/py/eth-tester.svg)](https://badge.fury.io/py/eth-tester)\n[![Python versions](https://img.shields.io/pypi/pyversions/eth-tester.svg)](https://pypi.python.org/pypi/eth-tester)\n\nTools for testing Ethereum applications\n\nRead more in the documentation below.\n\nView the [change log](https://github.com/ethereum/eth-tester/blob/main/CHANGELOG.rst).\n\n## Installation\n\n```sh\npython -m pip install eth-tester\n```\n\n## Quick Start\n\n```python\n\u003e\u003e\u003e from eth_tester import EthereumTester\n\u003e\u003e\u003e t = EthereumTester()\n\u003e\u003e\u003e t.get_accounts()\n('0x7E5F4552091A69125d5DfCb7b8C2659029395Bdf',\n '0x2B5AD5c4795c026514f8317c7a215E218DcCD6cF',\n '0x6813Eb9362372EEF6200f3b1dbC3f819671cBA69',\n '0x1efF47bc3a10a45D4B230B5d10E37751FE6AA718',\n '0xe1AB8145F7E55DC933d51a18c793F901A3A0b276',\n '0xE57bFE9F44b819898F47BF37E5AF72a0783e1141',\n '0xd41c057fd1c78805AAC12B0A94a405c0461A6FBb',\n '0xF1F6619B38A98d6De0800F1DefC0a6399eB6d30C',\n '0xF7Edc8FA1eCc32967F827C9043FcAe6ba73afA5c',\n '0x4CCeBa2d7D2B4fdcE4304d3e09a1fea9fbEb1528')\n\n\u003e\u003e\u003e t.get_balance('0x7E5F4552091A69125d5DfCb7b8C2659029395Bdf')\n1000000000000000000000000\n\n\u003e\u003e\u003e t.send_transaction({\n...     'from': '0x7E5F4552091A69125d5DfCb7b8C2659029395Bdf',\n...     'to': '0x2B5AD5c4795c026514f8317c7a215E218DcCD6cF',\n...     'gas': 30000,\n...     'value': 1,\n...     'max_fee_per_gas': 1000000000,\n...     'max_priority_fee_per_gas': 1000000000,\n...     'chain_id': 131277322940537,\n...     'access_list': (\n...         {\n...             'address': '0xde0b295669a9fd93d5f28d9ec85e40f4cb697bae',\n...             'storage_keys': (\n...                 '0x0000000000000000000000000000000000000000000000000000000000000003',\n...                 '0x0000000000000000000000000000000000000000000000000000000000000007',\n...             )\n...         },\n...         {\n...             'address': '0xbb9bc244d798123fde783fcc1c72d3bb8c189413',\n...             'storage_keys': ()\n...         },\n...     )\n... })\n'0xc20b90af87bc65c3d748cf0a1fa54f3a86ffc94348e0fd91a70f1c5ba6ef4109'\n\n\u003e\u003e\u003e t.get_transaction_by_hash('0xc20b90af87bc65c3d748cf0a1fa54f3a86ffc94348e0fd91a70f1c5ba6ef4109')\n{'type': '0x2',\n 'hash': '0xc20b90af87bc65c3d748cf0a1fa54f3a86ffc94348e0fd91a70f1c5ba6ef4109',\n 'nonce': 0,\n 'block_hash': '0x28b95514984b0abbd91d88f1a542eaeeb810c24e0234e09891b7d6b3f94f47ed',\n 'block_number': 1,\n 'transaction_index': 0,\n 'from': '0x7E5F4552091A69125d5DfCb7b8C2659029395Bdf',\n 'to': '0x2B5AD5c4795c026514f8317c7a215E218DcCD6cF',\n 'value': 1,\n 'gas': 30000,\n 'data': '0x',\n 'r': 60071646517429056848243893841817235885102606421189844318110381014348740252962,\n 's': 55731679314783756278323646144996847004593793888590884914350251538533006990589,\n 'v': 0,\n 'chain_id': 131277322940537,\n 'max_fee_per_gas': 1000000000,\n 'max_priority_fee_per_gas': 1000000000,\n 'access_list': ({'address': '0xde0B295669a9FD93d5F28D9Ec85E40f4cb697BAe',\n   'storage_keys': ('0x0000000000000000000000000000000000000000000000000000000000000003',\n    '0x0000000000000000000000000000000000000000000000000000000000000007')},\n  {'address': '0xBB9bc244D798123fDe783fCc1C72d3Bb8C189413',\n   'storage_keys': ()}),\n 'gas_price': 1000000000}\n\n\n\u003e\u003e\u003e t.get_transaction_receipt('0xc20b90af87bc65c3d748cf0a1fa54f3a86ffc94348e0fd91a70f1c5ba6ef4109')\n{'transaction_hash': '0xc20b90af87bc65c3d748cf0a1fa54f3a86ffc94348e0fd91a70f1c5ba6ef4109',\n 'transaction_index': 0,\n 'block_number': 1,\n 'block_hash': '0x28b95514984b0abbd91d88f1a542eaeeb810c24e0234e09891b7d6b3f94f47ed',\n 'cumulative_gas_used': 29600,\n 'gas_used': 29600,\n 'effective_gas_price': 1000000000,\n 'contract_address': None,\n 'logs': (),\n 'type': '0x2',\n 'status': 1}\n```\n\n# Documentation\n\n## Input and output data formats\n\nThe ethereum tester library strictly enforces the following input formats and\ntypes.\n\n- Hexadecimal values **must** be text (not byte) strings.  The `0x` prefix is optional.\n- Any address which contains mixed-case alpha characters will be validated as a checksummed address as specified by [EIP-55](https://github.com/ethereum/ercs/blob/master/ERCS/erc-55.md)\n- 32-byte hashes **must** be hexadecimal encoded.\n- Numeric values **must** be in their integer representation.\n\nSimilarly, ethereum tester ensures that return values conform to similar rules.\n\n- 32-byte hashes will be returned in their hexadecimal encoded representation.\n- Addresses will be returned in their hexadecimal representation and EIP55 checksummed.\n- Numeric values will be returned as integers.\n\n## Block Numbers\n\n\u003ca id=\"block-numbers\"\u003e\u003c/a\u003e\n\nAny `block_number` parameter will accept the following string values.\n\n- `'latest'`: for the latest mined block.\n- `'pending'`: for the current un-mined block.\n- `'earliest'`: for the genesis block.\n- `'safe'`: for the last block that has passed 2/3 of attestations post-merge.\n- `'finalized'`: for the last finalized block post-merge.\n\n\u003e Note: These **must** be text strings (not byte strings)\n\n## `eth_tester.EthereumTester`\n\n### API\n\n### Instantiation\n\n- `eth_tester.EthereumTester(backend=None, validator=None, normalizer=None, auto_mine_transactions=True, fork_blocks=None)`\n\nThe `EthereumTester` object is the sole API entrypoint.  Instantiation of this\nobject accepts the following parameters.\n\n- `backend`: The chain backend being used.  See the [chain backends](#backends)\n- `validator`: The validator being used.  See the [validators](#validation)\n- `normalizer`: The normalizer being used.  See the [normalizers](#normalization)\n- `auto_mine_transactions`: If *truthy* transactions will be automatically mined at the time they are submitted.  See [`enable_auto_mine_transactions`](#api-enable_auto_mine_transactions) and [`disable_auto_mine_transactions`](#api-disable_auto_mine_transactions).\n- `fork_blocks`: configures which block numbers the various network hard fork rules will be activated.  See [fork-rules](#fork-rules)\n\n```python\n\u003e\u003e\u003e from eth_tester import EthereumTester\n\u003e\u003e\u003e t = EthereumTester()\n\u003e\u003e\u003e t\n\u003ceth_tester.main.EthereumTester at 0x102255710\u003e\n```\n\n### Fork Rules\n\n\u003ca id=\"fork-rules\"\u003e\u003c/a\u003e\n\nEthereum tester uses the Paris (PoS) fork rules, starting at block 0.\n\n### Time Travel\n\n\u003ca id=\"time-travel\"\u003e\u003c/a\u003e\n\nThe chain can only time travel forward in time.\n\n\u003ca id=\"api-time_travel\"\u003e\u003c/a\u003e\n\n#### `EthereumTester.time_travel(timestamp)`\n\nThe `timestamp` must be an integer, strictly greater than the current timestamp\nof the latest block.\n\n\u003e Note: Time traveling will result in a new block being mined.\n\n### Mining\n\nManually mining blocks can be done with the following API.  The `coinbase`\nparameter of these methods **must** be a hexadecimal encoded address.\n\n\u003ca id=\"api-mine_blocks\"\u003e\u003c/a\u003e\n\n#### `EthereumTester.mine_blocks(num_blocks=1, coinbase=ZERO_ADDRESS)`\n\nMines `num_blocks` new blocks, returning an iterable of the newly mined block hashes.\n\n\u003ca id=\"api-mine_block\"\u003e\u003c/a\u003e\n\n#### `EthereumTester.mine_block(coinbase=ZERO_ADDRESS)`\n\nMines a single new block, returning the mined block's hash.\n\n\u003ca id=\"api-auto_mine_transactions\"\u003e\u003c/a\u003e\n\n#### Auto-mining transactions\n\nBy 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.\n\n\u003ca id=\"api-enable_auto_mine_transactions\"\u003e\u003c/a\u003e\n\n#### `EthereumTester.enable_auto_mine_transactions()`\n\nTurns on auto-mining of transactions.\n\n\u003ca id=\"api-disable_auto_mine_transactions\"\u003e\u003c/a\u003e\n\n#### `EthereumTester.disable_auto_mine_transactions()`\n\nTurns **off** auto-mining of transactions.\n\n### Accounts\n\nThe following API can be used to interact with account data.  The `account`\nparameter in these methods **must** be a hexadecimal encoded address.\n\n\u003ca id=\"api-get_accounts\"\u003e\u003c/a\u003e\n`EthereumTester.get_accounts()`\n\nReturns an iterable of the accounts that the tester knows about.  All accounts\nin this list will be EIP55 checksummed.\n\n```python\n\u003e\u003e\u003e t.get_accounts()\n('0x82A978B3f5962A5b0957d9ee9eEf472EE55B42F1',\n '0x7d577a597B2742b498Cb5Cf0C26cDCD726d39E6e',\n ...\n '0x90F0B1EBbbA1C1936aFF7AAf20a7878FF9e04B6c')\n```\n\n\u003ca id=\"api-add_account\"\u003e\u003c/a\u003e\n\n#### `EthereumTester.add_account(private_key, password=None)`\n\nAdds a new account for the given private key.  Returns the hex encoded address\nof the added account.\n\n```python\n\u003e\u003e\u003e t.add_account('0x58d23b55bc9cdce1f18c2500f40ff4ab7245df9a89505e9b1fa4851f623d241d')\n'0xdc544d1aa88ff8bbd2f2aec754b1f1e99e1812fd'\n```\n\nBy default, added accounts are unlocked and do not have a password.  If you\nwould like to add an account which has a password, you can supply the password\nas the second parameter.\n\n```python\n\u003e\u003e\u003e t.add_account('0x58d23b55bc9cdce1f18c2500f40ff4ab7245df9a89505e9b1fa4851f623d241d', 'my-secret')\n'0xdc544d1aa88ff8bbd2f2aec754b1f1e99e1812fd'\n```\n\n\u003ca id=\"api-unlock_account\"\u003e\u003c/a\u003e\n\n#### `EthereumTester.unlock_account(account, password, unlock_seconds=None)`\n\nUnlocks the given account if the provided password matches.\n\nRaises a `ValidationError` if:\n\n- The account is not known.\n- The password does not match.\n- The account was created without a password.\n\n```python\n\u003e\u003e\u003e t.unlock_account('0xdc544d1aa88ff8bbd2f2aec754b1f1e99e1812fd', 'my-secret')\n```\n\nBy default, accounts will be unlocked indefinitely.  You can however unlock an\naccount for a specified amount of time by providing the desired duration in\nseconds.\n\n```python\n# unlock for 1 hour.\n\u003e\u003e\u003e t.unlock_account('0xdc544d1aa88ff8bbd2f2aec754b1f1e99e1812fd', 'my-secret', 60 * 60)\n```\n\n\u003ca id=\"api-lock_account\"\u003e\u003c/a\u003e\n\n#### `EthereumTester.lock_account(account)`\n\nLocks the provided account.\n\nRaises a `ValidationError` if:\n\n- The account is not known\n- The account does not have a password.\n\n\u003ca id=\"api-get_balance\"\u003e\u003c/a\u003e\n\n#### `EthereumTester.get_balance(account) -\u003e integer`\n\nReturns the balance, in wei, for the provided account.\n\n```python\n\u003e\u003e\u003e t.get_balance('0x82A978B3f5962A5b0957d9ee9eEf472EE55B42F1')\n1000004999999999999999999\n```\n\n\u003ca id=\"api-get_nonce\"\u003e\u003c/a\u003e\n\n#### `EthereumTester.get_nonce(account) -\u003e integer`\n\nReturns the nonce for the provided account.\n\n```python\n\u003e\u003e\u003e t.get_nonce('0x82A978B3f5962A5b0957d9ee9eEf472EE55B42F1')\n1\n```\n\n\u003ca id=\"api-get_code\"\u003e\u003c/a\u003e\n\n#### `EthereumTester.get_code(account) -\u003e hex string`\n\nReturns the code for the given account.\n\n```python\n\u003e\u003e\u003e t.get_code('0x82A978B3f5962A5b0957d9ee9eEf472EE55B42F1')\n\"0x\"\n```\n\n### Blocks, Transactions, and Receipts\n\n\u003ca id=\"api-get_transaction_by_hash\"\u003e\u003c/a\u003e\n\n#### `EthereumTester.get_transaction_by_hash(transaction_hash) -\u003e transaction-object`\n\nReturns the transaction for the given hash, raising a\n[`TransactionNotFound`](#errors-TransactionNotFound) exception if the\ntransaction cannot be found.\n\n```python\n\u003e\u003e\u003e t.get_transaction_by_hash('0x21ae665f707e12a5f1bb13ef8c706b65cc5accfd03e7067ce683d831f51122e6')\n{'type': '0x2',\n 'hash': '0x21ae665f707e12a5f1bb13ef8c706b65cc5accfd03e7067ce683d831f51122e6',\n 'nonce': 0,\n 'block_hash': '0x810731efeb7498fc0ac3bc7c72a71571b672c9fdbfbfd8b435f483e368e8ef7e',\n 'block_number': 1,\n 'transaction_index': 0,\n 'from': '0x2B5AD5c4795c026514f8317c7a215E218DcCD6cF',\n 'to': '0x7E5F4552091A69125d5DfCb7b8C2659029395Bdf',\n 'value': 1337,\n 'gas': 21000,\n 'data': '0x',\n 'r': 1713666669454033023988006960017431058214051587080823768269189498559514600280,\n 's': 32003859822305799628524852194521134173285969678963273753063458725692016415033,\n 'v': 0,\n 'chain_id': 131277322940537,\n 'max_fee_per_gas': 2000000000,\n 'max_priority_fee_per_gas': 500000000,\n 'access_list': (),\n 'gas_price': 1375000000}\n```\n\n\u003e Note: For unmined transaction, `transaction_index`, `block_number` and `block_hash` will all be `None`.\n\n\u003ca id=\"api-get_block_by_number\"\u003e\u003c/a\u003e\n\n#### `EthereumTester.get_block_by_number(block_number, full_transactions=False) -\u003e block-object`\n\nReturns the block for the given `block_number`.  See [block\nnumbers](#block-numbers) for named block numbers you can use.  If\n`full_transactions` is truthy, then the transactions array will be populated\nwith full transaction objects as opposed to their hashes.\n\nRaises [`BlockNotFound`](#errors-BlockNotFound) if a block for the given number\ncannot be found.\n\n```python\n\u003e\u003e\u003e t.get_block_by_number(1)\n{'number': 1,\n 'hash': '0xd481955268d1f3db58ee61685a899a35e33e8fd35b9cc0812f85b9f06757140e',\n 'parent_hash': '0x5be984ab842071903ee443a5dee92603bef42de35b4e10928e753f7e88a7163a',\n 'nonce': '0x0000000000000000',\n 'sha3_uncles': '0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347',\n 'logs_bloom': 0,\n 'transactions_root': '0xef1e11d99f7db22fd93c6a10d44753d4a93e9f6ecb2f1e5030a0a91f1d3b07ac',\n 'receipts_root': '0x611e48488cf80b4c31f01ad45b6ebea533a68255a6d0240d434d9366a3582010',\n 'state_root': '0x9ce568dcaa6f130d733b333304f2c26a19334ed328a7eb9bb31707306381ba65',\n 'coinbase': '0x0000000000000000000000000000000000000000',\n 'difficulty': 0,\n 'total_difficulty': 0,\n 'mix_hash': '0x0000000000000000000000000000000000000000000000000000000000000000',\n 'size': 751,\n 'extra_data': '0x0000000000000000000000000000000000000000000000000000000000000000',\n 'gas_limit': 3141592,\n 'gas_used': 29600,\n 'timestamp': 1633669276,\n 'transactions': ('0xc20b90af87bc65c3d748cf0a1fa54f3a86ffc94348e0fd91a70f1c5ba6ef4109',),\n 'uncles': (),\n 'base_fee_per_gas': 875000000}\n```\n\n\u003ca id=\"api-get_block_by_hash\"\u003e\u003c/a\u003e\n\n#### `EthereumTester.get_block_by_hash(block_hash, full_transactions=True) -\u003e block-object`\n\nReturns the block for the given `block_hash`.  The `full_transactions`\nparameter behaves the same as in\n[`get_block_by_number`](#api-get_block_by_number).\n\nRaises [`BlockNotFound`](#errors-BlockNotFound) if a block for the given hash\ncannot be found.\n\n```python\n\u003e\u003e\u003e t.get_block_by_hash('0x0f50c8ea0f67ce0b7bff51ae866159edc443bde87de2ab26010a15b777244ddd')\n{'number': 1,\n 'hash': '0xd481955268d1f3db58ee61685a899a35e33e8fd35b9cc0812f85b9f06757140e',\n 'parent_hash': '0x5be984ab842071903ee443a5dee92603bef42de35b4e10928e753f7e88a7163a',\n 'nonce': '0x0000000000000000',\n 'sha3_uncles': '0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347',\n 'logs_bloom': 0,\n 'transactions_root': '0xef1e11d99f7db22fd93c6a10d44753d4a93e9f6ecb2f1e5030a0a91f1d3b07ac',\n 'receipts_root': '0x611e48488cf80b4c31f01ad45b6ebea533a68255a6d0240d434d9366a3582010',\n 'state_root': '0x9ce568dcaa6f130d733b333304f2c26a19334ed328a7eb9bb31707306381ba65',\n 'coinbase': '0x0000000000000000000000000000000000000000',\n 'difficulty': 0,\n 'total_difficulty': 0,\n 'mix_hash': '0x0000000000000000000000000000000000000000000000000000000000000000',\n 'size': 751,\n 'extra_data': '0x0000000000000000000000000000000000000000000000000000000000000000',\n 'gas_limit': 3141592,\n 'gas_used': 29600,\n 'timestamp': 1633669276,\n 'transactions': ('0xc20b90af87bc65c3d748cf0a1fa54f3a86ffc94348e0fd91a70f1c5ba6ef4109',),\n 'uncles': (),\n 'base_fee_per_gas': 875000000}\n```\n\n\u003ca id=\"api-get_transaction_receipt\"\u003e\u003c/a\u003e\n\n#### `EthereumTester.get_transaction_receipt(transaction_hash)`\n\nReturns the receipt for the given `transaction_hash`, raising\n[`TransactionNotFound`](#errors-TransactionNotFound) if no transaction can be\nfound for the given hash.\n\n```python\n\u003e\u003e\u003e t.get_transaction_receipt('0x9a7cc8b7accf54ecb1901bf4d0178f28ca457bb9f9c245692c0ca8fabef08d3b')\n {'block_hash': '0x878f779d8bb25b25fb78fc16b8d64d70a5961310ef1689571aec632e9424290c',\n 'block_number': 2,\n 'contract_address': None,\n 'cumulative_gas_used': 23154,\n 'gas_used': 23154,\n 'logs': ({'address': '0xd6F084Ee15E38c4f7e091f8DD0FE6Fe4a0E203Ef',\n   'block_hash': '0x878f779d8bb25b25fb78fc16b8d64d70a5961310ef1689571aec632e9424290c',\n   'block_number': 2,\n   'data': '0x',\n   'log_index': 0,\n   'topics': (\n    '0xf70fe689e290d8ce2b2a388ac28db36fbb0e16a6d89c6804c461f65a1b40bb15',\n    '0x0000000000000000000000000000000000000000000000000000000000003039'),\n   'transaction_hash': '0x9a7cc8b7accf54ecb1901bf4d0178f28ca457bb9f9c245692c0ca8fabef08d3b',\n   'transaction_index': 0,\n   'type': 'mined'},),\n 'transaction_hash': '0x9a7cc8b7accf54ecb1901bf4d0178f28ca457bb9f9c245692c0ca8fabef08d3b',\n 'transaction_index': 0}\n```\n\n- Receipts for unmined transactions will have all of `block_hash`, `block_number` and `transaction_index` set to `None`.\n- Receipts for transactions which create a contract will have the created contract address in the `contract_address` field.\n\n### Transaction Sending\n\nA transaction is a formatted as a dictionary with the following keys and\nvalues.\n\n- `from`: The address of the account sending the transaction (hexadecimal string).\n- `to`: The address of the account the transaction is being sent to.  Empty string should be used to trigger contract creation (hexadecimal string).\n- `gas`: Sets the gas limit for transaction execution (integer).\n- `value`: The amount of ether in wei that should be sent with the transaction (integer).\n- `data`: The data for the transaction (hexadecimal string).\n- `chain_id`: The integer id for the chain the transaction is meant to interact with.\n\nIn addition to the above, the following parameters are added based on the type of transaction being sent:\n\n#### Legacy transactions\n\n- `gas_price`: Sets the price per unit of gas in wei that will be paid for transaction execution (integer).\n\n#### Access list transactions (EIP-2930)\n\n- `gas_price`: Sets the price per unit of gas in wei that will be paid for transaction execution (integer).\n- `access_list` (optional): Specifies accounts and storage slots expected to be accessed, based on the transaction, in order to\n  gain a discount on the gas for those executions (see quickstart example for usage).\n\n#### Dynamic fee transactions (EIP-1559)\n\n- `max_fee_per_gas`: Sets the maximum fee per unit of gas in wei that will be paid for transaction execution (integer).\n- `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).\n- `access_list` (optional): Specifies accounts and storage slots expected to be accessed, based on the transaction, in order to\n  gain a discount on the gas for those executions (see quickstart example for usage).\n\n### Methods\n\n\u003ca id=\"api-send_transaction\"\u003e\u003c/a\u003e\n\n#### `EthereumTester.send_transaction(transaction) -\u003e transaction_hash`\n\nSends the provided `transaction` object, returning the `transaction_hash` for\nthe sent transaction.\n\n\u003ca id=\"api-call\"\u003e\u003c/a\u003e\n\n#### `EthereumTester.call(transaction, block_number='latest')`\n\nExecutes the provided `transaction` object at the evm state from the block\ndenoted by the `block_number` parameter, returning the resulting bytes return\nvalue from the evm.\n\n\u003ca id=\"api-estimate_gas\"\u003e\u003c/a\u003e\n\n#### `EthereumTester.estimate_gas(transaction, block_number='latest')`\n\nExecutes the provided `transaction` object at the evm state from the block\ndenoted by the `block_number` parameter, measuring and returning the gas\nconsumption.\n\n\u003ca id=\"api-fee_history\"\u003e\u003c/a\u003e\n\n#### `EthereumTester.get_fee_history(block_count=1, newest_block='latest', reward_percentiles=[])`\n\nReturn the historical gas information for the number of blocks specified as the `block_count` starting from `newest_block`.\nNote that specifying `reward_percentiles` has no effect on the response and so `reward` will always return an empty list.\n\n### Logs and Filters\n\n\u003ca id=\"api-create_block_filter\"\u003e\u003c/a\u003e\n\n#### `EthereumTester.create_block_filter() -\u003e integer`\n\nCreates a new filter for newly mined blocks.  Returns the `filter_id` which can\nbe used to retrieve the block hashes for the mined blocks.\n\n```python\n\u003e\u003e\u003e filter_id = t.create_block_filter()\n\u003e\u003e\u003e filter_id = t.create_block_filter()\n\u003e\u003e\u003e t.mine_blocks(3)\n\u003e\u003e\u003e t.get_only_filter_changes(filter_id)\n('0x07004287f82c1a7ab15d7b8baa03ac14d7e9167ab74e47e1dc4bd2213dd18431',\n '0x5e3222c506585e1202da08c7231afdc5e472c777c245b822f44f141d335c744a',\n '0x4051c3ba3dcca95da5db1be38e44f5b47fd1a855ba522123e3254fe3f8e271ea')\n\u003e\u003e\u003e t.mine_blocks(2)\n\u003e\u003e\u003e t.get_only_filter_changes(filter_id)\n('0x6649c3a7cb3c7ede3a4fd10ae9dd63775eccdafe39ace5f5a9ae81d360089fba',\n '0x04890a08bca0ed2f1496eb29c5dc7aa66014c85377c6d9d9c2c315f85204b39c')\n\u003e\u003e\u003e t.get_all_filter_logs(filter_id)\n('0x07004287f82c1a7ab15d7b8baa03ac14d7e9167ab74e47e1dc4bd2213dd18431',\n '0x5e3222c506585e1202da08c7231afdc5e472c777c245b822f44f141d335c744a',\n '0x4051c3ba3dcca95da5db1be38e44f5b47fd1a855ba522123e3254fe3f8e271ea',\n '0x6649c3a7cb3c7ede3a4fd10ae9dd63775eccdafe39ace5f5a9ae81d360089fba',\n '0x04890a08bca0ed2f1496eb29c5dc7aa66014c85377c6d9d9c2c315f85204b39c')\n```\n\n\u003ca id=\"api-create_pending_transaction_filter\"\u003e\u003c/a\u003e\n\n#### `EthereumTester.create_pending_transaction_filter() -\u003e integer`\n\nCreates a new filter for pending transactions.  Returns the `filter_id` which\ncan be used to retrieve the transaction hashes for the pending transactions.\n\n```python\n\u003e\u003e\u003e filter_id = t.create_pending_transaction_filter()\n\u003e\u003e\u003e t.send_transaction({...})\n'0x07f20bf9586e373ac914a40e99119c4932bee343d89ba852ccfc9af1fd541566'\n\u003e\u003e\u003e t.send_transaction({...})\n'0xff85f7751d132b66c03e548e736f870797b0f24f3ed41dfe5fc628eb2cbc3505'\n\u003e\u003e\u003e t.get_only_filter_changes(filter_id)\n('0x07f20bf9586e373ac914a40e99119c4932bee343d89ba852ccfc9af1fd541566',\n '0xff85f7751d132b66c03e548e736f870797b0f24f3ed41dfe5fc628eb2cbc3505')\n\u003e\u003e\u003e t.send_transaction({...})\n'0xb07801f7e8b1cfa52b64271fa2673c4b8d64cc21cdbc5fde51d5858c94c2d26a'\n\u003e\u003e\u003e t.get_only_filter_changes(filter_id)\n('0xb07801f7e8b1cfa52b64271fa2673c4b8d64cc21cdbc5fde51d5858c94c2d26a',)\n\u003e\u003e\u003e t.get_all_filter_logs(filter_id)\n('0x07f20bf9586e373ac914a40e99119c4932bee343d89ba852ccfc9af1fd541566',\n '0xff85f7751d132b66c03e548e736f870797b0f24f3ed41dfe5fc628eb2cbc3505',\n '0xb07801f7e8b1cfa52b64271fa2673c4b8d64cc21cdbc5fde51d5858c94c2d26a')\n```\n\n\u003ca id=\"api-create_log_filter\"\u003e\u003c/a\u003e\n\n#### `EthereumTester.create_log_filter(from_block=None, to_block=None, address=None, topics=None) -\u003e integer`\n\nCreates a new filter for logs produced by transactions.  The parameters for\nthis function can be used to filter the log entries.\n\n```python\n\u003e\u003e\u003e filter_id = t.create_log_filter()\n\u003e\u003e\u003e t.send_transaction({...})  # something that produces a log entry\n'0x728bf75fc7d23845f328d2223df7fe9cafc6e7d23792457b625d5b60d2b22b7c'\n\u003e\u003e\u003e t.send_transaction({...})  # something that produces a log entry\n'0x63f5b381ffd09940ce22c45a3f4e163bd743851cb6b4f43771fbf0b3c14b2f8a'\n\u003e\u003e\u003e t.get_only_filter_changes(filter_id)\n({'address': '0xd6F084Ee15E38c4f7e091f8DD0FE6Fe4a0E203Ef',\n  'block_hash': '0x68c0f318388003b652eae334efbed8bd345c469bd0ca77469183fc9693c23e13',\n  'block_number': 11,\n  'data': '0x',\n  'log_index': 0,\n  'topics': ('0xf70fe689e290d8ce2b2a388ac28db36fbb0e16a6d89c6804c461f65a1b40bb15',\n   '0x0000000000000000000000000000000000000000000000000000000000003039'),\n  'transaction_hash': '0x728bf75fc7d23845f328d2223df7fe9cafc6e7d23792457b625d5b60d2b22b7c',\n  'transaction_index': 0,\n  'type': 'mined'},\n {'address': '0xd6F084Ee15E38c4f7e091f8DD0FE6Fe4a0E203Ef',\n  'block_hash': '0x07d7e46be6f9ba53ecd4323fb99ec656e652c4b14f4b8e8a244ee7f997464725',\n  'block_number': 12,\n  'data': '0x',\n  'log_index': 0,\n  'topics': ('0xf70fe689e290d8ce2b2a388ac28db36fbb0e16a6d89c6804c461f65a1b40bb15',\n   '0x0000000000000000000000000000000000000000000000000000000000010932'),\n  'transaction_hash': '0x63f5b381ffd09940ce22c45a3f4e163bd743851cb6b4f43771fbf0b3c14b2f8a',\n  'transaction_index': 0,\n  'type': 'mined'})\n```\n\n\u003ca id=\"api-delete_filter\"\u003e\u003c/a\u003e\n\n#### `EthereumTester.delete_filter(filter_id)`\n\nRemoves the filter for the provided `filter_id`.  If no filter is found for the\ngiven `filter_id`, raises [`FilterNotFound`](#errors-FilterNotFound).\n\n\u003ca id=\"api-get_only_filter_changes\"\u003e\u003c/a\u003e\n\n#### `EthereumTester.get_only_filter_changes(filter_id) -\u003e transaction_hash or block_hash or log_entry`\n\nReturns all new values for the provided `filter_id` that have not previously\nbeen returned through this API.  Raises\n[`FilterNotFound`](#errors-FilterNotFound) if no filter is found for the given\n`filter_id`.\n\n\u003ca id=\"api-get_only_filter_changes\"\u003e\u003c/a\u003e\n\n#### `EthereumTester.get_all_filter_logs(filter_id) -\u003e transaction_hash or block_hash or log_entry`\n\nReturns all values for the provided `filter_id`. Raises\n[`FilterNotFound`](#errors-FilterNotFound) if no filter is found for the given\n`filter_id`.\n\n### Snapshots and Resetting\n\n\u003ca id=\"api-take_snapshot\"\u003e\u003c/a\u003e\n\n#### `EthereumTester.take_snapshot() -\u003e snapshot_id`\n\nTakes a snapshot of the current chain state and returns the snapshot id.\n\n\u003ca id=\"api-revert_to_snapshot\"\u003e\u003c/a\u003e\n\n#### `EthereumTester.revert_to_snapshot(snapshot_id)`\n\nReverts the chain to the chain state associated with the given `snapshot_id`.\nRaises [`SnapshotNotFound`](#errors-SnapshotNotFound) if no snapshot is known\nfor the given id.\n\n### Errors and Exceptions\n\n\u003ca id=\"errors-TransactionNotFound\"\u003e\u003c/a\u003e\n\n#### `eth_tester.exceptions.TransactionNotFound`\n\nRaised in cases where a transaction cannot be found for the provided transaction hash.\n\n\u003ca id=\"errors-BlockNotFound\"\u003e\u003c/a\u003e\n\n#### `eth_tester.exceptions.BlockNotFound`\n\nRaised in cases where a block cannot be found for either a provided number or\nhash.\n\n\u003ca id=\"errors-FilterNotFound\"\u003e\u003c/a\u003e\n\n#### `eth_tester.exceptions.FilterNotFound`\n\nRaised in cases where a filter cannot be found for the provided filter id.\n\n\u003ca id=\"errors-SnapshotNotFound\"\u003e\u003c/a\u003e\n\n#### `eth_tester.exceptions.SnapshotNotFound`\n\nRaised in cases where a snapshot cannot be found for the provided snapshot id.\n\n## Backends\n\nEthereum tester is written using a pluggable backend system.\n\n### Backend Dependencies\n\nEthereum tester does not install any of the dependencies needed to use the\nvarious backends by default.  You can however install ethereum tester with the\nnecessary dependencies using the following method.\n\n```bash\n$ python -m pip install eth-tester[\u003cbackend-name\u003e]\n```\n\nYou should replace `\u003cbackend-name\u003e` with the name of the desired testing\nbackend.  Available backends are:\n\n- `py-evm`: [PyEVM (alpha)](https://pypi.python.org/pypi/py-evm) **(experimental)**\n\n### Selecting a Backend\n\nYou can select which backend in a few different ways.\n\nThe most direct way is to manually pass in the backend instance you wish to\nuse.\n\n```python\n\u003e\u003e\u003e from eth_tester import EthereumTester, MockBackend\n\u003e\u003e\u003e t = EthereumTester(backend=MockBackend())\n```\n\nEthereum tester also supports configuration using the environment variable\n`ETHEREUM_TESTER_CHAIN_BACKEND`.  This should be set to the import path for the\nbackend class you wish to use.\n\n### Available Backends\n\nEthereum tester can be used with the following backends.\n\n- MockBackend\n- PyEVM (experimental)\n\n#### MockBackend\n\nThis backend has limited functionality.  It cannot perform any VM computations.\nIt mocks out all of the objects and interactions.\n\n```python\n\u003e\u003e\u003e from eth_tester import EthereumTester, MockBackend\n\u003e\u003e\u003e t = EthereumTester(MockBackend())\n```\n\n#### PyEVM (experimental)\n\n\u003e **WARNING** Py-EVM is experimental and should not be relied on for mission critical testing at this stage.\n\nUses the experimental Py-EVM library.\n\n```python\n\u003e\u003e\u003e from eth_tester import EthereumTester, PyEVMBackend\n\u003e\u003e\u003e t = EthereumTester(PyEVMBackend())\n```\n\n#### PyEVM Genesis Parameters and State\n\nIf you need to specify custom genesis parameters and state, you can build your own parameters `dict` to use instead of the default\nwhen initializing a backend.  Only default values can be overridden or a `ValueError` will be raised.\n\n```\n# Default Genesis Parameters\n\ndefault_genesis_params = {\n    \"coinbase\": GENESIS_COINBASE,\n    \"difficulty\": GENESIS_DIFFICULTY,\n    \"extra_data\": GENESIS_EXTRA_DATA,\n    \"gas_limit\": GENESIS_GAS_LIMIT,\n    \"mix_hash\": GENESIS_MIX_HASH,\n    \"nonce\": GENESIS_NONCE,\n    \"receipt_root\": BLANK_ROOT_HASH,\n    \"timestamp\": int(time.time()),\n    \"transaction_root\": BLANK_ROOT_HASH,\n}\n```\n\nTo generate a genesis parameters `dict` with an overridden parameters, pass a `genesis_overrides` `dict` \\\nto `PyEVM.generate_genesis_params`.\n\n```python\n\u003e\u003e\u003e from eth_tester import PyEVMBackend, EthereumTester\n\n\u003e\u003e\u003e genesis_overrides = {'gas_limit': 4500000}\n\u003e\u003e\u003e custom_genesis_params = PyEVMBackend.generate_genesis_params(overrides=genesis_overrides)\n\n# Generates the following `dict`:\n\n# custom_genesis_params = {\n#     \"coinbase\": GENESIS_COINBASE,\n#     \"difficulty\": GENESIS_DIFFICULTY,\n#     \"extra_data\": GENESIS_EXTRA_DATA,\n#     \"gas_limit\": 4500000    # \u003c\u003c\u003c Overridden Value \u003c\u003c\u003c\n#     \"mix_hash\": GENESIS_MIX_HASH,\n#     \"nonce\": GENESIS_NONCE,\n#     \"receipt_root\": BLANK_ROOT_HASH,\n#     \"timestamp\": int(time.time()),\n#     \"transaction_root\": BLANK_ROOT_HASH,\n# }\n```\n\nThen pass the generated `custom_genesis_params` `dict` to the backend's `__init__`\n\n```python\n\u003e\u003e\u003e from eth_tester import PyEVMBackend, EthereumTester\n\u003e\u003e\u003e pyevm_backend = PyEVMBackend(genesis_parameters=custom_genesis_params)\n\u003e\u003e\u003e t = EthereumTester(backend=pyevm_backend)\n```\n\nSimilarly to `genesis_parameters`, override the genesis state by passing in an `overrides` `dict`\nto `PyEVMBackend.generate_genesis_state`. Optionally, provide `num_accounts` to set the number of accounts.\n\nFor more control on which accounts the backend generates, use the `from_mnemonic()` classmethod. Give it\na `mnemonic` (and optionally the number of accounts) and it will use that information to generate the accounts.\nOptionally, provide a `genesis_state_overrides` `dict` to adjust the `genesis_state`.\n\n```python\n\u003e\u003e\u003e from eth_tester import PyEVMBackend, EthereumTester\n\u003e\u003e\u003e from eth_utils import to_wei\n\u003e\u003e\u003e from hexbytes import HexBytes\n\u003e\u003e\u003e\n\u003e\u003e\u003e pyevm_backend = PyEVMBackend.from_mnemonic(\n\u003e\u003e\u003e    'test test test test test test test test test test test junk',\n\u003e\u003e\u003e    genesis_state_overrides={'balance': to_wei(1000000, 'ether')}\n\u003e\u003e\u003e )\n\u003e\u003e\u003e t = EthereumTester(backend=pyevm_backend)\n\u003e\u003e\u003e print(t.get_accounts()[0])  # Outputs 0x1e59ce931B4CFea3fe4B875411e280e173cB7A9C\n\u003e\u003e\u003e print(t.get_balance('0x1e59ce931B4CFea3fe4B875411e280e173cB7A9C'))  # Outputs 1000000000000000000000000\n```\n\n*NOTE: The same state is applied to all generated test accounts.*\n\n```\n# Default Account Genesis State\n\ndefault_account_state = {\n    'balance': to_wei(1000000, 'ether'),\n    'storage': {},\n    'code': b'',\n    'nonce': 0,\n}\n```\n\nFor Example, to create 3 test accounts, each with a balance of 100 ETH each:\n\n```python\n\u003e\u003e\u003e from eth_tester import EthereumTester, PyEVMBackend\n\u003e\u003e\u003e  from eth_utils import to_wei\n\n\u003e\u003e\u003e state_overrides = {'balance': to_wei(100, 'ether')}\n\u003e\u003e\u003e custom_genesis_state = PyEVMBackend.generate_genesis_state(overrides=state_overrides, num_accounts=3)\n\n# Then pass the generated `custom_genesis_state` `dict` to the backend's `__init__`\n\n\u003e\u003e\u003e pyevm_backend = PyEVMBackend(genesis_state=custom_genesis_state)\n\u003e\u003e\u003e t = EthereumTester(backend=pyevm_backend)\n```\n\n### Implementing Custom Backends\n\nThe base class `eth_tester.backends.base.BaseChainBackend` is the recommended\nbase class to begin with if you wish to write your own backend.\n\nDetails on implementation are beyond the scope of this document.\n\n## Data Formats\n\nEthereum tester uses two formats for data.\n\n- The *normal* format is the data format that is expected as input arguments to all `EthereumTester` methods as well as the return types from all method calls.\n- The *canonical* format is the data format that is used internally by the backend class.\n\nEthereum tester enforces strict validation rules on these formats.\n\n### Canonical Formats\n\nThe canonical format is intended for low level handling by backends.\n\n- 32 byte hashes: `bytes` of length 32\n- Arbitrary length strings: `bytes`\n- Addresses: `bytes` of length 20\n- Integers: `int`\n- Array Types: `tuple`\n\n### Normal Formats\n\nThe normal format is intended for use by end users.\n\n- 32 byte hashes: `0x` prefixed hexadecimal encoded text strings (not byte strings)\n- Arbitrary length strings: `0x` prefixed hexadecimal encoded text strings (not byte strings)\n- Addresses: `0x` prefixed and EIP55 checksummed hexadecimal encoded text strings (not byte strings)\n- Integers: `int`\n- Array Types: `tuple`\n\n## Normalization and Validation\n\n\u003e Beware! Here there be dragons...  This section of the documentation is only\n\u003e relevant if you intend to build tooling on top of this library.\n\nThe ethereum tester provides strong guarantees that backends can be swapped out\nseamlessly without affecting the data formats of both the input arguments and\nreturn values.  This is accomplished using a two-step process of strict\n*normalization* and *validation*.\n\nAll inputs to the methods of the `EthereumTester` are first validated then\nnormalized to a *canonical* format.  Return values are put through this process\nas well, first validating the data returned by the backend, and then\nnormalizing it from the *canonical* format to the *normal* form before being\nreturned.\n\n\u003ca id=\"normalization\"\u003e\u003c/a\u003e\n\n### Normalization\n\nThe `EthereumTester` delegates normalization to whatever `normalizer` was\npassed in during instantiation.  If no value was provided, the default\nnormalizer will be used from\n`eth_tester.normalization.default.DefaultNormalizer`.\n\nThe specifics of this object are beyond the scope of this document.\n\n\u003ca id=\"validation\"\u003e\u003c/a\u003e\n\n### Validation\n\nThe `EthereumTester` delegates validation to whatever `validator` was\npassed in during instantiation.  If no value was provided, the default\nvalidator will be used from\n`eth_tester.validation.default.DefaultValidator`.\n\nThe specifics of this object are beyond the scope of this document.\n\n# Use with Web3.py\n\nSee the [web3.py documentation](http://web3py.readthedocs.io/en/latest/) for\ninformation on the `EthereumTester` provider which integrates with this\nlibrary.\n\n## Developer Setup\n\nIf you would like to hack on eth-tester, please check out the [Snake Charmers\nTactical Manual](https://github.com/ethereum/snake-charmers-tactical-manual)\nfor information on how we do:\n\n- Testing\n- Pull Requests\n- Documentation\n\nWe use [pre-commit](https://pre-commit.com/) to maintain consistent code style. Once\ninstalled, it will run automatically with every commit. You can also run it manually\nwith `make lint`. If you need to make a commit that skips the `pre-commit` checks, you\ncan do so with `git commit --no-verify`.\n\n### Development Environment Setup\n\nYou can set up your dev environment with:\n\n```sh\ngit clone git@github.com:ethereum/eth-tester.git\ncd eth-tester\nvirtualenv -p python3 venv\n. venv/bin/activate\npython -m pip install -e \".[dev]\"\npre-commit install\n```\n\n### Release setup\n\nTo release a new version:\n\n```sh\nmake release bump=$$VERSION_PART_TO_BUMP$$\n```\n\n#### How to bumpversion\n\nThe version format for this repo is `{major}.{minor}.{patch}` for stable, and\n`{major}.{minor}.{patch}-{stage}.{devnum}` for unstable (`stage` can be alpha or beta).\n\nTo issue the next version in line, specify which part to bump,\nlike `make release bump=minor` or `make release bump=devnum`. This is typically done from the\nmain branch, except when releasing a beta (in which case the beta is released from main,\nand the previous stable branch is released from said branch).\n\nIf you are in a beta version, `make release bump=stage` will switch to a stable.\n\nTo issue an unstable version when the current version is stable, specify the\nnew version explicitly, like `make release bump=\"--new-version 4.0.0-alpha.1 devnum\"`\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fethereum%2Feth-tester","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fethereum%2Feth-tester","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fethereum%2Feth-tester/lists"}