├── .github └── workflows │ └── docker.yml ├── .gitignore ├── CONTRIBUTING.md ├── Dockerfile ├── LICENSE ├── README.md ├── SECURITY.md ├── docker-compose.yml ├── geth-entrypoint.sh ├── goerli ├── genesis-l2.json └── rollup.json ├── logo.webp └── op-node-entrypoint.sh /.github/workflows/docker.yml: -------------------------------------------------------------------------------- 1 | name: Tag Docker image 2 | 3 | on: 4 | push: 5 | branches: 6 | - 'main' 7 | tags: 8 | - 'v*' 9 | 10 | env: 11 | REGISTRY: ghcr.io 12 | IMAGE_NAME: ${{ github.repository }} 13 | 14 | jobs: 15 | build: 16 | runs-on: ubuntu-latest 17 | steps: 18 | - name: Checkout 19 | uses: actions/checkout@v2 20 | 21 | - name: Log into the Container registry 22 | uses: docker/login-action@v2 23 | with: 24 | registry: ${{ env.REGISTRY }} 25 | username: ${{ github.actor }} 26 | password: ${{ secrets.GITHUB_TOKEN }} 27 | 28 | - name: Extract metadata for the Docker image 29 | id: meta 30 | uses: docker/metadata-action@v4 31 | with: 32 | images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} 33 | 34 | - name: Build and push the Docker image 35 | uses: docker/build-push-action@v4 36 | with: 37 | context: . 38 | push: true 39 | tags: ${{ steps.meta.outputs.tags }} 40 | labels: ${{ steps.meta.outputs.labels }} 41 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /.idea/ 2 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing to Base Node 2 | 3 | ## Code of Conduct 4 | 5 | All interactions with this project follow our [Code of Conduct][code-of-conduct]. 6 | By participating, you are expected to honor this code. Violators can be banned 7 | from further participation in this project, or potentially all Base and/or 8 | Coinbase 9 | projects. 10 | 11 | [code-of-conduct]: https://github.com/coinbase/code-of-conduct 12 | 13 | ## Bug Reports 14 | 15 | * Ensure your issue [has not already been reported][1]. It may already be fixed! 16 | * Include the steps you carried out to produce the problem. 17 | * Include the behavior you observed along with the behavior you expected, and 18 | why you expected it. 19 | * Include any relevant stack traces or debugging output. 20 | 21 | ## Feature Requests 22 | 23 | We welcome feedback with or without pull requests. If you have an idea for how 24 | to improve the project, great! All we ask is that you take the time to write a 25 | clear and concise explanation of what need you are trying to solve. If you have 26 | thoughts on _how_ it can be solved, include those too! 27 | 28 | The best way to see a feature added, however, is to submit a pull request. 29 | 30 | ## Pull Requests 31 | 32 | * Before creating your pull request, it's usually worth asking if the code 33 | you're planning on writing will actually be considered for merging. You can 34 | do this by [opening an issue][1] and asking. It may also help give the 35 | maintainers context for when the time comes to review your code. 36 | 37 | * Ensure your [commit messages are well-written][2]. This can double as your 38 | pull request message, so it pays to take the time to write a clear message. 39 | 40 | * Add tests for your feature. You should be able to look at other tests for 41 | examples. If you're unsure, don't hesitate to [open an issue][1] and ask! 42 | 43 | * Submit your pull request! 44 | 45 | ## Support Requests 46 | 47 | For security reasons, any communication referencing support tickets for Coinbase 48 | products will be ignored. The request will have its content redacted and will 49 | be locked to prevent further discussion. 50 | 51 | All support requests must be made via [our support team][3]. 52 | 53 | [1]: https://github.com/base-org/node/issues 54 | [2]: https://medium.com/brigade-engineering/the-secrets-to-great-commit-messages-106fc0a92a25 55 | [3]: https://support.coinbase.com/customer/en/portal/articles/2288496-how-can-i-contact-coinbase-support- 56 | 57 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM golang:1.19 as op 2 | 3 | WORKDIR /app 4 | 5 | ENV REPO=https://github.com/ethereum-optimism/optimism.git 6 | ENV COMMIT=09d23ee8995b7c318a4469a49276f9453535c6a9 7 | RUN git init && \ 8 | git remote add origin $REPO && \ 9 | git fetch --depth=1 origin $COMMIT && \ 10 | git reset --hard FETCH_HEAD 11 | 12 | RUN cd op-node && \ 13 | make op-node 14 | 15 | 16 | FROM golang:1.19 as geth 17 | 18 | WORKDIR /app 19 | 20 | ENV REPO=https://github.com/ethereum-optimism/op-geth.git 21 | ENV COMMIT=a84992a3b7c33f038ccc69e761bafeefcd605fd3 22 | RUN git init && \ 23 | git remote add origin $REPO && \ 24 | git fetch --depth=1 origin $COMMIT && \ 25 | git reset --hard FETCH_HEAD 26 | 27 | RUN go run build/ci.go install -static ./cmd/geth 28 | 29 | 30 | FROM golang:1.19 31 | 32 | RUN apt-get update && \ 33 | apt-get install -y jq curl 34 | 35 | WORKDIR /app 36 | 37 | COPY --from=op /app/op-node/bin/op-node ./ 38 | COPY --from=geth /app/build/bin/geth ./ 39 | COPY . . 40 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 base.org contributors 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ![Base](logo.webp) 2 | 3 | # Base node 4 | 5 | Base is a secure, low-cost, developer-friendly Ethereum L2 built to bring the next billion users onchain. It's built on Optimism’s open-source [OP Stack](https://stack.optimism.io/). 6 | 7 | This repository contains the relevant Docker builds to run your own node on the Base network. 8 | 9 | 10 | 11 | [![GitHub contributors](https://img.shields.io/github/contributors/base-org/node)](https://github.com/base-org/node/graphs/contributors) 12 | [![GitHub commit activity](https://img.shields.io/github/commit-activity/w/base-org/node)](https://github.com/base-org/node/graphs/contributors) 13 | [![GitHub Stars](https://img.shields.io/github/stars/base-org/node.svg)](https://github.com/base-org/node/stargazers) 14 | ![GitHub repo size](https://img.shields.io/github/repo-size/base-org/node) 15 | [![GitHub](https://img.shields.io/github/license/base-org/node?color=blue)](https://github.com/base-org/node/blob/main/LICENSE) 16 | 17 | 18 | 19 | [![Website base.org](https://img.shields.io/website-up-down-green-red/https/base.org.svg)](https://base.org) 20 | [![Blog](https://img.shields.io/badge/blog-up-green)](https://base.mirror.xyz/) 21 | [![Docs](https://img.shields.io/badge/docs-up-green)](https://docs.base.org/) 22 | [![Twitter BuildOnBase](https://img.shields.io/twitter/follow/BuildOnBase?style=social)](https://twitter.com/BuildOnBase) 23 | 24 | 25 | 26 | [![GitHub pull requests by-label](https://img.shields.io/github/issues-pr-raw/base-org/node)](https://github.com/base-org/node/pulls) 27 | [![GitHub Issues](https://img.shields.io/github/issues-raw/base-org/node.svg)](https://github.com/base-org/node/issues) 28 | 29 | ### Hardware requirements 30 | 31 | We recommend you have this configuration to run a node: 32 | 33 | - at least 16 GB RAM 34 | - an SSD drive with at least 100 GB free 35 | 36 | ### Troubleshooting 37 | 38 | If you encounter problems with your node, please open a [GitHub issue](https://github.com/base-org/node/issues/new/choose) or reach out on our [Discord](https://discord.gg/buildonbase): 39 | 40 | - Once you've joined, in the Discord app go to `server menu` > `Linked Roles` > `connect GitHub` and connect your GitHub account so you can gain access to our developer channels 41 | - Report your issue in `#🛟|node-support` 42 | 43 | ### Supported networks 44 | 45 | | Ethereum Network | Status | 46 | | ---------------- | ------ | 47 | | Goerli testnet | ✅ | 48 | | Mainnet | 🚧 | 49 | 50 | ### Usage 51 | 52 | 1. Ensure you have an Ethereum Goerli L1 full node RPC available (not Base Goerli), and set `OP_NODE_L1_ETH_RPC` (in `docker-compose.yml` if using docker-compose). If running your own L1 node, it needs to be synced before Base will be able to fully sync. 53 | 2. Run: 54 | 55 | ``` 56 | docker compose up --build 57 | ``` 58 | 59 | 3. You should now be able to `curl` your Base node: 60 | 61 | ``` 62 | curl -d '{"id":0,"jsonrpc":"2.0","method":"eth_getBlockByNumber","params":["latest",false]}' \ 63 | -H "Content-Type: application/json" http://localhost:8545 64 | ``` 65 | 66 | Note: Some L1 nodes (e.g. Erigon) do not support fetching storage proofs. You can work around this by specifying `--l1.trustrpc` when starting op-node (add it in `op-node-entrypoint.sh` and rebuild the docker image with `docker compose build`.) Do not do this unless you fully trust the L1 node provider. 67 | 68 | You can map a local data directory for `op-geth` by adding a volume mapping to the `docker-compose.yaml`: 69 | 70 | ```yaml 71 | services: 72 | geth: # this is Optimism's geth client 73 | ... 74 | volumes: 75 | - $HOME/data/base:/data 76 | ``` 77 | 78 | ### Syncing 79 | 80 | Sync speed depends on your L1 node, as the majority of the chain is derived from data submitted to the L1. You can check your syncing status using the `optimism_syncStatus` RPC on the `op-node` container. Example: 81 | 82 | ``` 83 | command -v jq &> /dev/null || { echo "jq is not installed" 1>&2 ; } 84 | echo Latest synced block behind by: \ 85 | $((($( date +%s )-\ 86 | $( curl -s -d '{"id":0,"jsonrpc":"2.0","method":"optimism_syncStatus"}' -H "Content-Type: application/json" http://localhost:7545 | 87 | jq -r .result.unsafe_l2.timestamp))/60)) minutes 88 | ``` 89 | -------------------------------------------------------------------------------- /SECURITY.md: -------------------------------------------------------------------------------- 1 | # Security 2 | 3 | ## Bug bounty program 4 | 5 | In line with our strategy of being the safest way for users to access crypto: 6 | 7 | + Coinbase will be extending our [best-in-industry][1] million-dollar [HackerOne bug bounty program][2] 8 | to cover the Base network, the Base bridge contracts, and Base infrastructure. 9 | 10 | + Coinbase will be working in tandem with OP Labs to harden the security 11 | guarantees of Bedrock and accelerate the timeline for decentralized 12 | fault-proofs on the [OP Stack][3]. 13 | 14 | + Coinbase's bug bounty program will run alongside Optimism's existing [Immunefi Bedrock bounty program][4] 15 | to support the open source [Bedrock][5] OP Stack framework. 16 | 17 | ## Reporting vulnerabilities 18 | 19 | All potential vulnerability reports can be submitted via the [HackerOne][6] 20 | platform. 21 | 22 | The HackerOne platform allows us to have a centralized and single reporting 23 | source for us to deliver optimized SLA's and results. All reports submitted to 24 | the platform are triaged around the clock by our team of Coinbase engineers 25 | with domain knowledge, assuring the best quality of review. 26 | 27 | For more information on reporting vulnerabilities and our HackerOne bug bounty 28 | program, view our [security program policies][7]. 29 | 30 | [1]: https://www.coinbase.com/blog/celebrating-10-years-of-our-bug-bounty-program 31 | [2]: https://hackerone.com/coinbase?type=team 32 | [3]: https://stack.optimism.io/ 33 | [4]: https://immunefi.com/bounty/optimism/ 34 | [5]: https://stack.optimism.io/docs/releases/bedrock/ 35 | [6]: https://hackerone.com/coinbase 36 | [7]: https://hackerone.com/coinbase?view_policy=true 37 | 38 | 39 | -------------------------------------------------------------------------------- /docker-compose.yml: -------------------------------------------------------------------------------- 1 | services: 2 | geth: # this is Optimism's geth client 3 | build: . 4 | ports: 5 | - 8545:8545 6 | - 8546:8546 7 | - 30303:30303 8 | command: [ "sh", "./geth-entrypoint.sh" ] 9 | environment: 10 | - OP_GETH_GENESIS_FILE_PATH=goerli/genesis-l2.json 11 | - OP_GETH_SEQUENCER_HTTP=https://goerli.base.org 12 | - OP_NODE_L2_ENGINE_AUTH=/tmp/engine-auth-jwt 13 | - OP_NODE_L2_ENGINE_AUTH_RAW=688f5d737bad920bdfb2fc2f488d6b6209eebda1dae949a8de91398d932c517a # for localdev only 14 | # - OP_GETH_ETH_STATS=nodename:secret@host:port # optional 15 | node: 16 | build: . 17 | depends_on: 18 | - geth 19 | ports: 20 | - 7545:8545 21 | - 9222:9222 22 | - 7300:7300 # metrics 23 | - 6060:6060 24 | command: [ "sh", "./op-node-entrypoint.sh" ] 25 | environment: 26 | - OP_NODE_L1_ETH_RPC=https://ethereum-goerli-rpc.allthatnode.com # [recommended] replace with your preferred L1 (ethereum, not Base) node RPC URL 27 | - OP_NODE_L2_ENGINE_AUTH=/tmp/engine-auth-jwt 28 | - OP_NODE_L2_ENGINE_AUTH_RAW=688f5d737bad920bdfb2fc2f488d6b6209eebda1dae949a8de91398d932c517a # for localdev only 29 | - OP_NODE_L2_ENGINE_RPC=http://geth:8551 30 | - OP_NODE_LOG_LEVEL=info 31 | - OP_NODE_METRICS_ADDR=0.0.0.0 32 | - OP_NODE_METRICS_ENABLED=true 33 | - OP_NODE_METRICS_PORT=7300 34 | - OP_NODE_P2P_AGENT=base 35 | - OP_NODE_P2P_BOOTNODES=enr:-J64QBbwPjPLZ6IOOToOLsSjtFUjjzN66qmBZdUexpO32Klrc458Q24kbty2PdRaLacHM5z-cZQr8mjeQu3pik6jPSOGAYYFIqBfgmlkgnY0gmlwhDaRWFWHb3BzdGFja4SzlAUAiXNlY3AyNTZrMaECmeSnJh7zjKrDSPoNMGXoopeDF4hhpj5I0OsQUUt4u8uDdGNwgiQGg3VkcIIkBg,enr:-J64QAlTCDa188Hl1OGv5_2Kj2nWCsvxMVc_rEnLtw7RPFbOfqUOV6khXT_PH6cC603I2ynY31rSQ8sI9gLeJbfFGaWGAYYFIrpdgmlkgnY0gmlwhANWgzCHb3BzdGFja4SzlAUAiXNlY3AyNTZrMaECkySjcg-2v0uWAsFsZZu43qNHppGr2D5F913Qqs5jDCGDdGNwgiQGg3VkcIIkBg 36 | - OP_NODE_P2P_LISTEN_IP=0.0.0.0 37 | - OP_NODE_P2P_LISTEN_TCP_PORT=9222 38 | - OP_NODE_P2P_LISTEN_UDP_PORT=9222 39 | - OP_NODE_ROLLUP_CONFIG=goerli/rollup.json 40 | - OP_NODE_RPC_ADDR=0.0.0.0 41 | - OP_NODE_RPC_PORT=8545 42 | - OP_NODE_SNAPSHOT_LOG=/tmp/op-node-snapshot-log 43 | - OP_NODE_VERIFIER_L1_CONFS=0 44 | # OP_NODE_L1_TRUST_RPC allows for faster syncing, but should be used *only* if your L1 RPC node 45 | # is fully trusted. It also allows op-node to work with clients such as Erigon that do not 46 | # support storage proofs. 47 | # - OP_NODE_L1_TRUST_RPC=true 48 | -------------------------------------------------------------------------------- /geth-entrypoint.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -eu 3 | 4 | VERBOSITY=${GETH_VERBOSITY:-3} 5 | GETH_DATA_DIR=/data 6 | GETH_CHAINDATA_DIR="$GETH_DATA_DIR/geth/chaindata" 7 | OP_GETH_GENESIS_FILE_PATH="${OP_GETH_GENESIS_FILE_PATH:-/genesis.json}" 8 | CHAIN_ID=$(jq -r .config.chainId < "$OP_GETH_GENESIS_FILE_PATH") 9 | RPC_PORT="${RPC_PORT:-8545}" 10 | WS_PORT="${WS_PORT:-8546}" 11 | AUTHRPC_PORT="${AUTHRPC_PORT:-8551}" 12 | HOST_IP="0.0.0.0" 13 | ADDITIONAL_ARGS="" 14 | 15 | mkdir -p $GETH_DATA_DIR 16 | 17 | if [ ! -d "$GETH_CHAINDATA_DIR" ]; then 18 | echo "$GETH_CHAINDATA_DIR missing, running init" 19 | echo "Initializing genesis." 20 | ./geth --verbosity="$VERBOSITY" init \ 21 | --datadir="$GETH_DATA_DIR" \ 22 | "$OP_GETH_GENESIS_FILE_PATH" 23 | else 24 | echo "$GETH_CHAINDATA_DIR exists." 25 | fi 26 | 27 | echo "$OP_NODE_L2_ENGINE_AUTH_RAW" > "$OP_NODE_L2_ENGINE_AUTH" 28 | 29 | if [ "${OP_GETH_ETH_STATS+x}" = x ]; then 30 | ADDITIONAL_ARGS="$ADDITIONAL_ARGS --ethstats=$OP_GETH_ETH_STATS" 31 | fi 32 | 33 | ./geth \ 34 | --datadir="$GETH_DATA_DIR" \ 35 | --verbosity="$VERBOSITY" \ 36 | --http \ 37 | --http.corsdomain="*" \ 38 | --http.vhosts="*" \ 39 | --http.addr=0.0.0.0 \ 40 | --http.port="$RPC_PORT" \ 41 | --http.api=web3,debug,eth,txpool,net,engine \ 42 | --authrpc.addr=0.0.0.0 \ 43 | --authrpc.port="$AUTHRPC_PORT" \ 44 | --authrpc.vhosts="*" \ 45 | --authrpc.jwtsecret="$OP_NODE_L2_ENGINE_AUTH" \ 46 | --ws \ 47 | --ws.addr=0.0.0.0 \ 48 | --ws.port="$WS_PORT" \ 49 | --ws.origins="*" \ 50 | --ws.api=debug,eth,txpool,net,engine \ 51 | --syncmode=full \ 52 | --gcmode=archive \ 53 | --nodiscover \ 54 | --maxpeers=100 \ 55 | --nat=extip:$HOST_IP \ 56 | --networkid="$CHAIN_ID" \ 57 | --rollup.sequencerhttp="$OP_GETH_SEQUENCER_HTTP" \ 58 | $ADDITIONAL_ARGS # intentionally unquoted 59 | -------------------------------------------------------------------------------- /goerli/rollup.json: -------------------------------------------------------------------------------- 1 | { 2 | "genesis": { 3 | "l1": { 4 | "hash": "0x73d89754a1e0387b89520d989d3be9c37c1f32495a88faf1ea05c61121ab0d19", 5 | "number": 8410981 6 | }, 7 | "l2": { 8 | "hash": "0xa3ab140f15ea7f7443a4702da64c10314eb04d488e72974e02e2d728096b4f76", 9 | "number": 0 10 | }, 11 | "l2_time": 1675193616, 12 | "system_config": { 13 | "batcherAddr": "0x2d679b567db6187c0c8323fa982cfb88b74dbcc7", 14 | "overhead": "0x0000000000000000000000000000000000000000000000000000000000000834", 15 | "scalar": "0x00000000000000000000000000000000000000000000000000000000000f4240", 16 | "gasLimit": 25000000 17 | } 18 | }, 19 | "block_time": 2, 20 | "max_sequencer_drift": 600, 21 | "seq_window_size": 3600, 22 | "channel_timeout": 300, 23 | "l1_chain_id": 5, 24 | "l2_chain_id": 84531, 25 | "batch_inbox_address": "0x8453100000000000000000000000000000000000", 26 | "deposit_contract_address": "0xe93c8cd0d409341205a592f8c4ac1a5fe5585cfa", 27 | "l1_system_config_address": "0xb15eea247ece011c68a614e4a77ad648ff495bc1", 28 | "regolith_time": 1683219600 29 | } 30 | -------------------------------------------------------------------------------- /logo.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/android7770/node/68018f79456714cadde1d7e877b286921b29bbb5/logo.webp -------------------------------------------------------------------------------- /op-node-entrypoint.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -eu 3 | 4 | # wait until local geth comes up (authed so will return 401 without token) 5 | until [ "$(curl -s -w '%{http_code}' -o /dev/null "$OP_NODE_L2_ENGINE_RPC")" -eq 401 ]; do 6 | echo "waiting for geth to be ready" 7 | sleep 5 8 | done 9 | 10 | # public-facing P2P node, advertise public IP address 11 | PUBLIC_IP=$(curl -s v4.ident.me) 12 | export OP_NODE_P2P_ADVERTISE_IP=$PUBLIC_IP 13 | 14 | echo "$OP_NODE_L2_ENGINE_AUTH_RAW" > "$OP_NODE_L2_ENGINE_AUTH" 15 | 16 | ./op-node 17 | --------------------------------------------------------------------------------