Skip to main content
B20 is Base’s native token standard: an ERC-20 superset that runs as a native precompile, which makes transfers cheaper and higher-throughput than a standard contract token while keeping full ERC-20 compatibility. Roles, supply caps, pausing, policy gating, memos, and permit are built into the chain, so you don’t build, audit, or maintain that logic yourself.

How B20 works

Every B20 token is created by the singleton B20 Factory, which returns a fully configured token in a single transaction. Two variants cover the common cases:
  • Asset — configurable decimals (6–18), plus a rebase multiplier, onchain announcements, and batched issuance. Use it for real-world assets, equities, and long-tail tokens.
  • Stablecoin — fixed at 6 decimals with a self-declared ISO currency code. Use it for fiat-backed tokens.
Both variants share the same core surface: role-based access control, optional supply caps, policy-gated transfers and mints, granular pause, memos, and ERC-2612 permit. For the complete ABIs and precompile behavior, see the B20 native token standard spec. The rest of this page walks through launching a B20 Asset token: create it, mint its initial supply, and verify the balance onchain. To accept the token as payment in an app, continue with Accept a B20 payment.

Before you begin

You need Base’s Foundry build (base-forge, base-cast, base-anvil). Install the Beryl-compatible v1.1.1 release via base-foundryup:
Terminal
Standard forge cannot simulate calls to B20 precompile addresses (they hold no contract bytecode) and aborts with call to non-contract address. Base’s base-forge registers the precompiles into its EVM. It installs alongside your existing Foundry toolchain without overwriting it — use base-forge, base-cast, and base-anvil for all commands in this guide.

Verify the Activation Registry is enabled

Attempting to deploy before the Activation Registry is enabled will revert with FeatureNotActivated. Run the check for the variant you plan to deploy and confirm it returns true before proceeding:
Terminal
The examples in this guide and the use-case guides target the released Beryl interface in base-std@v1.0.0. Do not install from the moving main branch: unreleased interfaces can compile while targeting functions that are not part of the documented Beryl surface.

Set up Foundry

Terminal
This installs the Base Standard Library v1.0.0, which provides the released Beryl interfaces, constants, and encoding helpers used below. Add the remappings and the base = true flag to foundry.toml (under [profile.default]). base = true tells Base’s forge build to run the B20 precompiles inside its EVM, so the deploy script’s local simulation can call the factory:
foundry.toml
The interfaces compile with any Solidity >=0.8.20 <0.9.0.

Set up TypeScript and CLI clients

The task guides use viem@2.55.11 for application code and base-cast@v1.1.1 for operational commands. Install viem in a separate project and keep signing keys in environment variables:
Terminal
clients.ts
For CLI examples, export the same values and install jq so policy-creation scripts can read PolicyCreated from transaction receipts:
.env
Never put a funded private key in browser code, source control, shell history, or a client-visible environment variable. The task guides use a throwaway Base Sepolia signer for reproducible scripts.
The verified B20 fixture projects contain the complete imports, ABIs, simulation helper, Foundry scripts, and CLI workflows used by the byte guides.

Choose a network

Pick a network with the B20 precompiles active, then create a .env inside your b20-quickstart project directory. For full network details, see Connecting to Base.
.env
If you don’t have an account, base-cast wallet new prints a fresh address and key.
Confirm your account has ETH for gas:
Terminal
The command prints a non-zero balance. This account signs the deploy and the mint, and receives the minted supply.

Create your token

The factory’s single entry point is createB20(variant, salt, params, initCalls):
  • variant: ASSET or STABLECOIN. This guide uses ASSET.
  • salt: caller-chosen entropy that fixes the deterministic token address.
  • params: ABI-encoded name, symbol, initial admin, and decimals.
  • initCalls: optional batch of config calls applied at creation.
1

Write the create script

Use B20FactoryLib to encode params and initCalls. Create script/CreateToken.s.sol:
script/CreateToken.s.sol
Encode with B20FactoryLib. The native implementation rejects non-canonical calldata with AbiDecodeFailed; the helpers produce canonical encoding.
Asset decimals are fixed at creation and must be in [6, 18]. The supply cap is optional; the no-cap sentinel is type(uint128).max (the cap can never exceed uint128.max).
Use the STABLECOIN variant and its params encoder. A stablecoin fixes decimals at 6 and carries an immutable ISO currency code (uppercase AZ) instead of a configurable decimals value:
Everything else in this guide — roles, supply cap, minting, and verification — works identically.
2

Deploy the factory call

Terminal
On success the script logs the new token’s address. The factory is the fixed precompile at 0xB20f000000000000000000000000000000000000 (the same on every network); the tokens it creates start 0xB200...:
If you see TokenAlreadyExists, the salt keccak256("my-first-b20") is already registered on this network or anvil instance. Either restart base-anvil for a fresh state, or change the salt in the script to a unique value.
Output
3

Capture the token address

Save the address to an environment variable so the next step needs no copy-paste. The broadcast artifact holds the return value:
Terminal
Appending to .env keeps TOKEN_ADDRESS available in later steps, even in a new terminal session.
The broadcast path includes the chain ID, which the CHAIN_ID value in your .env supplies: 84532 for Sepolia, 84538453 for Vibenet, 31337 for local base-anvil.

Mint and verify

Minting requires MINT_ROLE, which initCalls granted to your account.
1

Mint supply

Terminal
base-cast send prints a receipt with status 1 (success).
2

Confirm the balance

Terminal
The token now holds minted supply onchain. Search $TOKEN_ADDRESS in the explorer to view it.

What you built

In this guide you:
  • Created a B20 Asset token with one createB20 call
  • Configured its admin, minter, and supply cap atomically via initCalls
  • Minted supply
  • Verified the balance onchain
All without writing, deploying, or auditing a token contract.

Next steps

  • Accept a B20 payment in an app: wire this token into a checkout flow that tags each payment with an order ID and reconciles it from onchain events.
  • Gate transfers or mints with PolicyRegistry policies, add granular pause, or manage roles. See the B20 token standard.