{"id":13751204,"url":"https://github.com/shadow-hq/shadow-reth","last_synced_at":"2025-05-09T17:33:22.189Z","repository":{"id":241801862,"uuid":"804428398","full_name":"shadow-hq/shadow-reth","owner":"shadow-hq","description":"A single-node implementation of a Shadow RPC on top of Reth, utilizing ExEx and custom RPC methods.","archived":false,"fork":false,"pushed_at":"2024-12-16T09:22:37.000Z","size":1468,"stargazers_count":99,"open_issues_count":4,"forks_count":12,"subscribers_count":4,"default_branch":"main","last_synced_at":"2025-05-03T15:54:39.729Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"https://app.shadow.xyz","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/shadow-hq.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE-APACHE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":"CODEOWNERS","security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-05-22T15:10:24.000Z","updated_at":"2025-04-25T16:34:10.000Z","dependencies_parsed_at":"2024-05-30T05:27:08.588Z","dependency_job_id":"e0cc8721-3a38-4478-9e82-7e23f9f0a103","html_url":"https://github.com/shadow-hq/shadow-reth","commit_stats":null,"previous_names":["shadow-hq/shadow-reth"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/shadow-hq%2Fshadow-reth","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/shadow-hq%2Fshadow-reth/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/shadow-hq%2Fshadow-reth/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/shadow-hq%2Fshadow-reth/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/shadow-hq","download_url":"https://codeload.github.com/shadow-hq/shadow-reth/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":253295845,"owners_count":21885709,"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-03T09:00:38.979Z","updated_at":"2025-05-09T17:33:21.761Z","avatar_url":"https://github.com/shadow-hq.png","language":"Rust","funding_links":[],"categories":["Execution Extensions (ExExes) ##"],"sub_categories":[],"readme":"# shadow-reth\n\nA single-node implementation of a Shadow RPC on top of Reth.\n\n`shadow-reth` contains a series of [Reth](https://github.com/paradigmxyz/reth) modifications that enable you to generate shadow events via [Execution Extensions](https://www.paradigm.xyz/2024/05/reth-exex), and retrieve them easily with a custom RPC Extension.\n\nSee our [blog post](https://blog.shadow.xyz/shadow-reth/) for more information.\n\n## Getting Started\n\nYou can get started with running `shadow-reth` in four steps:\n\n1. Clone this repository\n2. Generate a shadow node configuration using any external tool\n3. Build and install the `shadow-reth` binary\n4. Fetch shadow events via the `shadow_getLogs` JSON-RPC endpoint\n\n### Step 1: Clone this repository\n\n```bash\ngit clone https://github.com/shadow-hq/shadow-reth\ncd shadow-reth\n```\n\n### Step 2: Configure your shadow node\n\nTo quickly get started, you can use the example `shadow.json` file in this repository. It contains recompiled bytecode for the WETH contract with an added `ShadowTransfer` event.\n\n```bash\ncp shadow.json.example shadow.json\n```\n\nOtherwise, see the Shadow Configuration section below for detailed instructions on how to configure your shadow node.\n\n### Step 3: Build and install `shadow-reth`\n\n```bash\ncargo install --locked --path bin/shadow-reth --bin shadow-reth\n\n# start your shadow-reth node\nshadow-reth node [RETH OPTIONS]\n```\n\n### Step 4: Fetch shadow events via `shadow_getLogs`\n\n```bash\ncurl http://127.0.0.1:8545 \\\n-X POST \\\n-H \"Content-Type: application/json\" \\\n--data '{\"method\":\"shadow_getLogs\",\"params\":[{\"address\": \"0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2\"}],\"id\":1,\"jsonrpc\":\"2.0\"}' \\\n| json_pp\n```\n\n## Shadow Configuration\n\n### With Shadow\n\n1.  Navigate to https://app.shadow.xyz\n2.  Search for the contract you wish to modify using the search bar at the top of the webpage.\n\n    \u003cdetails\u003e\n    \u003csummary\u003eView Screenshot\u003c/summary\u003e\n        \u003cimg src=\"./.github/assets/s1.png\" alt=\"preview\" width=\"1920\"/\u003e\n    \u003c/details\u003e\n\n3.  Open the contract in the editor and make your changes. When you’re satisfied with your shadow contract, use the compile button, and then the deploy button.\n\n    \u003cdetails\u003e\n    \u003csummary\u003eView Screenshots\u003c/summary\u003e\n        \u003cimg src=\"./.github/assets/s2.png\" alt=\"preview\" width=\"1920\"/\u003e\n        \u003cimg src=\"./.github/assets/s3.png\" alt=\"preview\" width=\"1920\"/\u003e\n    \u003c/details\u003e\n\n4.  On the home screen, click on the “Reth ExEx” tab, then click “Download JSON”.\n\n    \u003cdetails\u003e\n    \u003csummary\u003eView Screenshots\u003c/summary\u003e\n        \u003cimg src=\"./.github/assets/s4.png\" alt=\"preview\" width=\"1920\"/\u003e\n    \u003c/details\u003e\n\n### With Foundry\n\n1. Clone the contract source from a verified contract on Etherscan.\n\n```bash\nforge clone 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2\n```\n\n2. Modify the cloned source code\n3. Compile your modified contract, and copy the deployed bytecode from the compiler output:\n\n```bash\n# compile your changes\nforge build\n\n# get the deployed bytecode\nCONTRACT_SRC_FILE=Contract.sol\nCONTRACT_NAME=WETH9\ngrep '\"deployedBytecode\":' out/$CONTRACT_SRC_FILE/$CONTRACT_NAME.json | sed -n 's/.*\"object\": *\"\\([^\"]*\\)\".*/\\1/p'\n```\n\n4. Add the contract address and shadow bytecode to `shadow.json`:\n\n```json\n{\n  \"0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2\": \"0x60606040...\"\n}\n```\n\n### How does it work?\n\nHere's how it works at a high level:\n\n1. Generate shadow bytecode using any external tool, such as [foundry](https://github.com/foundry-rs/foundry). This bytecode is then added to `shadow.json`, which simply maps contract addresses to their shadow bytecode.\n\n   For example, if you wanted to shadow [Wrapped Ether](https://etherscan.io/address/0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2), you would add the following to `shadow.json`:\n\n   ```json\n   {\n     \"0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2\": \"0x60606040...\"\n   }\n   ```\n\n2. Run `shadow-reth`, exactly like you would start and run a normal [Reth](https://github.com/paradigmxyz/reth) node. When a block is committed to the chain, an `ExExNotification` is emitted and handled by [ShadowExEx](./crates/exex), which re-executes each transaction in the block, using a `ShadowDatabase` (which implements `revm::Database`), with the shadow bytecode injected as defined in `shadow.json`. In addition to this, the `base_fee_per_gas` is set to 0, allowing shadow contracts to perform arbitrary computations without worrying about gas costs. Events emitted by shadow contracts are then stored in a sqlite database in revm's `datadir`.\n\n   \u003e Note: All log index fields (`block_log_index`, `transaction_log_index`) _will include_ shadow events. As a result, shadow events will be interleaved with canonical events in the same block, and log indices _will not_ match the canonical chain.\n\n3. A namespaced `shadow` JSON-RPC (see [ShadowRpc](./crates/rpc)) is exposed, which allows you to interact with your shadowed contracts. Currently, only `shadow_getLogs` is implemented, which allows you to retrieve Shadow Events emitted by your shadow contracts.\n\n   \u003e Note: for this example, we've added a simple `ShadowTransfer(address,address,uint256)` event to the Wrapped Ether shadow bytecode. This event has the signature `0xe7742d659c2c3c18fba9c357096ed6d568223cb89064e8bc947b709cba2a6ab7`.\n\n   ```bash\n   curl http://127.0.0.1:8545 \\\n   -X POST \\\n   -H \"Content-Type: application/json\" \\\n   --data '{\"method\":\"shadow_getLogs\",\"params\":[{\"address\": \"0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2\"}],\"id\":1,\"jsonrpc\":\"2.0\"}' \\\n   | json_pp\n   ```\n\n   \u003cdetails\u003e\n   \u003csummary\u003eExpand response\u003c/summary\u003e\n\n   ```json\n   {\n       \"jsonrpc\": \"2.0\",\n       \"result\": [\n           {\n               \"address\" : \"0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2\",\n               \"blockHash\" : \"0xe54e22affd13be3e77449a5af5c29d2aee11ffb4f3da44845544f4d55de24e8c\",\n               \"blockNumber\" : \"00000000012fd986\",\n               \"data\" : \"0x000000000000000000000000000000000000000000000000052a871b93874afb\",\n               \"logIndex\" : \"1\",\n               \"removed\" : false,\n               \"topics\" : [\n                   \"0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef\",\n                   \"0x000000000000000000000000961ec3bb28c9e98a040c4bded38917aa96b791be\",\n                   \"0x0000000000000000000000003fc91a3afd70395cd496c647d5a6cc9d4b2b7fad\",\n                   null\n               ],\n               \"transactionHash\" : \"0xa92037f3e25559e6ccdfdd8695286be525eb7d36f194176a4d577e6ef4409545\",\n               \"transactionIndex\" : \"123\"\n           },\n           {\n               \"address\" : \"0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2\",\n               \"blockHash\" : \"0xe54e22affd13be3e77449a5af5c29d2aee11ffb4f3da44845544f4d55de24e8c\",\n               \"blockNumber\" : \"00000000012fd986\",\n               \"data\" : \"0x000000000000000000000000000000000000000000000000052a871b93874afb\",\n               \"logIndex\" : \"2\",\n               \"removed\" : false,\n               \"topics\" : [\n                   \"0xe7742d659c2c3c18fba9c357096ed6d568223cb89064e8bc947b709cba2a6ab7\",\n                   \"0x000000000000000000000000961ec3bb28c9e98a040c4bded38917aa96b791be\",\n                   \"0x0000000000000000000000003fc91a3afd70395cd496c647d5a6cc9d4b2b7fad\",\n                   null\n               ],\n               \"transactionHash\" : \"0xa92037f3e25559e6ccdfdd8695286be525eb7d36f194176a4d577e6ef4409545\",\n               \"transactionIndex\" : \"123\"\n           },\n           ...\n       ]\n   }\n   ```\n\n   \u003c/details\u003e\n\nAs a result, `shadow-reth` allows you to run a trustless, fully open-source version of a shadow node.\n\n## Limitations\n\n- \u003cb\u003eGas limits:\u003c/b\u003e `shadow-reth` does not override gas limits when re-executing a block with `ShadowExecutor` for data consistency reasons. Transactions may fail if they run out of gas during shadow re-execution, and no shadow events will be emitted for that transaction.\n- \u003cb\u003eBackfilling:\u003c/b\u003e `shadow-reth` does not backfill shadow events. If you start running `shadow-reth` on a synced Reth node, `shadow-reth` will only generate shadow events for blocks that have been processed since `shadow-reth` was started. If you want historical shadow events, you’ll need to re-sync your Reth node from genesis. We’re working closely with the Reth team to improve this.\n- \u003cb\u003eDecoding:\u003c/b\u003e `shadow-reth` is designed to be analogous to a regular node, which doesn’t include event decoding. If you want to decode shadow events, we recommend polling the `shadow_getLogs` endpoint in a separate process.\n- \u003cb\u003eWebsockets:\u003c/b\u003e Shadow events will not be published over `eth_subscribe` websocket subscriptions.\n\n## Getting Help\n\nIf you have any questions, first see if the answer to your question can be found in the [reth book](https://paradigmxyz.github.io/reth/)\n\nIf the answer is not there and is specific to `shadow-reth`, you can:\n\n- Join the [Telegram](https://t.me/shadow_devs) to get help, or\n- Open an issue with the [bug](https://github.com/shadow-hq/shadow-reth/issues/new?assignees=\u0026template=bug.yml)\n\n## Contributing\n\nSee our [contributing guidelines](./CONTRIBUTING.md).\n\n## Security\n\nThis code has not been audited, and should not be used in any production systems.\n\n## Acknowledgements\n\n`shadow-reth` wouldn't be possible without the hard work of the following projects:\n\n- [Reth](https://github.com/paradigmxyz/reth): The foundation of `shadow-reth`, an Ethereum full node implementation that is focused on being user-friendly, highly modular, as well as being fast and efficient.\n- [Revm](https://github.com/bluealloy/revm): Revm is an EVM written in Rust that is focused on speed and simplicity. Revm is the backbone of `shadow-reth`’s `ShadowExecutor`, as well as Reth itself.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fshadow-hq%2Fshadow-reth","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fshadow-hq%2Fshadow-reth","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fshadow-hq%2Fshadow-reth/lists"}