diff --git a/README.md b/README.md index d5975aea8..b27f25ce6 100644 --- a/README.md +++ b/README.md @@ -24,6 +24,26 @@ --- +## base-anvil: Base's Foundry build + +base-anvil is a fork of Foundry that teaches `forge`, `cast`, `anvil`, and `chisel` about Base's native precompiles, such as the B20 token factory, B20 tokens, the PolicyRegistry, and the ActivationRegistry. Stock Foundry can't reach them and aborts with `call to non-contract address`; base-anvil registers them into its EVM so you can build and test Base apps locally, with no live network. + +Install alongside your existing Foundry (it never overwrites stock `foundryup` or your `forge`/`cast`/`anvil`/`chisel`): + +```bash +curl -L https://raw.githubusercontent.com/base/base-anvil/HEAD/foundryup/install | bash +base-foundryup +``` + +This adds `base-foundryup` and the namespaced `base-forge`/`base-cast`/`base-anvil`/`base-chisel` commands, which enable Base precompiles by default. + +- **Test your Base app with base-anvil:** [`docs/base.md`](./docs/base.md) +- **Release model and the `base/base` pin (maintainers):** [`RELEASES.md`](./RELEASES.md) + +Everything below is inherited from upstream Foundry and works unchanged; only the Base additions above are specific to this fork. + +--- + ### Foundry is a blazing fast, portable and modular toolkit for Ethereum application development written in Rust. Foundry consists of: @@ -66,6 +86,8 @@ Foundry consists of: ## Installation +> **Installing the Base build?** Use `base-foundryup`, not the stock `foundryup` shown below. See [base-anvil: Base's Foundry build](#base-anvil-bases-foundry-build) above. The steps below install upstream Foundry. + Getting started is very easy: Install `foundryup`: diff --git a/docs/base.md b/docs/base.md index 7bfebbbe9..36d377cf2 100644 --- a/docs/base.md +++ b/docs/base.md @@ -1,8 +1,20 @@ # Testing your Base app with base-anvil `base-anvil` is a build of Foundry (`forge`, `anvil`, `cast`, `chisel`) that -understands Base's native precompiles. It lets you build and test Base apps -against real precompile behavior, locally, without a live network. +understands Base's native precompiles, such as the B20 token factory, B20 tokens, +the PolicyRegistry, and the ActivationRegistry. It lets you build and test Base +apps against real precompile behavior, locally, without a live network. + +Stock Foundry knows nothing about these precompiles. A `forge test` that calls a +B20 precompile address gets empty data back (the address holds no bytecode), and +high-level calls abort with `call to non-contract address`. base-anvil registers +the precompiles into Foundry's in-process EVM, so the same call runs the real +Base behavior, with no node and no RPC round-trips. + +> base-anvil does not reimplement the precompiles; it compiles them in from +> [`base/base`](https://github.com/base/base), so each build reproduces a +> specific `base/base` commit and you test exactly what the chain runs. See +> [`RELEASES.md`](../RELEASES.md) for how the pin and release naming work. ## Install @@ -18,10 +30,7 @@ installs the Base build under **namespaced commands**: `base-forge`, `base-cast` `forge`/`cast`/`anvil`/`chisel`, is left completely untouched, so the two toolchains coexist: keep using `forge` for everyday work, and reach for `base-forge` only when you want Base precompile behavior. Re-run `base-foundryup` -any time to update. Each build reproduces a specific `base/base` commit, shown -in the title of its [GitHub release](https://github.com/base/base-anvil/releases) -(`anvil --version` reports base-anvil's own build version and commit, not the -`base/base` commit). +any time to update. > `base-foundryup` and `foundryup` are independent: `base-foundryup` manages only > the Base build and self-updates separately, so installing or updating Base @@ -51,8 +60,8 @@ base-forge install base/base-std ``` [base-std](https://github.com/base/base-std) provides the Solidity handles for the -precompiles: `StdPrecompiles.sol` plus `IB20`, `IB20Factory`, `IPolicyRegistry`, -and `IActivationRegistry`. +precompiles, including `StdPrecompiles.sol`, `IB20`, `IB20Factory`, +`IPolicyRegistry`, and `IActivationRegistry`. ## Run your tests @@ -78,3 +87,57 @@ while your stock `forge`/`anvil` continue to behave exactly as before. > `foundry.toml` profile (run with `FOUNDRY_PROFILE=base forge test`), or the > `FOUNDRY_BASE=true` environment variable. The `base-*` commands are simply a > preconfigured, non-clobbering convenience. + +## What is Base-specific + +base-anvil is otherwise stock Foundry. The full command reference for `forge`, +`cast`, `anvil`, and `chisel` (every subcommand and flag) is the upstream Foundry +documentation at [getfoundry.sh](https://getfoundry.sh), and `base-forge --help` +/ `base-anvil --help` print the same. Only the following are added by this fork: + +| Addition | Applies to | What it does | +| --- | --- | --- | +| `base-forge`, `base-cast`, `base-anvil`, `base-chisel` | all | Wrappers that run the Base build with precompiles enabled by default. Installed by `base-foundryup`. | +| `--base` flag | `anvil` | Installs the Base precompiles into the node's EVM. The `base-anvil` wrapper passes this for you. | +| `base = true` (in `foundry.toml`) | `forge`, `cast`, `chisel` | Installs the Base precompiles into the in-process EVM. Read from the active profile. | +| `FOUNDRY_BASE=true` (env) | `forge`, `cast`, `chisel` | Same as `base = true`, set via the environment. | +| `base-foundryup` | installer | Base-only installer; select a version with `--install ` (e.g. `v1.1.0`, `nightly`). Never touches stock `foundryup`. | + +Because the precompiles are native, a `base-cast call` against a precompile +address over RPC only returns data if the node itself runs them (a `base-anvil` +node, or a live Base RPC). In a pure local test, the precompiles live inside +`base-forge`'s own in-process EVM. + +## The local base-anvil node + +A `base-anvil` node starts with Base's activation-gated features (such as B20 +asset, B20 stablecoin, and PolicyRegistry) already active, matching a live +Beryl-or-later chain, so you do not need to `activate()` anything by hand. Its +chain id is `31337` and it ships the usual anvil pre-funded dev accounts. + +Networks that already have the precompiles active, for testing against a remote +chain: + +| Network | RPC URL | Chain ID | +| --- | --- | --- | +| Local (`base-anvil`) | `http://127.0.0.1:8545` | `31337` | +| Base Sepolia | `https://sepolia.base.org` | `84532` | +| Vibenet | `https://rpc.vibes.base.org/` | `84538453` | + +## Troubleshooting + +| Symptom | Cause and fix | +| --- | --- | +| `call to non-contract address 0x...` at a precompile | You are running stock `forge`, or Base is not enabled. Use `base-forge`, or set `base = true` / `FOUNDRY_BASE=true`. | +| `FeatureNotActivated` against a live network | The precompile's feature is not activated on that chain yet. Local `base-anvil` seeds them active; on a network, use one where the feature is live. | +| Behavior differs from the chain you expect | Your installed build may reproduce a different `base/base` commit than the chain you are comparing against. Check the release title / [`RELEASES.md`](../RELEASES.md) and re-install the matching version with `base-foundryup --install `. | + +## Next steps + +- **Launch a B20 token end to end:** the Base docs walkthrough at + [docs.base.org/get-started/launch-b20-token](https://docs.base.org/get-started/launch-b20-token) + creates a token, mints supply, and verifies the balance using these commands. +- **The B20 token standard:** + [docs.base.org/base-chain/specs/upgrades/beryl/b20](https://docs.base.org/base-chain/specs/upgrades/beryl/b20). +- **Maintainers, the `base/base` pin and release lifecycle:** + [`RELEASES.md`](../RELEASES.md).