[ 15 / 16 ] · Monad课程

第 15 课:Reading the Monad Codebase

14 分钟400 XP

踏上构建生产级应用的旅程。

此课程的中文翻译正在进行中,当前显示英文版本。

You've learned what Monad is, how the EVM works, and how proposals make their way through the EIP and MIP process. Now you're going to look at where all of that actually lives: the open-source code that runs every Monad node.

This lesson gives you a mental map of the Monad codebase. You'll know which repos exist, what's in each one, who maintains them, and how a proposal becomes merged code. You won't be able to write protocol code after this (that takes years of practice), but you will be able to open any Monad GitHub page and know what you're looking at, follow conversations in pull requests, and figure out where to look when you want to understand how something works.

This lesson isn't a tour of every file. The codebase is large and it changes constantly. Instead, you're learning how to navigate it, so you can find what you need regardless of what version you're looking at.

The Three GitHub Orgs to Know

Monad's code lives across three GitHub organizations. Each one has a different role.

category-labs is where the actual Monad client code lives. A client is the program a computer runs to participate in the network. Every validator on Monad is running this code. If you want to read the code that actually runs the chain, this is where you go.

monad-crypto is the Monad Foundation's organization. It holds governance-level things: improvement proposals (MIPs), protocol registries, and ecosystem coordination. There's no client code here, just the documents and metadata that shape what the client teams build.

monad-developers is the developer-facing org. Specs, tooling, ecosystem libraries, and Monad's fork of Solidity all live here. If you're a developer building on Monad, you'll spend most of your time in this org.

A change in any of these orgs has a different meaning. A PR to category-labs changes how the node actually runs. A PR to monad-crypto/MIPs proposes a future change to the protocol. A PR to monad-developers improves the developer experience without touching the chain itself.

Which GitHub org holds the actual Monad client code that every validator runs?

The Two Main Client Repos

Inside category-labs, the two repos that matter most are monad-bft and monad. Together they form a complete Monad node.

monad-bft is the consensus client. It's written in Rust. This is where MonadBFT lives, where the network layer (RaptorCast) lives, and where the JSON-RPC server that talks to wallets lives. If a transaction comes into the network, monad-bft is the part that decides whether it's valid, orders it among other transactions, and reaches agreement with other validators on what should be in the next block.

monad is the execution client. It's written in C++. This is where the custom EVM implementation lives, where MonadDB lives, and where transaction scheduling for parallel execution happens. Once consensus has decided which transactions go in a block, monad is the part that actually runs them, updates state, and stores the results.

Why two languages? Rust and C++ are both performance-critical systems languages, but they emphasize different things. Rust has stronger memory safety guarantees out of the box, which matters for consensus code where bugs can be exploited to halt the network. C++ gives you very fine-grained control over memory layout and instruction selection, which matters for the EVM, where every nanosecond compounds across millions of transactions. The split is intentional.

Why two repos? Because they're separate processes that talk over a well-defined interface. The consensus client can be improved independently of the execution client and vice versa. It makes the codebase easier to navigate, because each repo has a clear job.

Which repo is the execution client, and what language is it written in?

From GitHub to the Network

A quick clarification before going further. The repos you see on GitHub hold the source code, not the running network. Here's how the two connect.

Monad runs on validators. A validator is a powerful computer, sitting in a data center somewhere, run by a person or company (the validator operator). To become a validator, someone has to first go to GitHub, download the monad-bft and monad source code, compile it into a runnable program, and install that program on their machine. Then they configure it, point it at the rest of the network, and start it running.

Once running, that program is what we mean when we say "a node." Every validator is running its own copy of monad-bft and monad. There are validators all over the world doing this right now, each one running the same code, in sync with the others.

When you send a transaction, it travels through a few hops before becoming part of the chain.

The first hop is an RPC node.

RPC stands for Remote Procedure Call, which is just a way for one program to ask another program to do something over the internet. Your wallet is one program. The Monad network is a collection of other programs. RPC is how they talk.

An RPC node is the specific kind of computer that listens for those requests. It's running the same Monad software as a validator, but its job is different. A validator's job is to vote on blocks. An RPC node's job is to handle incoming requests from outside: things like "what's my balance?" or "please send this transaction to the network." When your wallet wants to do anything on Monad, it sends an RPC request to an RPC node, and the RPC node handles it from there.

You don't have to run your own RPC node to use Monad. Most people use ones run by companies like Alchemy and Infura, which run thousands of RPC nodes professionally and let wallets and apps connect to them for free or at low cost. Monad teams run RPC nodes too. When a wallet like MetaMask is set up to use Monad, it has the address of one of these RPC nodes saved in its settings, and that's where every request goes.

From the RPC node, the transaction's path continues:

  1. The RPC node forwards the transaction to the validators it's connected to.
  2. Each validator that receives it places it in its mempool, a holding area for transactions that haven't yet been included in a block.
  3. When it's a validator's turn to propose a block (every 400ms in Monad), that validator picks transactions from its own mempool, bundles them, and sends the proposed block to all other validators.
  4. The other validators run their copies of monad-bft to vote on whether the block is valid. Once enough agree, the block becomes part of the chain.
  5. Each validator's copy of monad then executes the transactions in the block, updating its local state.

GitHub never touches any of this. GitHub is just the warehouse where the source code lives between releases. The actual work happens on the validators' machines, in copies of the program they downloaded earlier.

When the code changes, those running copies don't update by themselves. The flow looks like this:

  1. A change gets merged into the GitHub repo.
  2. A new version of the client (called a release) gets built and published.
  3. Validator operators see the new release. They download it, install it on their machines, and restart their node software with the new version.
  4. For most changes, validators can do this whenever they want, on their own schedule. The new code runs once they restart.
  5. For changes that affect what counts as a valid block (a hard fork), validators don't all upgrade at the same moment. That would be a coordination nightmare. Instead, they upgrade ahead of time to a version that contains both the old and new behavior. The validator automatically switches behavior based on which block / slot it is operating on.

This is why MIPs that change protocol behavior are a bigger deal than regular performance PRs. A performance PR ships whenever each validator decides to upgrade. A hard fork needs the whole network to coordinate.

What is the job of an RPC node, as opposed to a validator?

Inside monad-bft

When you open monad-bft, you'll see it's organized into smaller pieces (called crates in Rust). The ones worth knowing:

  • monad-bft itself. The consensus engine. Implements MonadBFT: leader rotation, voting rounds, signature aggregation, the works.
  • monad-crypto. The cryptography sub-crate. Cryptography is the math that lets validators sign things, prove things, and check each other's signatures without trusting one another. monad-bft calls into this sub-crate constantly to do any cryptographic work it needs. The dedicated cryptography lessons later in this track explain what's inside.
  • monad-dataplane. The network layer. This is where RaptorCast lives, the protocol that gets blocks from the leader to all validators within a 400ms window.
  • monad-eth-block-policy and monad-eth-block-validator. Block validation rules. What makes a block valid, what makes it invalid, what edge cases need handling.
  • RPC server. The part that wallets and applications talk to. When MetaMask sends a transaction, it lands here first.

If you ever want to know how something specific works (say, how a validator's vote is encoded), the file structure tells you where to look. Vote-related code lives in the consensus sub-crate. Network propagation lives in dataplane. Cryptographic verification lives in monad-crypto.

Inside monad

The monad repo is structured differently because it's C++ instead of Rust, but the same principle holds: each major subsystem has its own directory. The ones to know:

  • EVM implementation. Category Labs ships two custom EVMs: an interpreter and a compiler that translates contracts into machine code. These are what execute transactions.
  • MonadDB. The state database. Built from scratch for speed, so that multiple reads can happen at the same time and disk access doesn't block execution. The dedicated "Why MonadDB Exists" lesson in this track covers it in depth.
  • Transaction scheduling. The logic that decides which transactions can run in parallel without conflicting. This is the heart of Monad's parallel execution model.

If you're following an MIP that touches storage (like MIP-8), the relevant code lives in monad. If you're following one that touches consensus (like MIP-10), it's in monad-bft.

Where does MonadDB, the state database built from scratch for speed, live?

The Other Repos Worth Knowing

Beyond the two main clients, a few other repos are worth bookmarking.

monad-crypto/MIPs is where Monad Improvement Proposals live. Each MIP is a Markdown file in this repo. Drafts get opened as pull requests. Accepted MIPs sit in MIPS/. This is where MIP-8 (page-aware storage) and MIP-10 (deterministic RaptorCast) live. If you want to follow what's being proposed, watching this repo is the move.

monad-crypto/protocols is a registry of deployed protocols on Monad. If you build something and want it listed on Monad's ecosystem pages, you open a PR here with a JSON file describing your protocol.

category-labs/monad-std is a Solidity standard library for Monad. This is where MIP-8-aware data structures like PagedArray live. As a vibecoder, this is the repo you'd point your agent at when designing storage that takes advantage of MIP-8.

monad-developers/execution-specs is the formal specification for Monad's execution layer. If you ever need to know exactly what behavior a Monad client should implement, this is the source of truth.

monad-developers/validator-info holds information validators need: hardware specs, configuration guides, network parameters.

You don't need to remember all of these. The names are searchable. What matters is the mental model: the foundation org holds governance, Category Labs builds the clients, and the developers org holds everything in between.

Who Maintains What

This is the part that doesn't show up in any README, but it's what makes a codebase navigable.

Category Labs maintains the client repos. The team is split across consensus, execution, and networking specialties, with a protocol research function that crosses all three.

The Monad Foundation stewards the MIPs process and the broader ecosystem. They don't write client code, but they coordinate proposals, run the forum, and decide what gets prioritized.

Individual maintainers matter even more than the team affiliation. When you read a PR, look at the author and the reviewers. Names that show up over and over again are the people with deep context on that part of the code.

External contributors show up too. Audit firms (Code4rena ran a competitive audit in late 2025). Vendors. Occasional community PRs. The bar for an external PR is higher than for internal ones, but the door is open.

How a Change Becomes Code

There are two main paths a change can take, and they correspond to the kind of change being made.

The MIP path is for protocol-level changes: things that affect consensus, the EVM, gas pricing, the data model. The flow looks like this:

  1. Someone has an idea. They post about it in the Monad forum or Discord to gauge reaction.
  2. They write a draft MIP (a Markdown file following the MIP template) and open a PR against monad-crypto/MIPs.
  3. MIP editors review the structure: does it follow the template, is the spec complete, does it have a clear motivation.
  4. Community discussion happens on the PR and in the forum. The author iterates.
  5. If the MIP reaches consensus, it moves through "Draft" to "Review" to "Last Call" to "Final" statuses.
  6. Implementation begins in category-labs/monad-bft or category-labs/monad, whichever the MIP touches.
  7. The implementation gets merged when it passes review.

The MIP itself and the implementation are two separate things. A MIP can be "Final" but not yet shipped, because the implementation hasn't been merged or hasn't been included in a network upgrade. MIP-8 is in this state today: the proposal is detailed and accepted in principle, but the implementation work is ongoing.

The client PR path is for implementation-level changes that don't require a protocol change: performance improvements, bug fixes, code cleanups, new features that don't change protocol semantics. The flow is faster:

  1. Someone opens a GitHub issue or starts an internal discussion.
  2. They open a PR against category-labs/monad-bft or category-labs/monad.
  3. Automated checks run (tests, code style, security scans).
  4. Reviewers from the relevant team comment, request changes, approve.
  5. The PR gets merged.
  6. Eventually the change ships in a node release.

Daniel Von Fange's Solidity compiler PRs are an example of the second path, even though they're not in a Monad repo. The same lifecycle applies anywhere in the EVM ecosystem.

Why can a MIP be marked Final but not yet be live on the network?

What This Means for You

You don't need to write Rust or C++ to make use of this knowledge. As a vibecoder, your agent can read this code for you. What you need is the mental model: where things are, who works on them, and how change happens. With that, a lot becomes possible.

  • You can read protocol announcements and trace them back to the specific repos and files they affect.
  • You can follow a MIP from idea to merged code, watching each step.
  • You can lurk in PR conversations and learn the social norms before you ever participate.
  • You can prompt your agent: "look at how monad-bft handles vote aggregation" or "show me the relevant files in monad for transaction scheduling" and actually understand what comes back.
  • You can identify maintainers and engage them appropriately. Đorđe is the person to ping about storage and Solidity. Other engineers own other parts.

The Monad codebase is open. The discussions are open. The proposal process is open. What keeps most people from engaging is not knowing where to look, and after this lesson, you do.

Up next

Spend a few minutes clicking around category-labs/monad-bft after you finish reading. Open a recent PR. Read the description and a few comments. You'll see the names you've been reading about, the issues being debated, the code being shipped. The gap between you and the people writing it is mostly the gap of unfamiliarity. Familiarity comes from showing up.

Next up: Reading Protocol Research Papers, so you can go straight to the source when a PR or MIP references one.

0/5 正确

0% — 全部答对即可完成

注册以记录进度