# 介绍 Monad

Monad 是与以太坊兼容的高性能 Layer1，Monad 实质性推动了区块链去中心化和扩容间博弈的有效边界。

Monad 在以下四个方面进行了优化，使区块链的吞吐量达到每秒 10,000 笔交易（tps）：

* [MonadBFT 共识机制](/monad-architecture/consensus/monadbft)
* [延迟执行（Deferred Execution）](/monad-architecture/consensus/deferred-execution)
* [并行执行（Parallel Execution）](/monad-architecture/execution/parallel-execution)
* [MonadDb 数据库](/monad-architecture/execution/monaddb)

Monad 的优化解决了现有区块链的瓶颈问题，同时为应用程序开发人员（完全兼容 EVM 字节码）和用户（兼容以太坊 RPC API）保留了完全兼容性。因此，丰富的以太坊工具和应用密码学研究可以无缝接入到 Monad，同时受益于 Monad 的高吞吐量和交易规模：

* 应用程序（在以太坊上构建的任何 Dapp）
* 开发人员工具（如：Hardhat、Apeworx、Foundry）
* 钱包（如：MetaMask）
* 链上分析/索引工具（如：Etherscan、Dune）

Monad 客户端以性能为核心，采用 C++ 和 Rust 语言编写。下文将介绍 Monad 的主要优化及用户交互。


# 为什么选择区块链？

“是什么” 和 “为什么” 的简单心智选择。

区块链是不同参与者就以下两件事达成的去中心化协议：

1. 交易的官方排序（账本）。
2. 官方全局状态，包括用户账户余额和各种程序的状态。

在以太坊等现代区块链中，交易包括余额转移、创建新程序以及对现有程序的函数调用。到目前为止，所有交易的总结果就是当前状态，这就是为什么（1）的一致性意味着（2）的一致性。

区块链系统有一组协议规则，这些规则描述了当前同步的分布式节点集将如何相互通信，以商定每个节点应该使用的新交易列表。归纳法使节点保持同步：它们从相同的状态开始，同步相同的交易，因此在使用新的交易列表结束时，它们仍然具有一致的状态。(本文将忽略这种节点系统如何达成一致的细节，但你可以参阅 Monad [共识机制](/monad-architecture/consensus)的文档，了解更多）。

共享全局状态用于开发去中心化应用程序——链上程序，即在区块链系统的每个节点上运行的应用程序。去中心化应用程序是一个代码块（以及长期的、特定于应用程序的状态），可以被任何用户调用，用户只需提交指向该应用程序功能的交易即可，区块链中的每个节点都负责正确执行被调用的字节码，重复工作可保证每个节点的诚实。

### 去中心化应用程序示例

去中心化应用程序可以实现我们可能期望以中心化方式实现的功能，去中心化应用程序的一个非常简单的例子就是虚拟银行（在加密领域通常被称为借贷协议）。

在现实世界中，银行是吸收存款并以较高利率放贷的企业，银行赚取存款和借贷之间的利差。借款人获得贷款，去做一些有经济效益的事情，存款人则从存款中赚取利息，大家都是赢家！

区块链虚拟银行只是一个拥有四种主要功能的应用程序：`存款`、`取款`、`借款`、`还款` ，每种功能的逻辑主要是记账，以确保正确跟踪存款和贷款：

```
class VirtualBank:
  def deposit(sender, amount):
    # transfer amount from sender to myself (the bank)
    # do internal bookkeeping to credit the sender

  def withdraw(sender, amount):
    # ensure the sender had enough on deposit
    # do internal bookkeeping to debit the sender
    # transfer amount from myself (the bank) to sender

  def borrow(sender, amount):
    # ...

  def repay(sender, amount);
    # ...
```

在以太坊或 Monad 中，有人可以为这个虚拟银行编写代码并上传，然后任何人都可以利用它进行借贷，与其所在国实体银行相比，区块链虚拟银行服务可能方便得多。

这个简单的例子显示了去中心化应用程序的威力，这里还有其他优势值得一提：

* **开放式应用程序接口/可组合性**：去中心化应用程序可被其他去中心化应用程序原子调用，允许开发人员通过堆栈现有组件来构建更复杂的程序功能。
* **透明性**：去中心化应用程序的功能逻辑纯粹通过代码实现，因此任何人都可以审查程序的安全性，状态是透明和可审计的，默认情况下在 DeFi 中进行开源证明。
* **抗审查和可信中立性:** 任何人都可以无需许可地向区块链提交交易或上传应用程序。
* **全球覆盖**：任何人只要能上网，就能获得重要的金融服务，包括 unbanked/underbanked 用户。


# 为什么选择 Monad: 去中心化+性能

### 去中心化很重要

区块链有几个主要组成部分：

* **共识机制**，用于就添加到分类账的交易确认达成一致。
* **执行/存储系统**，用于维持区块链活动状态。

在提高这些组件的性能时，可以偷工减料，例如要求所有节点在物理上相互靠近（以节省达成共识的开销），或要求大量使用 RAM（以将大部分或全部状态缓存在内存中），但这是以牺牲去中心化为代价的。

而去中心化正是关键所在！

正如”[为什么是区块链](https://docs.monad.xyz/technical-discussion/why-blockchain)“章节中所讨论的，去中心化的全局状态共享允许多方协调，同时依赖于单一、共享、客观的真实消息源。去中心化是问题的关键，由一小群节点操作员（或在极端情况下，一个操作员！）维护的区块链将无法拥有去信任化、可信的中立性和抗审查性等特征。

对于任何区块链网络来说，去中心化都应该是主要关注点，提高性能不应以牺牲去中心化为代价。

### 当下区块链性能瓶颈

以太坊当前的执行限制（1.25M Gas/每秒）设置得比较保守，这样做有几个理由：

* 低效的存储访问模式
* 单线程执行
* 执行时间预算非常有限，因为没有执行就无法达成共识
* 对状态增长的担忧，以及状态增长对未来状态访问成本的影响

Monad 通过改进算法和架构来解决这些局限性，开创了多项创新，有望在未来几年成为以太坊的标准。保持高度去中心化，同时进行实质性的性能优化，这是关键的考虑因素。

### 通过优化解决瓶颈问题

Monad 在以下四个主要方面实现了流水线作业并有其他优化，从而使以太坊虚拟机具有卓越的性能，极大地推动了区块链的去中心化和可扩展性博弈的有效边界。下文将介绍这些主要方面的优化：

* [MonadBFT 共识机制](/monad-architecture/consensus/monadbft)
* [延迟执行（Deferred Execution）](/monad-architecture/consensus/deferred-execution)
* [并行执行（Parallel Execution）](/monad-architecture/execution/parallel-execution)
* [MonadDb 数据库](/monad-architecture/execution/monaddb)


# 面向用户的 Monad

Monad 是与以太坊兼容的高性能 Layer1，为用户提供了两全其美的解决方案：**可复制性**和**性能**。

从可复制性的角度来看，Monad 为以太坊虚拟机（EVM）提供了**完整的字节码兼容性**，因此在太坊上构建的应用程序无需修改代码即可复制到 Monad；并且提供了**完整的以太坊RPC兼容性**，因此用户可以使用 MetaMask 或 Etherscan 等基础设施。

从性能角度来看，Monad 拥有 **10,000 tps** 的吞吐量，即每天 10 亿笔的交易量，另外 Monad 的**出块时间和区块确认时间仅为 1 秒**。这使得 Monad 能够支持比现有区块链更多的用户高并发交互，同时拥有更低廉的单笔交易成本。

### 对比以太坊，Monad 有什么相似之处？

从用户角度来看，Monad 的链上操作与以太坊非常相似。你可以使用熟悉的钱包（如 MetaMask）或区块浏览器（如 Etherscan）来签署或查看交易，在以太坊上构建的应用程序也可以复制到 Monad 上，无需修改代码，因此用户可以在 Monad 上使用最喜欢的以太坊应用程序。Monad 中的地址空间与以太坊中的地址空间相同，因此用户可以使用现有的密钥在 Monad 上创建钱包。

与以太坊一样，Monad 也具有 linear blocks 和区块内 linear ordering 排序的特点。

与以太坊一样，Monad 也是一个由去中心化的验证者维护的权益证明网络。任何人都可以运行一个节点来独立验证交易的执行情况，并且已经采取了大量措施来保持最低的硬件要求。

### 对比以太坊，Monad 有什么不同之处？

Monad 通过在以太坊虚拟机中引入**并行执行（parallel execution）**&#x548C; **超标量流水线（superscalar pipelining）**&#x6280;术，使卓越的性能成为可能。

**并行执行** 是指利用多个内核和线程有策略地并行执行交易，同时仍按原始排序提交交易结果。虽然交易在"内部"是并行执行的，但从用户和开发人员的角度来看，它们是串行执行的；一系列交易的结果总是相同的，就像这些交易是一个接一个地执行一样。

**超标量流水线** 是一种将执行单元划分为不同阶段，并且并行执行这些阶段的技术。可以通过以下图例阐明该技术：

<div align="center" data-full-width="false"><figure><img src="https://3402452340-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FPaHQrSOuX4vToXCmyjn9%2Fuploads%2FND43WdYAmOnDM7iYZGeh%2F001_.png?alt=media&amp;token=20de6591-a98b-41c6-b425-9464fbdb435b" alt=""><figcaption><p>pipelining 作业的熟悉案例：智能洗衣<br>上图：普通洗衣作业；下图：pipelined 洗衣作业<br>资料来源：<a href="https://www.cs.fsu.edu/~hawkes/cda3101lects/chap6/index.html?$$$F6.1.html$$$">Prof. Lois Hawkes, FSU</a></p></figcaption></figure></div>

当洗四件衣服时，“普通洗衣作业”的策略是在洗第二件衣服之前，完成第一件衣服的洗涤、烘干、折叠和储存；“pipelined 洗衣作业”的策略是当第一件衣服洗涤完成进入烘干机时，开始洗涤第二件衣服，通过同时利用多个资源来更有效地完成工作。

Monad 引入了 pipelining 执行技术，以解决现有区块链在状态存储、交易处理和分布式共识中的瓶颈。具体而言，Monad 在以下四个方面引入了 pipelining 技术和其他优化：

* [MonadBFT 共识机制](/monad-architecture/consensus/monadbft)（pipelined HotStuff 共识机制，以及更多的研究改进）
* [Deferred Execution / 延迟执行](/monad-architecture/consensus/deferred-execution)（在达成共识和执行之间进行 pipelining 作业，以大幅增加执行预算）
* [Parallel Execution / 并行执行](/monad-architecture/execution/parallel-execution)
* [MonadDb 数据库](/monad-architecture/execution/monaddb)（高性能状态后端）

Monad 客户端采用 C++ 和 Rust 语言编写，它反映了在这些架构上的优化，为去中心化应用程序提供了一个平台，可以真正扩展到全球范围。

### 应该关心什么？

去中心化应用程序是中心化服务的替代品，具有若干显著优势：

* **开放式应用程序接口和可组合性**：去中心化的应用程序可以被其他去中心化应用程序原子调用，允许开发人员通过堆栈现有组件来构建更复杂的功能。
* **透明性**：应用程序的逻辑纯粹通过代码表达，因此任何人都可以审查程序的安全性，状态是透明和可审计的，默认情况下在DeFi中进行开源证明。
* **抗审查和可信中立性:** 任何人都可以无需许可地向网络提交交易或上传应用程序。
* **全球覆盖**：任何人只要能上网，就能获得重要的金融服务，包括 unbanked/underbanked 用户。

然而，去中心化应用程序需要廉价、高性能的基础设施，才能达到预期的影响水平。一个拥有 100 万日活跃用户（DAUs）和每个用户每天进行10笔交易的应用程序，每天需要吞吐 1000 万笔交易，即 100 tps。快速浏览一下 [L2Beat](https://l2beat.com/scaling/activity)（一个研究 EVM 兼容的 Layer1 和 Layer2 区块链网络吞吐量和去中心化程度的网站）就会发现，目前没有任何EVM区块链支持或接近 100 tps 的吞吐量水平。

Monad 极大地提高了与 EVM 兼容的区块链网络的性能，开创了多项创新，有望在未来几年成为以太坊的标准。

有了 Monad，开发人员、用户和研究人员可以采用大量现有的为 EVM 而构建的应用程序、库和应用密码学研究。

### 如何使用 Monad ？

Monad 的首个公共测试网将在未来几个月内上线。

届时，用户可以在兼容以太坊的钱包中添加相应的 RPC URL 和 链 ID，然后像使用其他兼容以太坊的区块链一样开始使用 Monad 。在此之前，敬请期待！


# 面向开发人员的 Monad

Monad 是与以太坊兼容的 Layer1 区块链，吞吐量为 10,000 tps，区块时间为1秒，采用[单时隙确定性](https://ethereum.org/zh/roadmap/single-slot-finality/)（single-slot finality）。

Monad 对以太坊虚拟机的优化符合[上海升级](https://www.evm.codes/?fork=shanghai)的要求，使用 Monad 执行环境模拟以太坊历史交易会产生相同的结果。Monad 还与以太坊 RPC 完全兼容，因此用户可以使用 MetaMask 和 Etherscan 等熟悉的工具与 Monad 进行交互。

Monad 通过引入以下四项重大创新实现了这些性能的优化：

* [MonadBFT 共识机制](/monad-architecture/consensus/monadbft)（pipelined HotStuff 共识机制，以及更多的研究改进）
* [Deferred Execution / 延迟执行](/monad-architecture/consensus/deferred-execution)（在达成共识和执行之间进行 pipelining 作业，以大幅增加执行预算）
* [Parallel Execution / 并行执行](/monad-architecture/execution/parallel-execution)
* [MonadDb 数据库](/monad-architecture/execution/monaddb)（高性能状态后端）

虽然 Monad 具有并行执行和流水线执行功能，但需要注意的是，Monad 中的区块是线性的，交易在每个区块中也是线性排序的。

### 交易格式

<table><thead><tr><th width="128">相关属性</th><th>属性描述</th></tr></thead><tbody><tr><td>地址空间</td><td>使用 ECDSA 匹配以太坊 20 字节地址</td></tr><tr><td>交易格式</td><td><p>符合 <a href="https://ethereum.org/zh/developers/docs/transactions/">以太坊</a> </p><p>符合 <a href="https://eips.ethereum.org/EIPS/eip-2718">EIP-2718</a>，使用 <a href="https://ethereum.org/zh/developers/docs/data-structures-and-encoding/rlp/">RLP</a> 编码。支持但不要求访问列表（<a href="https://eips.ethereum.org/EIPS/eip-2930">EIP-2930</a>）。</p></td></tr><tr><td>钱包兼容性</td><td>Monad 与 Metamask 等标准以太坊钱包兼容。唯一需要更改的是 RPC URL 和 ChainId。</td></tr></tbody></table>

### 智能合约

* Monad 支持 EVM 字节码，与以太坊字节码等效，支持所有 [操作码](https://www.evm.codes/?fork=shanghai)（截至上海升级）。

### 共识机制

<table><thead><tr><th width="134">相关属性</th><th>属性描述</th></tr></thead><tbody><tr><td>抗 51% 攻击</td><td>权益证明（PoS）</td></tr><tr><td>委托投票权</td><td>允许（协议原生）</td></tr><tr><td>共识机制和流水线机制</td><td><p><a href="/monad-architecture/consensus/monadbft">MonadBFT</a> 是一种基于领导人选举的共识算法，用于在部分同步条件下就交易排序和打包达成一致。广义上，它是 HotStuff 的衍生算法，并进行了额外的研究优化。</p><p></p><p>MonadBFT 是一种流水线式两阶段 BFT 算法，在一般情况下具有线性的 communication overhead。与大多数 BFT 算法一样，通信分阶段进行，在每个阶段，领导人向投票者发送签名信息，投票者再发回签名回执。流水线作业允许区块 <code>k</code> 的法定人数证书（QC）或超时证书（TC）包含区块 <code>k+1</code> 的提议，超时会进行二次消息传递。</p></td></tr><tr><td>区块时间</td><td>1秒</td></tr><tr><td>最终确定性</td><td>单时隙确定性，一旦2/3的验证者对整块提议投了"支持"票，区块即最终确定。</td></tr><tr><td>内存池</td><td>有<a href="/monad-architecture/consensus/shared-mempool">内存池</a>，交易采用纠删码，并使用 broadcast tree 进行通信，以提高效率。</td></tr><tr><td>抵制垃圾交易</td><td>用户为交易打包进区块（“<a href="/monad-architecture/consensus/carriage-cost-and-reserve-balance">传输成本</a>”）和交易执行（“执行成本”）付费。</td></tr><tr><td>共识参与者</td><td>直接共识参与者对区块提议进行投票，并担任领导人。要成为直接参与者，节点必须至少有 <code>MinStake</code> 质押，并且按投票权排在 <code>MaxConsensusNodes</code> 参与者的前列，这些参数在代码中设定。</td></tr><tr><td>交易哈希</td><td>为提高效率，区块提议<a href="/monad-architecture/consensus/shared-mempool">仅通过哈希值</a>来引用交易。如果一个节点没有参与交易，它将通过哈希向邻居节点请求交易。</td></tr><tr><td>延迟执行和燃料成本</td><td><p>在 Monad 中，共识和执行以流水线方式进行。节点在执行正式交易排序（<a href="/monad-architecture/consensus/deferred-execution">延迟执行</a>）之前，会就该排序达成共识，执行结果并不是达成共识的先决条件。</p><p></p><p>在区块链中，通常执行是达成共识的先决条件，而执行的时间预算只占区块时间的一小部分。将共识和执行流水线化后，Monad 就可以将全部区块时间用于共识和执行。</p><p></p><p>区块提议由交易哈希有序列表和 <code>D</code> 个区块前的状态 merkle 根组成，延迟参数 <code>D</code> 在代码中设定，预计最初 <code>D = 10</code>。</p><p></p><p>用户必须支付费用（"<a href="/monad-architecture/consensus/carriage-cost-and-reserve-balance">传输费用</a>"）才能将交易打包进区块。对于每个交易账户，节点保留两个余额：</p><p>• 储备余额，用于支付传输费用</p><p>• 执行余额，用于支付执行费用</p><p></p><p>当交易被纳入区块（共识）时，传输费用从储备余额中扣除；当交易被执行时，传输费用从执行余额中扣除（双重费用）；在 <code>D</code> 个区块的延迟期后，将剩余费用偿还给储备余额。</p><p></p><p>账户的储备余额实际是"待处理"交易的费用预算，它的存在是为了确保只有已支付交易费用的交易被打包进区块。</p><p></p><p>每个账户都有一个预留储备余额，该余额可通过与内置的智能合约交互进行更改，例如，对于计划发送大量交易的 EOA 账户而言。</p></td></tr><tr><td>状态确认</td><td><p>最终确定性发生在共识时间，在这一点上，交易的官方排序是神圣的。对于任何全节点来说，结果都是完全确定的，它们通常会在1秒内执行该新块的交易。</p><p></p><p>状态 merkle 根的 <code>D</code> 区块延迟仅用于状态根验证，例如允许节点验证自己没有计算错误。</p></td></tr></tbody></table>

### 执行机制

每个区块的执行阶段，在该区块达成共识后开始，并允许节点继续就后续区块达成共识。

#### **并行执行**

交易是按线性顺序排列的，执行作业是得出串行执行交易列表后的状态，最简单的方法就是一个接一个地执行交易。我们能做得更好吗？可以！

Monad 采用[并行执行](/monad-architecture/execution/parallel-execution)：

* 执行器是执行交易的虚拟机，Monad 可并行运行多个执行器。
* 执行器接收一笔交易并产生一个**结果**，结果是该笔交易的**输入**和**输出**列表，其中输入是执行过程 SLOAD 的（ContractAddress、Slot、Value）元组，输出是交易结果 SSTORE 的（ContractAddress、Slot、Value）元组。
* 结果最初在待处理状态下产生，然后按照交易的原始排序提交，当结果提交时，其输出会更新当前状态。在结果提交时，Monad 会检查其输入是否仍与当前状态匹配，如果不匹配，Monad 会重新安排交易。由于采用了并发控制，Monad 能确保生成与串行执行交易相同的结果。
* 当交易被重新安排时，许多或全部需要的输入都已被缓存，因此重新执行的成本通常相对较低。需要注意的是，在重新执行时，交易可能会生成与上次执行不同的输入集。

#### **MonadDb：高性能状态后端**

所有交易的活动状态都存储在 [MonadDb](/monad-architecture/execution/monaddb) 中，MonadDb 是由固态硬盘（SSD）组成的存储后端，专为存储 merkle trie 数据而优化。该数据更新是分批进行的，因此可以提高 merkle 根的更新效率。

MonadDb 实现了内存缓存，并使用 [asio](https://think-async.com/Asio/) 实现了高效的异步读写。节点至少配置 32GB 内存，以获得最佳性能。

### 与以太坊的比较：用户角度

| 相关属性                                                                                  | Ethereum                                                                   | Monad                                                                      |
| ------------------------------------------------------------------------------------- | -------------------------------------------------------------------------- | -------------------------------------------------------------------------- |
| 每秒交易量（合约调用和转账）                                                                        | \~10次                                                                      | \~10,000次                                                                  |
| 区块时间                                                                                  | 12秒                                                                        | 1秒                                                                         |
| 最终确定性                                                                                 | [2 epochs](https://hackmd.io/@prysmaticlabs/finality) (12-18分钟)            | 单时隙确定性 (1秒)                                                                |
| 字节码标准                                                                                 | EVM ([上海升级](https://www.evm.codes/?fork=shanghai))                         | EVM ([上海升级](https://www.evm.codes/?fork=shanghai))                         |
| RPC API                                                                               | [Ethereum RPC API](https://ethereum.org/en/developers/docs/apis/json-rpc/) | [Ethereum RPC API](https://ethereum.org/en/developers/docs/apis/json-rpc/) |
| 密码学                                                                                   | ECDSA                                                                      | ECDSA                                                                      |
| 账户                                                                                    | ECDSA 算法中，keccak-256 公钥的最后20个字节                                            | ECDSA 算法中，keccak-256公钥的最后20个字节                                             |
| 共识机制                                                                                  | Gasper (Casper-FFG finality gadget + LMD-GHOST fork-choice rule)           | MonadBFT (pipelined HotStuff 以及更多的研究优化)                                    |
| 内存池                                                                                   | 有                                                                          | 有                                                                          |
| 交易排序                                                                                  | <p>Leader's discretion </p><p>(实际：PBS)</p>                                 | <p>Leader's discretion </p><p>(默认方案：PGA)</p>                               |
| 抗51%攻击                                                                                | PoS                                                                        | PoS                                                                        |
| 投票权委托                                                                                 | 不允许，需通过 LSTs 实现                                                            | 允许                                                                         |
| [硬件要求](https://docs.monad.xyz/using-monad/running-a-node/hardware-requirements) (全节点) | <p>4核 CPU </p><p>16GB 内存 </p><p>1TB 固态硬盘 </p><p>25Mbit/s 带宽</p>            | <p>16核 CPU</p><p>32GB 内存</p><p>2TB 固态硬盘</p><p>100Mbit/s 带宽</p>             |


# Devnet 开发者申请

目前，Monad 正在内部开发网中运行，开发者可以按照以下步骤，申请加入内部开发网。

* 添加 Monad DevRel 工作人员微信：Box，微信号：box1234567890
* 加入全球开发者社区：[Monad Developer Discord](https://discord.com/invite/monaddev)
* 填写申请表：<https://tally.so/r/nWDeAR>


# 快速入门


# 部署合约


# 使用 Foundry 部署合约

[Foundry](https://book.getfoundry.sh/) 是一个快速、可复制的模块化工具包，适用于 Rust 语言编写的以太坊应用程序的开发。

### 先决条件

开始之前，需要安装以下工具：

* [Rust](https://doc.rust-lang.org/book/)
* [Cargo](https://doc.rust-lang.org/cargo/index.html)

### 安装 `foundryup`

Foundryup 是 Foundry 工具链的官方安装程序。

```bash
curl -L https://foundry.paradigm.xyz
```

按照屏幕上的说明操作，安装 Foundryup，接下来便可以在本地 CLI 中使用 `foundryup` 命令。

### 安装 `forge`、`cast`、`anvil` 和 `chisel` 文件 <a href="#id-2-installing-forge-cast-anvil-and-chisel-binaries" id="id-2-installing-forge-cast-anvil-and-chisel-binaries"></a>

```bash
foundryup
```

{% hint style="info" %}
**注意：**&#x5982;果你使用的是 Windows 系统，则需要安装并使用 Git BASH 或 WSL 终端，因为 Foundryup 目前不支持 Powershell 或命令提示符 (Cmd）。
{% endhint %}

### 创建 Foundry 示例项目

{% hint style="info" %}
**提示：**&#x4F60;可以使用 `foundry-monad` 模板来创建一个新项目。

[Foundry-Monad](https://github.com/monad-developers/foundry-monad) 是一个具有 Monad 配置的 Foundry 模板。使用该模板，开发者不必在 Foundry 中针对 Monad 网络进行初始配置。
{% endhint %}

运行以下命令，使用 `foundry-monad` 模板，创建一个新的 foundry 项目：

```bash
forge init --template monad-developers/foundry-monad [project_name]
```

或者，可以运行以下命令，创建默认的 foundry 项目：

```bash
forge init [project_name]
```

### 修改 Foundry 配置 <a href="#id-4-modify-foundry-configuration" id="id-4-modify-foundry-configuration"></a>

{% hint style="info" %}
**注意：**&#x76EE;前，开发网 RPC 和区块浏览器尚未公开。如公开，此页面将更新，感谢您的耐心等待。
{% endhint %}

{% hint style="info" %}
**注意：**&#x4E0A;述步骤&#x4E2D;**，**&#x5982;果你使用了 `foundry-monad` 模板，请跳过本步骤。
{% endhint %}

更新 `foundry.toml` 文件以添加 Monad 配置：

```bash
[profile.default]
src = "src"
out = "out"
libs = ["lib"]

# Monad Configuration
# TODO: Add RPC URL and Chain ID
eth-rpc-url="MONAD_RPC_URL"
chain_id = "MONAD_CHAIN_ID"

# TODO: Add Explorer URL and Chain ID
[etherscan]
monadDevnet = { key = "DUMMY_VALUE", url = "EXPLORER_URL", chain = MONAD_CHAIN_ID }
```

### 编写智能合约 <a href="#id-5-write-a-smart-contract" id="id-5-write-a-smart-contract"></a>

你可以在 `src` 文件夹下编写智能合约。此项目中已有一个 `Counter` 合约，位于 `src/Counter.sol`。

```solidity
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.13;

contract Counter {
    uint256 public number;

    function setNumber(uint256 newNumber) public {
        number = newNumber;
    }

    function increment() public {
        number++;
    }
}
```

### 编译智能合约 <a href="#id-6-compile-the-smart-contract" id="id-6-compile-the-smart-contract"></a>

```bash
forge compile
```

编译结果输出在新创建的 `out` 目录下，其中包括 Contract ABI 和 bytecode。

### 部署智能合约 <a href="#id-7-deploy-the-smart-contract" id="id-7-deploy-the-smart-contract"></a>

{% hint style="info" %}
**注意：**&#x5BF9;于合约部署，不建议使用与真实资产相关联的钱包地址及私钥，务必创建一个新钱包或使用仅用于开发的钱包地址。
{% endhint %}

#### 获取测试代币

{% hint style="info" %}
目前，开发网水龙头尚未公开。如公开，此页面将更新，感谢您的耐心等待。
{% endhint %}

部署智能合约需要测试网测试代币，可通过测试网水龙头领取。

#### 部署智能合约

{% tabs %}
{% tab title="使用 Keystore（推荐）" %}
Keystore 是 Foundry 项目中使用私钥的一种更安全的方式，因为 keystore 会加密私钥，且可以在任何需要私钥的命令中引用。

运行以下命令，创建新的钱包密钥库：

```bash
cast wallet import <keystore_name> --interactive
```

出现提示时，输入钱包私钥，并设置密码进行加密。

运行以下命令，部署智能合约：

```bash
forge create src/Counter.sol:Counter --account <keystore_name>
```

结果输出如下示例，表示合约成功部署：

```bash
Deployer: 0xB1aB62fdFC104512F594fCa0EF6ddd93FcEAF67b
Deployed to: 0x67329e4dc233512f06c16cF362EC3D44Cdc800e0
Transaction hash: 0xa0a40c299170c9077d321a93ec20c71e91b8aff54dd9fa33f08d6b61f8953ee0
```

{% endtab %}

{% tab title="直接使用钱包私钥" %}
运行以下命令，直接在终端中粘贴私钥，并部署智能合约。

```bash
forge create --private-key <your_private_key> src/Counter.sol:Counter
```

结果输出如下示例，表示合约成功部署：

```bash
Deployer: 0xB1aB62fdFC104512F594fCa0EF6ddd93FcEAF67b
Deployed to: 0x67329e4dc233512f06c16cF362EC3D44Cdc800e0
Transaction hash: 0xa0a40c299170c9077d321a93ec20c71e91b8aff54dd9fa33f08d6b61f8953ee0
```

{% endtab %}
{% endtabs %}

### 后续步骤

{% hint style="info" %}
**注意：**&#x76EE;前，开发网区块浏览器尚未公开。如公开，此页面将更新，感谢您的耐心等待。
{% endhint %}

了解如何在 Monad Explorer 上验证合约，请参阅 [验证 Foundry 合约](/getting-started/verify-contract/foundry)。


# 使用 Hardhat 部署合约

[Hardhat](https://hardhat.org/docs) 是一个综合开发环境，由不同组件组成，用于编写、编译、调试和部署智能合约和 dApps。

### 先决条件

开始之前，需要安装以下依赖项：

* [npm](https://docs.npmjs.com/about-npm) (建议`npm 7`以上版本) 或 [yarn](https://yarnpkg.com/getting-started)
* [Node.js](https://nodejs.org/en/download) v18.0.0 或更高版本

{% hint style="info" %}
如果你使用的是 Windows 系统，强烈建议安装并使用 [WSL 2](https://learn.microsoft.com/en-us/windows/wsl/about) 终端来完成以下步骤。
{% endhint %}

### 创建 Hardhat 示例项目

首先，创建一个新的文件夹目录，并导航到该目录：

```bash
mkdir my-hardhat-project && cd my-hardhat-project
```

在该目录中初始化一个新的 Hardhat 项目：

```bash
npx hardhat init
```

在出现 CLI 选择提示时，输入 “y/n“，选择你的首选项，或使用下方推荐的首选项。

```bash
✔ What do you want to do? · Create a TypeScript project (with Viem)
✔ Hardhat project root: · /path/to/my-hardhat-project
✔ Do you want to add a .gitignore? (Y/n) · y
✔ Do you want to install this sample project's dependencies with npm (hardhat @nomicfoundation/hardhat-toolbox-viem)? (Y/n) · y
```

### 设置配置变量 <a href="#id-2-setting-up-configuration-variables" id="id-2-setting-up-configuration-variables"></a>

Hardhat 项目可以将配置变量用于用户特定值，或用于不应包含在代码存储库中的数据。

{% hint style="info" %}
**注意：**&#x76EE;前，开发网 RPC 尚未公开。如公开，此页面将更新，感谢您的耐心等待。
{% endhint %}

运行以下命令，设置配置变量：

```bash
npx hardhat vars set <variable_name>
```

例如，运行以下命令，设置 `MONAD_RPC_URL` 变量：

```bash
npx hardhat vars set MONAD_EXPLORER_URL
```

{% hint style="info" %}
**注意**：在设置 `MONAD_EXPLORER_URL` 配置变量时，请勿包含 `/api` 部分。
{% endhint %}

然后在提示符中，为此变量输入自定义值：

```bash
Enter value: ********************************
```

同样，你还可以设置 `MONAD_CHAIN_ID` 变量。

{% hint style="danger" %}
**警告**：配置变量以纯文本形式存储在磁盘上。对于需要加密保存的敏感或重要数据，请避免使用此功能。你可以运行 `npx hardhat vars path` 查找存储的文件位置。
{% endhint %}

### 更新 `hardhat.config.ts` 文件以生效 `monadDevnet` 配置 <a href="#id-2-update-your-hardhatconfigts-file-to-include-the-monaddevnet-configuration" id="id-2-update-your-hardhatconfigts-file-to-include-the-monaddevnet-configuration"></a>

```bash
import type { HardhatUserConfig } from "hardhat/config";
import "@nomicfoundation/hardhat-toolbox-viem";
import { vars } from "hardhat/config";

const config: HardhatUserConfig = {
    solidity: "0.8.27",
    ...
    etherscan: {
        apiKey: `DUMMY_VALUE_FOR_BLOCKSCOUT`,
        customChains: [
            {
                network: "monadDevnet",
                chainId: Number(vars.get("MONAD_CHAIN_ID")),
                urls: {
                    browserURL: vars.get("MONAD_EXPLORER_URL"),
                    apiURL: `${vars.get("MONAD_EXPLORER_URL")}/api`,
                },
            },
            ...
        ],
    },
};

export default config;
```

### 编写智能合约 <a href="#id-4-write-a-smart-contract" id="id-4-write-a-smart-contract"></a>

你可以在 `contracts` 目录中创建新的合约，下方示例中，将创建名为`GMonad.sol`的智能合约：

```bash
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.17;

contract GMonad {
    function sayGmonad() public pure returns (string memory) {
        return "gmonad";
    }
}
```

### 编译智能合约 <a href="#id-5-compile-the-smart-contract" id="id-5-compile-the-smart-contract"></a>

```bash
npx hardhat compile
```

结果输出如下示例，表示合约成功编译：

```bash
Compiled 2 Solidity file successfully (evm target: paris).
```

{% hint style="info" %}
**注意**：如果你没有从 Hardhat 中删除默认的 `Lock.sol` 合约，则`GMonad.sol` 和`Lock.sol`均会被编译。
{% endhint %}

### 部署智能合约 <a href="#id-6-deploy-the-smart-contract" id="id-6-deploy-the-smart-contract"></a>

你可以使用声明式部署系统 [Hardhat Ignition](https://hardhat.org/ignition/docs/getting-started#overview) 来部署合约。

你可以使用示例项目中附带的 Ignition 模块部署 `GMonad` 合约。

#### 创建 Hardhat Ignition 模块 <a href="#creating-a-hardhat-ignition-module" id="creating-a-hardhat-ignition-module"></a>

运行以下命令，在 `ignition/modules` 目录中创建一个名为 `GMonad.ts` 的文件：

```solidity
import { buildModule } from "@nomicfoundation/hardhat-ignition/modules";

const GMonadModule = buildModule("GMonadModule", (m) => {
    const gmonad = m.contract("GMonad");

    return { gmonad };
});

module.exports = GMonadModule;
```

现在，你可以进行合约部署了。

#### 部署智能合约 <a href="#deploying-the-smart-contract" id="deploying-the-smart-contract"></a>

```bash
npx hardhat ignition deploy ./ignition/modules/GMonad.ts --network monadDevnet
```

当出现 `Confirm` 提示时，选择 `yes` ：

```bash
✔ Confirm deploy to network monadDevnet (<chain_id>)? … yes
```

结果输出如下示例，表示合约成功部署：

```bash
✔ Confirm deploy to network monadDevnet (<chain_id>)? … yes
Hardhat Ignition 🚀

Deploying [ GMonadModule ]

Batch #1
  Executed GMonadModule#GMonad

[ GMonadModule ] successfully deployed 🚀

Deployed Addresses

GMonadModule#GMonad - <contract_address>
```

### 后续步骤

了解如何在 Monad Explorer 上验证合约，请参阅 [验证 Hardhat 合约](/getting-started/verify-contract/hardhat)。


# 验证合约


# 验证 Foundry 合约

{% hint style="info" %}
**注意：**&#x76EE;前，开发网 RPC 和区块浏览器尚未公开。如公开，此页面将更新，感谢您的耐心等待。
{% endhint %}

{% tabs %}
{% tab title="Foundry Monad 模板（推荐）" %}
如果你使用 [`foundry-monad`](https://github.com/monad-developers/foundry-monad) 模板部署的合约，请运行以下命令：

```bash
forge verify-contract <contract_address> <contract_name>
```

你需要将 `contract_address` 和 `contract_name` 更换为你部署时使用的信息，例如：

```bash
forge verify-contract 0x195B9401D1BF64D4D4FFbEecD10aE8c41bEBA453 src/Counter.sol:Counter
```

结果输出如下示例，表示合约成功验证：

```bash
Start verifying contract `0x1355a4f7829161a4d27BDb8970D32b89ef89A1Be`

Submitting verification for [src/Counter.sol:Counter] 0x1355a4f7829161a4d27BDb8970D32b89ef89A1Be.
Submitted contract for verification:
    Response: `OK`
    GUID: `1355a4f7829161a4d27bdb8970d32b89ef89a1be67448d78`
```

{% endtab %}

{% tab title="默认 Foundry 项目 " %}

### 使用 Monad 配置更新 `foundry.toml` <a href="#id-1-update-foundrytoml-with-monad-configuration" id="id-1-update-foundrytoml-with-monad-configuration"></a>

{% hint style="info" %}
**提示**：如果你使用 [`foundry-monad`](https://github.com/monad-developers/foundry-monad) 模板部署的合约，则可以跳过本步骤。
{% endhint %}

```bash
[profile.default]
src = "src"
out = "out"
libs = ["lib"]

# Monad Configuration
# TODO: Add RPC URL and Chain ID
eth-rpc-url="MONAD_RPC_URL"
chain_id = "MONAD_CHAIN_ID"


# TODO: Add Explorer URL and Chain ID
[etherscan]
monadDevnet = { key = "DUMMY_VALUE", url = "EXPLORER_URL", chain = MONAD_CHAIN_ID }
```

### 验证合约 <a href="#id-2-verify-the-contract-using-the-command-below" id="id-2-verify-the-contract-using-the-command-below"></a>

运行以下命令，验证合约：

```bash
forge verify-contract <contract_address> <contract_name>
```

你需要将 `contract_address` 和 `contract_name` 更换为你部署时使用的信息，例如：

```bash
forge verify-contract 0x195B9401D1BF64D4D4FFbEecD10aE8c41bEBA453 src/Counter.sol:Counter
```

结果输出如下示例，表示合约成功验证：

```bash
Start verifying contract `0x1355a4f7829161a4d27BDb8970D32b89ef89A1Be`

Submitting verification for [src/Counter.sol:Counter] 0x1355a4f7829161a4d27BDb8970D32b89ef89A1Be.
Submitted contract for verification:
    Response: `OK`
    GUID: `1355a4f7829161a4d27bdb8970d32b89ef89a1be67448d78`
```

{% endtab %}
{% endtabs %}


# 验证 Hardhat 合约

当你的合约被部署到区块链实时网络中，下一步将是在区块浏览器上验证其源代码。

验证合约意味着将合约源代码以及用于编译代码的设置上传到存储库（通常由区块资源管理器维护）。这样，任何人都可以对合约进行编译，并将生成的字节码与部署在链上的字节码进行比较。对于 Monad 这样的开放区块链平台来说，这样做极为重要。

{% hint style="info" %}
**注意：**&#x76EE;前，开发网区块浏览器尚未公开。如公开，此页面将更新，感谢您的耐心等待。
{% endhint %}

本章节将阐述如何在 Monad 区块浏览器中执行Hardhat 合约验证。

### 设置配置变量 <a href="#id-2-setting-up-configuration-variables" id="id-2-setting-up-configuration-variables"></a>

Hardhat 项目可以将配置变量用于用户特定值，或用于不应包含在代码存储库中的数据。

运行以下命令，设置配置变量：

```bash
npx hardhat vars set <variable_name>
```

例如，运行以下命令，设置 `MONAD_RPC_URL` 变量：

```bash
npx hardhat vars set MONAD_EXPLORER_URL
```

{% hint style="info" %}
**注意**：在设置 `MONAD_EXPLORER_URL` 配置变量时，请勿包含 `/api` 部分。
{% endhint %}

接下来，在提示符中，为此变量输入自定义值：

```bash
Enter value: ********************************
```

同样，你还可以设置 `MONAD_CHAIN_ID` 变量。

{% hint style="danger" %}
**警告**：配置变量以纯文本形式存储在磁盘上。对于需要加密保存的敏感或重要数据，请避免使用此功能。你可以运行 `npx hardhat vars path` 查找存储的文件位置。
{% endhint %}

### 更新 `hardhat.config.ts` 文件以生效 `monadDevnet` 配置 <a href="#id-2-update-your-hardhatconfigts-file-to-include-the-monaddevnet-configuration" id="id-2-update-your-hardhatconfigts-file-to-include-the-monaddevnet-configuration"></a>

```bash
import type { HardhatUserConfig } from "hardhat/config";
import "@nomicfoundation/hardhat-toolbox-viem";
import { vars } from "hardhat/config";

const config: HardhatUserConfig = {
    solidity: "0.8.27",
    ...
    etherscan: {
        apiKey: `DUMMY_VALUE_FOR_BLOCKSCOUT`,
        customChains: [
            {
                network: "monadDevnet",
                chainId: Number(vars.get("MONAD_CHAIN_ID")),
                urls: {
                    browserURL: vars.get("MONAD_EXPLORER_URL"),
                    apiURL: `${vars.get("MONAD_EXPLORER_URL")}/api`,
                },
            },
            ...
        ],
    },
};

export default config;
```

{% hint style="info" %}
**注意**：目前 Monad 区块浏览器是基于 Blockscout 的，因此不需要 API 密钥。现阶段使用了虚拟占位符值`DUMMY_VALUE_FOR_BLOCKSCOUT`，以避免错误。
{% endhint %}

### 验证智能合约 <a href="#id-3-verify-the-smart-contract" id="id-3-verify-the-smart-contract"></a>

运行以下命令，验证智能合约：

```bash
npx hardhat verify <contract_address> --network monadDevnet
```

结果输出如下示例，表示合约成功验证：

```bash
Successfully submitted source code for contract
contracts/GMonad.sol:GMonad at <contract_address>
for verification on the block explorer. Waiting for verification result...

Successfully verified contract GMonad on the block explorer.
<block_explorer_url>/address/0x690BE9B15b84c6487965d1cbf3372A9FB07A6eE1#code
```

使用上方输出结果末尾的链接，可以在区块浏览器中查看经过验证的智能合约。

{% hint style="info" %}
**注意：**&#x76EE;前，开发网区块浏览器尚未公开。如公开，此页面将更新，感谢您的耐心等待。
{% endhint %}


# 开发指南


# EVM 资源


# EVM Behavior

### **EVM** B**ehavior 规范**

* [关于EVM的说明](https://github.com/CoinCulture/evm-tools/blob/master/analysis/guide.md)：EVM 的直接技术规范和一些 behavior 示例
* [EVM：从Solidity到字节码、内存和存储](https://www.youtube.com/watch?v=RxL_1AfV7N4): Peter Robinson 和 David Hyland-Wood 90 分钟的讲座
* [EVM图解](https://takenobu-hs.github.io/downloads/ethereum_evm_illustrated.pdf)：一套用于衡量开发者心智水平的出色图表
* [EVM深度挖掘：通往隐形超级编码器之路](https://noxx.substack.com/p/evm-deep-dives-the-path-to-shadowy)

### **操作码参考**

[evm.codes](https://www.evm.codes/)：操作码参考（包括 Gas 成本）和用于单步执行字节码的交互式沙盒

### **Solidity 存储布局**

EVM 允许智能合约将数据存储在 32 字节的单词（"存储槽"）中，但复杂数据结构（如列表或映射）则留给更高级的语言来处理，Solidity 有一种将变量分配到存储槽的特定方法，如下所述：

* [关于存储布局的官方文件](https://docs.soliditylang.org/en/latest/internals/layout_in_storage.html)
* [Solidity中的存储模式](https://programtheblockchain.com/posts/2018/03/09/understanding-ethereum-smart-contract-storage/)


# Solidity 资源

Monad 与 EVM 字节码完全兼容，支持[上海升级](https://www.evm.codes/?fork=shanghai)后的所有操作码和预编译，Monad 还保留了标准的以太坊 JSON-RPC 接口。

因此，以太坊主网的大部分开发资源都适用于 Monad。

本章节为在以太坊上构建去中心化应用程序的开发者提供了一套最基础的资源。

由于 [Solidity](https://docs.soliditylang.org/en/v0.8.25/) 是以太坊智能合约最常用的语言，因此本章节的资源主要集中在 Solidity，包括部分 [Vyper](/guides/evm-resources/other-languages/vyper) 和[Huff](/guides/evm-resources/other-languages/huff) 的资源。请注意，由于智能合约是可组合的，最初用一种语言编写的合约仍可以调用另一种语言的合约。

### **集成开发环境（IDEs）**

* [Remix](https://remix.ethereum.org/#lang=en\&optimize=false\&runs=200\&evmVersion=null)：一款交互式 Solidity 集成开发环境，它是编码和编译 Solidity 智能合约最简单快捷的方式，无需安装其他工具。
* [VSCode](https://code.visualstudio.com/) + [Solidity extension](https://marketplace.visualstudio.com/items?itemName=NomicFoundation.hardhat-solidity)

### **Solidity 入门教程**

* [CryptoZombies](https://cryptozombies.io/en/course)：在 EVM 上构建去中心化应用程序的最佳学习教程。它为任何人提供了资源和课程，适用于从零代码编写经验，到希望探索区块链深度开发的所有人员。
* [Solidity by Example](https://solidity-by-example.org/)：通过简单的开发示例，循序渐进地介绍相关概念，最适合已有其他语言开发基础经验的人员阅读。
* [Blockchain Basics course by Cyfrin Updraft](https://updraft.cyfrin.io/courses/blockchain-basics)：区块链基础知识课程，内容包括区块链、DeFi 和智能合约的基础知识。
* [Solidity Smart Contract Development by Cyfrin Updraft](https://updraft.cyfrin.io/courses/solidity)：智能合约开发课程，开发人员可以通过此课程学习构建项目，以获得项目开发实践经验。
* [Ethereum Developer Degree by LearnWeb3](https://learnweb3.io/degrees/ethereum-developer-degree/)：适用于没有 Web3 开发背景的开发者构架 Web3 应用程序，课程提供了 Web3 开发领域关键协议、框架和概念的案例学习。

### **Solidity 中级教程**

* [Solidity Language](https://docs.soliditylang.org/en/v0.8.21/introduction-to-smart-contracts.html)：围绕 EVM 环境，对智能合约和区块链基础知识进行了详细阐述。除了 Solidity Language 文档外，它还涵盖了在 EVM 上编译代码、部署合约的基础知识，以及提供了在 EVM 上部署合约的相关基本组件。
* [Solidity Patterns](https://github.com/fravoll/solidity-patterns)：提供了代码模板库及其用法说明。
* [Uniswap V2](https://github.com/Uniswap/v2-core)：一个专业而易于理解的智能合约，它提供了一个正在运行中的 Solidity dApp 的全局视图，该合约的演示在[此处](https://ethereum.org/en/developers/tutorials/uniswap-v2-annotated-code/)。
* [Cookbook.dev](https://www.cookbook.dev/search?q=cookbook\&categories=Libraries)：提供了一套交互式合约模板示例，具有实时编译、一键部署和人工智能聊天集成功能，可帮助解决代码问题。
* [OpenZeppelin](https://www.openzeppelin.com/contracts)：为 ERC20、ERC712 和 ERC1155 等常见的以太坊代币部署提供了可定制的合约模板。请注意，它们没有进行 Gas 优化。
* [Rareskills Blog](https://www.rareskills.io/category/solidity)：一系列关于 Solidity 中各种概念的精彩深入的文章合集。
* [Foundry Fundamentals course by Cyfrin Updraft](https://updraft.cyfrin.io/courses/foundry)：一门全面的 Web3 开发课程，旨在向开发者介绍 Foundry，这是构建、部署和测试智能合约的行业标准框架。
* [Smart Contract Programmer YT channel](https://www.youtube.com/@smartcontractprogrammer)：一系列关于各种 Solidity 概念的视频合集，如 ABI 编码、EVM 内存等。

### **Solidity 高级教程**

* [Solmate](https://github.com/transmissions11/solmate) 和 [Solady](https://github.com/Vectorized/solady/tree/main) 资源库：利用 Solidity 或 Yul 提供 Gas 优化合约。
* [Yul](https://docs.soliditylang.org/en/latest/yul.html)：Solidity 的一种中间语言，一般可视为 EVM 的内联汇编。它并不完全是纯粹的汇编语言，它提供控制流结构并抽象出堆栈的内部工作，同时仍向开发人员提供原始内存后台。Yul 主要面向需要接触 EVM 原始内存后台的开发人员，以构建高性能、Gas 优化的 EVM 合约代码。
* [Huff](https://docs.huff.sh/get-started/overview/)：最接近于 EVM 的汇编语言，与 Yul 不同，Huff 不提供控制流结构，也不抽象程序堆栈的内部工作。只有对性能最敏感的应用程序才会使用 Huff，但它是学习 EVM 诠释最底层指令的绝佳教学工具。
* [Advanced Foundry course by Cyfrin Updraft](https://updraft.cyfrin.io/courses/advanced-foundry)：介绍 Foundry，以及如何开发 DeFi 协议和稳定币，如何开发 DAO，高级智能合约开发，高级智能合约测试、模糊测试以及手动验证。
* [Smart Contract Security course by Cyfrin Updraft](https://updraft.cyfrin.io/courses/security)：审计和编写安全协议所需的一切知识。
* [Assembly and Formal Verification course by Cyfrin Updraft](https://updraft.cyfrin.io/courses/formal-verification)：介绍 Assembly，以及使用 Huff 和 Yul 编写智能合约，介绍以太坊虚拟机 OPCode、Formal 验证测试、智能合约不变性测试以及 Halmos、Certora、Kontrol 等工具的使用。
* [Smart Contract DevOps course by Cyfrin Updraft](https://updraft.cyfrin.io/courses/wallets)：介绍使用钱包时的访问控制最佳实践，合约部署后的安全保障、智能合约和 Web3 DevOps 以及实时协议的维护和监控。
* [Secureum YT Channel](https://www.youtube.com/@SecureumVideos/videos)：一系列关于 Solidity 的视频合集，介绍从 Solidity 基础学习到模糊测试和 Solidity 审计等高级概念。

### &#x20;Solidity 游戏化教程

* [Ethernaut](https://ethernaut.openzeppelin.com/)：通过解谜学习 Solidity
* [Damn Vulnerable DeFi](https://www.damnvulnerabledefi.xyz/)：一系列智能合约的漏洞挑战游戏，由易受攻击的合约组成，开发者可以尝试寻找漏洞并破解合约。漏洞挑战是练习和获得 Solidity 开发技能的绝佳方法。

### **最佳实践/模式**

* [DeFi 开发者路线图](https://github.com/OffcierCia/DeFi-Developer-Road-Map)
* [Gas 优化技能书](https://www.rareskills.io/post/gas-optimization)

### **测试**

* [Echidna](https://github.com/crytic/echidna)：模糊测试
* [Slither](https://github.com/crytic/slither)：用于漏洞检测的静态分析
* [solidity-coverage](https://github.com/sc-forks/solidity-coverage/tree/master)：测试 Solidity 代码覆盖率

### **智能合约存档**

* [Smart contract sanctuary](https://github.com/tintinweb/smart-contract-sanctuary)：在以太坊上验证智能合约
* [EVM 函数签名数据库](https://www.4byte.directory/)


# 其他编程语言


# Vyper 语言

[Vyper](https://www.quicknode.com/guides/ethereum-development/smart-contracts/how-to-write-an-ethereum-smart-contract-using-vyper) 是一种流行的 EVM 编程语言，逻辑上类似于 Solidity，语法上类似于 Python。

[Vyper文档](https://docs.vyperlang.org/en/stable/index.html) 包括 Vyper 语言的安装、语法、编码示例和编译。

我们鼓励希望获得类似 Python 体验的典型 EVM 开发人员使用 Vyper 作为编程语言，并使用采用 Python 语言构建的 [ApeWorx](https://docs.apeworx.io/ape/stable/userguides/quickstart.html) 作为测试和部署框架，ApeWorx 还允许在分析测试结果时使用典型的 Python 库，如 Pandas。

Vyper 和 ApeWorx 可与 [Jupyter](https://jupyter.org/) 配合使用，后者提供了一个使用网络浏览器的交互式环境。 有关使用 Vyper 和 Jupyter 为 EVM 开发智能合约的快速指南，请点击[此处](https://medium.com/deepyr/interacting-with-ethereum-using-web3-py-and-jupyter-notebooks-e4207afa0085)。

### **Vyper相关资源**

* [Vyper示例](https://vyper-by-example.org/)
* [Snekmate](https://github.com/pcaversaccio/snekmate)：基于 Vyper 语言的智能合约 Gas 优化模块库
* [Curve contracts](https://github.com/curvefi/curve-contract)：Vyper 语言最突出的使用实例


# Yul 语言

[Yul](https://docs.soliditylang.org/en/latest/yul.html) 是 Solidity 的一种中间语言，通常被认为是 EVM 的内联汇编。它不完全是纯粹的汇编语言，Yul 提供了控制流结构并抽象出堆栈的内部工作，同时仍向开发人员公开原始内存后端。Yul 面向需要接触 EVM 原始内存后端的开发人员，以编写高性能、 具备 gas 优化的 EVM 代码。


# Huff 语言

[Huff](https://docs.huff.sh/) 最接近于 EVM 汇编语言，与 Yul 不同，Huff 不提供控制流结构，也不抽象程序堆栈的内部工作。只有对性能最敏感的应用程序才会使用 Huff，但它是学习 EVM 诠释最底层指令的绝佳教学工具。

* [Huff资源库](https://docs.huff.sh/resources/overview/)：提供关于 Huff 语言的资源


# 链上调试

### **交易反馈与追踪**

* [Tenderly](https://dashboard.tenderly.co/explorer)
* [EthTx Transaction Decoder](https://ethtx.info/)
* <https://openchain.xyz/>
* [Bloxy](https://bloxy.info/)
* <https://github.com/naddison36/tx2uml>：生成 UML 图表的操作系统工具
* <https://github.com/apeworx/evm-trace>： 追踪工具

### **合约反编译**

* <https://oko.palkeo.com/>：[Panoramix](https://github.com/palkeo/panoramix) 反编译器的托管版本

### **本地节点**

开发人员通常会发现，运行一个修改了参数的以太坊单节点，对交互测试很有帮助：

* [Anvil](https://github.com/foundry-rs/foundry/tree/master/crates/anvil) 是一个打包在 Foundry 工具包中的本地以太坊节点。
* [Hardhat](https://hardhat.org/hardhat-network/docs/overview) 是一个打包在 Hardhat 工具包中的本地以太坊节点。

如何安装相应工具包，并获得本地节点，下一章节将详细介绍。

### **工具包**

开发人员通常会发现，在一个功能齐全的开发框架内构建自己的程序能提高开发效率。开发框架可以组织外部依赖关系（即软件包管理），组织单元测试和集成测试，定义部署程序（针对本地节点、测试网和主网），记录Gas成本等。

以下是两种最常用的 Solidity 开发工具包：

* [Foundry](https://book.getfoundry.sh/) 是一个用于开发和测试的 Solidity 开发框架，Foundry 可以管理依赖关系、编译项目、运行测试、部署，并允许用户通过命令行或 Solidity 脚本与链进行交互，Foundry 用户通常使用 Solidity 语言编写智能合约和测试。
* [Hardhat](https://hardhat.org/docs) 是一个 Solidity 开发框架，搭配有 JavaScript 测试框架，它具有与 Foundry 类似的功能，在 Foundry 出现之前是 EVM 开发人员的主要工具链。

### **与以太坊 RPC API 交互**

去中心化应用程序的前端通常使用 JavaScript 或 Python 向 RPC 节点提交读取或写入查询，这些代码通常被称为 "客户端"，因为开发人员可以将区块链大致等同于后台服务器。

以下资源库提供了向 RPC 节点提交查询或交易的标准方法：

* Python:
  * [web3.py](https://web3py.readthedocs.io/en/stable/)
* Javascript:
  * [web3.js](https://web3js.readthedocs.io/)
  * [ethers.js](https://docs.ethers.org/) 开发了 [Web3.js](https://web3js.readthedocs.io/en/v1.10.0/getting-started.html) 和 [Web3.py](https://web3py.readthedocs.io/en/stable/quickstart.html)，它们分别是 Java Script 和 Python 资源库，这些开发旨在使开发人员能够更直观地与区块链进行交互。

这里是一个创建去中心化应用程序前端的快速示例：[create-eth-app](https://github.com/WalletConnect/create-eth-app)。

### **测试网**

Monad 测试网将在未来几个月内提供给开发者使用，由于字节码和 RPC 与 EVM 兼容，计划在 Monad 上部署的开发者可以初步使用[以太坊测试网](https://ethereum.org/en/developers/docs/networks/)。

### 更多资源

以下子页面添加了额外资源：

* [EVM behavior](/guides/evm-resources/evm-behavior)
* [更多 Solidity 资源](/guides/evm-resources/solidity-resources)
* [链上调试](/guides/evm-resources/debugging-on-chain)
* [其他编程语言](/guides/evm-resources/other-languages)
  * [Vyper](/guides/evm-resources/other-languages/vyper)
  * [Huff](/guides/evm-resources/other-languages/huff)

除了 "[建议资源](/guides/evm-resources) "中提到的资源外，这里还有一些其他资源：

### **教程**

* [Ethernaut](https://ethernaut.openzeppelin.com/)：通过解谜学习 Solidity

### **最佳实践/模式**

* [DeFi开发人员路线图](https://github.com/OffcierCia/DeFi-Developer-Road-Map)
* [Gas优化技能书](https://www.rareskills.io/post/gas-optimization)

### **测试**

* [Echidna](https://github.com/crytic/echidna)：模糊测试
* [Slither](https://github.com/crytic/slither)：用于漏洞检测的静态分析
* [solidity-coverage](https://github.com/sc-forks/solidity-coverage/tree/master)：测试 Solidity 代码覆盖率

### **智能合约存档**

*


# 使用 Scaffold-Eth-Monad 构建 dApp

Scaffold-Eth-Monad 是一个拥有Monad 配置功能的 [Scaffold-ETH 2](https://docs.scaffoldeth.io/) 分支。

Scaffold-Eth-Monad 旨在使开发者更容易在 Monad 上创建和部署智能合约，并提供了与合约交互的用户界面。

### 先决条件

开始之前，需要安装以下工具：

* [Node.js](https://nodejs.org/en/download) (v18.18 或更高版本)
* [Yarn](https://classic.yarnpkg.com/en/docs/install#mac-stable) (v1 或 v2+ 版本)&#x20;
* [Git](https://git-scm.com/downloads)

### 获取测试代币

{% hint style="info" %}
**注意：**&#x76EE;前，测试网水龙头尚未公开。如公开，此页面将更新，感谢您的耐心等待。
{% endhint %}

你需要在 Monad 测试网获得测试代币，才能部署智能合约。未来，你可以在此处从水龙头获取测试代币。

### 初始设置

1. 克隆 Scaffold-Eth-Monad 代码存储库

```bash
git clone https://github.com/monad-developers/scaffold-eth-monad.git
```

2. 打开项目目录并安装依赖项

```bash
cd scaffold-eth-monad && yarn install
```

3. 为 Hardhat 配置 `.env` 文件

在 `packages/hardhat` 文件夹中复制 `.env.example`，将其命名为 `.env` ，并设置以下自定义值。

* `DEPLOYER_PRIVATE_KEY`：部署智能合约所使用的钱包私钥。
* `MONAD_RPC_URL`：可以使用公共 RPC 或从 Monad 支持的 RPC 服务商获取私有 RPC 。

```bash
DEPLOYER_PRIVATE_KEY=
MONAD_RPC_URL=
MONAD_CHAIN_ID=
MONAD_EXPLORER_URL=
```

{% hint style="info" %}
**注意：**&#x76EE;前，开发网 RPC 尚未公开。如公开，此页面将更新，感谢您的耐心等待。
{% endhint %}

4. 在 Monad 上部署智能合约

完成 `.env` 文件配置后，接下来，你可以在终端中运行以下命令：

```bash
yarn deploy --network monadDevnet
```

此命令将 `YourContract.sol` 部署到 Monad 测试网，该合约位于 `packages/hardhat/contracts` 中，可根据需要进行修改。

`yarn deploy` 命令调用 `packages/hardhat/deploy` 中的部署脚本，将合约部署到网络，你可以自定义部署脚本。

5. 为 Next.js 应用程序设置 `.env` 文件 (可选)

在 `packages/nextjs` 文件夹中复制 `.env.example`，将其命名为 `.env` ，并设置以下自定义值。

```
NEXT_PUBLIC_WALLET_CONNECT_PROJECT_ID=
```

6. 在另外的终端上，启动 NextJS 应用程序

```bash
yarn start
```

在浏览器中访问应用：**`http://localhost:3000`**

你应该会看到如下所示的 dApp 用户界面：

<figure><img src="https://3402452340-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FPaHQrSOuX4vToXCmyjn9%2Fuploads%2FusezG6BUf3DgYXCagskA%2Ffront_page-c63141018affa8c64241d01f97ada82f.png?alt=media&amp;token=a451daac-13f7-44a6-bb07-7464646f5740" alt=""><figcaption></figcaption></figure>

你可以在 `Debug Contracts` 页面与智能合约交互，还可以在 `packages/nextjs/scaffold.config.ts` 中调整应用程序配置。

### 下一步 <a href="#whats-next" id="whats-next"></a>

* 在 `packages/hardhat/contracts` 编辑 `YourContract.sol` 智能合约。
* 在 `packages/nextjs/app/page.tsx` 编辑前端主页，有关路由和 `pages/layouts` 配置，请参阅 [Next.js 文档](https://nextjs.org/docs)。
* 在 `packages/hardhat/deploy` 编辑合约部署脚本。
* 在 `packages/hardhat/test` 编辑智能合约测试，可以使用 `yarn hardhat：test` 运行测试。


# Monad 架构


# 相关概念


# Asynchronous I/O

Asynchronous I/O 是一种输入/输出处理方式，它允许中央处理器在通信进行时继续并发执行。

硬盘和网络比中央处理器慢几个数量级，与启动输入/输出操作并等待结果相比，中央处理器可以在需要数据时立即启动输入/输出操作，并继续执行其他不依赖于输入/输出操作结果的指令。

一些粗略的比较，仅供参考：

| 硬件            | 延迟时间      | 传输速度              |
| ------------- | --------- | ----------------- |
| 中央处理器（三级缓存）   | 10 纳秒     | 400 GB/s          |
| 内存            | 100 纳秒    | 100 GB/s          |
| 硬盘（NVMe 固态硬盘） | 400 纳秒    | 380 MB/s          |
| 网络            | 50-200 毫秒 | 1 Gb/s (125 MB/s) |

(由 fio 报告的 2KB 随机读取的实际硬盘统计数据 - \~190k IOPS）

幸运的是，固态硬盘驱动器可以并发执行事务，因此 CPU 可以同时启动多个请求继续执行，然后同时接收多个事务的结果。

某些数据库（如：lmdb/mdbx）使用内存映射存储来读写磁盘，遗憾的是，内存映射存储是由内核（mmap）实现的，而不是异步的，因此在等待事务完成时会阻碍执行。

有关 Asynchronous I/O 的更多信息，请点击[此处](https://en.wikipedia.org/wiki/Asynchronous_I/O)。


# Pipelining

Pipelining 技术是一种实现并行化的技术，它将事务拆分成一系列可并行处理的较小事务。

Pipelining 技术用于计算机处理器，致力于提高以相同时钟频率顺序执行一系列指令的吞吐量(处理器中还使用了其他技术来提高吞吐量）。有关指令级并行（ILP）的更多信息，请点击[此处](https://en.wikipedia.org/wiki/Instruction_pipelining)。

解释 Pipelining 技术的一个简单案例：

<figure><img src="https://3402452340-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FPaHQrSOuX4vToXCmyjn9%2Fuploads%2FKYb18Igx3akjuUxH9M7h%2F001_.png?alt=media&amp;token=0672f963-f31f-4aa0-a9d8-614419031df8" alt=""><figcaption><p>Pipelining 洗衣作业的日常，上: 普通洗衣作业; 下: pipelined 洗衣作业<br>资料来源: <a href="https://www.cs.fsu.edu/~hawkes/cda3101lects/chap6/index.html?$$$F6.1.html$$$">Prof. Lois Hawkes, FSU</a></p></figcaption></figure>

当洗四件衣服时，“普通洗衣作业”的策略是在洗第二件衣服之前，完成第一件衣服的洗涤、烘干、折叠和储存。“pipelined 洗衣作业”的策略是当第一件衣服洗涤完成进入烘干机时，开始洗涤第二件衣服，通过同时利用多个资源来更有效地完成工作。


# 共识机制


# MonadBFT 共识机制

流水线式两阶段 HotStuff 共识机制（Pipelined two-phase HotStuff）

MonadBFT 是一种高性能共识机制，用于在拜占庭参与者存在的情况下，在部分同步条件下就交易排序达成一致。它是 [HotStuff](https://arxiv.org/pdf/1803.05069) 的衍生机制，在 [Jolteon](https://arxiv.org/pdf/2106.10362.pdf)/[DiemBFT](https://developers.diem.com/papers/diem-consensus-state-machine-replication-in-the-diem-blockchain/2021-08-17.pdf)/[Fast-HotStuff](https://arxiv.org/abs/2010.11454) 中采用了优化方案，即在领导人超时的情况下，利用二次通信复杂度将三轮共识减少到两轮。

MonadBFT 是一种流水线式两阶段 BFT 算法，具有乐观响应性，在普通情况下通信开销为线性，在超时情况下通信开销为二次方。与大多数 BFT 算法一样，通信分阶段进行，在每个阶段，领导人向投票者发送签名信息，投票者再向下一位领导人发送签名回执，流水线作业允许区块 `k` 的法定人数证书（QC）或超时证书（TC）捎带区块 `k+1` 的提议。

### **基本情况**

| 相关属性     | 属性描述       |
| -------- | ---------- |
| 抗51%攻击机制 | 权益证明 （PoS） |
| 区块时间     | 1 秒        |
| 最终确定性    | 单时隙确定性     |
| 投票权委托    | 允许         |

### **内存池**

请参阅 [共享内存池](/monad-architecture/consensus/shared-mempool)

### **共识协议**

MonadBFT 是一种流水线式共识机制，分轮次进行。以下内容提供了对协议的高级直观理解。

按照惯例，假设有 `n=3f+1` 个节点，其中 `f` 是拜占庭节点的最大数量， `2f+1`（即 2/3）个节点是非拜占庭节点。在下面的讨论中，我们将所有节点视为具有相同投票权，实际上，所有阈值都可以用投票权而不是节点数来表示。

* 在每一轮中，领导人都会发出一个新的区块，以及上一轮的 QC 或 TC（稍后将详细介绍）。
* 每个验证者都会审查该区块是否符合协议，如果通过，则将签名的”同意"选票发送给下一轮领导人，然后该领导人通过汇总（通过阈值签名）来自 `2f+1` 个验证者的 "同意"选票，得出 QC（法定人数证书）。请注意，这种情况下的消息是线性的：领导人向验证者发送区块，验证者直接向下一轮领导人发送选票。
* 另外，如果验证者在预先指定的时间内没有收到有效数据块，它就会向所有对等设备广播一个签名的超时消息，该超时消息还包括验证者观察到的最高 QC。如果任何验证者积累了 `2f+1` 个超时消息，它就会将这些消息（同样通过阈值签名）组合成一个 TC（超时证书），然后直接发送给下一轮领导人。
* 每个验证者在收到第 `k+1` 轮的 QC 时（在第 `k+2` 轮领导人的消息中），最终确定第 `k` 轮提出的区块。具体来说：
* 第 `k` 轮的领导人 ***Alice*** 会向所有人发送一个新的区块（同时发送第 `k-1` 轮的QC或TC。我们忽略这一点，因为它并不重要）。
* 如果有 `2f+1` 个验证者通过向 ***Bob***（第 `k+1` 轮的领导人）发送选票来对该区块投同意票，那么 `k+1` 中的区块将包含第 `k` 轮的 QC。然而，验证者 ***Valerie*** 此时看到第 `k` 轮的 QC 并不足以让她知道第 `k` 轮的区块已被纳入。原因例如：***Bob*** 可能是恶意的，他只向 ***Valerie*** 发送了该区块，***Valerie*** 所能做的就是对区块 `k+1` 进行投票，并将她的投票发送给 ***Charlie***（第 `k+2` 轮的领导人）。
* 如果有 `2f+1` 个验证者对区块 `k+1` 投同意票，那么 ***Charlie*** 就会发布 `k+1` 轮的 QC 以及 `k+2` 轮的区块提议。一旦 ***Valerie*** 收到这个区块，她就知道第 `k` 轮的区块（即 ***Alice*** 的区块）已经最终确定。
* 假设 ***Bob*** 在第 `k+1` 轮恶意发送了一个无效的区块提议，或者向少于 `2f+1` 个验证者发送了该提议，那么至少有 `f+1` 个验证者会超时，然后触发其他非拜占庭验证者超时，这样至少有一个验证者产生 `k+1` 轮的 TC。然后，***Charlie*** 将在他的提议中公布第 `k+1` 轮的 TC（他必须这样做才能提出提议，因为第 `k+1` 轮没有 QC）。
* 我们把这种提交流程称为 2-chain 提交规则，因为只要验证者看到 2 个相邻的被证明块 `B` 和 `B'`，就可以提交 `B` 及其所有祖先块。

参考资料：

* Maofan Yin, Dahlia Malkhi, Michael K. Reiter, Guy Golan Gueta, and Ittai Abraham. [HotStuff: BFT Consensus in the Lens of Blockchain](https://arxiv.org/abs/1803.05069), 2018.
* Mohammad M. Jalalzai, Jianyu Niu, Chen Feng, Fangyu Gai. [Fast-HotStuff: A Fast and Resilient HotStuff Protocol](https://arxiv.org/abs/2010.11454), 2020.
* Rati Gelashvili, Lefteris Kokoris-Kogias, Alberto Sonnino, Alexander Spiegelman, and Zhuolun Xiang. [Jolteon and ditto: Network-adaptive efficient consensus with asynchronous fallback](https://arxiv.org/pdf/2106.10362.pdf). arXiv preprint arXiv:2106.10362, 2021.
* The Diem Team. [DiemBFT v4: State machine replication in the diem blockchain](https://developers.diem.com/papers/diem-consensus-state-machine-replication-in-the-diem-blockchain/2021-08-17.pdf). 2021.

### **BLS多重签名**

证书（QC 和 TC）可以在 secp256k1 curve 上以 ECDSA 签名向量的形式简单实现，这些证书是明确的，易于构建和验证。但是证书的大小与签名者的数量成线性关系，除了投票信息外，几乎每条共识消息都包含证书，这限制了区块链扩容。

BLS12-381 curve 上基于配对的 BLS 签名有助于解决扩容问题，签名可以逐步聚合成一个签名，验证单个有效的聚合签名就能证明与公钥相关的投票权都已在消息上签名。

BLS 签名比 ECDSA 签名慢得多，出于性能考虑，MonadBFT 采用了一种混合签名方案：BLS 签名只用于可聚合的消息类型（投票和超时），消息的完整性和真实性仍由 ECDSA 签名提供。


# 延迟执行

Monad 区块链的一个新颖之处在于执行与共识分离，采用流水线式共识执行分级机制。

简而言之，共识是 Monad 节点就交易的官方排序达成一致的过程，而执行则是实际执行这些交易并更新状态的过程。

在 Monad 共识中，节点就交易的官方排序达成一致，但领导人节点或验证节点都无需执行这些交易。

也就是说，领导人在不知道结果状态根的情况下提出排序，验证节点投票区块的有效性，可以不知道区块中的所有交易执行是否可以回滚。

怎么会这样？为什么 Monad 会这样做？

这个答案是 Monad 设计的基石，它使 Monad 能够大幅提升交易速度，让单体分片区块链扩展到数百万用户。

### **交错执行和共识效率低下问题**

在以太坊中，执行是达成共识的先决条件。因此当节点就一个区块达成共识时，它们先要就以下两点达成共识：(1) 该区块中的交易列表；(2) 归集执行该交易列表后所有状态的 merkle 根。因此领导人在共享提议之前必须执行提议区块中的所有交易，而验证节点在响应投票之前也必须执行这些交易。

在这种模式下，执行的时间预算极为有限，因为它必须执行两次，并留出足够的时间进行多轮跨全局通信以达成共识。另外由于执行过程会限制共识达成，因此必须极其保守地选择 Gas 限制，以确保即使在最极端的情况下，所有节点上的计算都能在预算范围内完成。

### **确定的排序意味着状态确定性**

这里有一个显而易见却又至关重要的见解：给定一个官方的交易排序，正确的状态就完全确定了，需要执行才能揭示真相，但真相已经确定。

Monad 利用了这一见解，取消了节点在达成共识前执行交易的要求。节点协议仅是关于官方排序，每个节点独立执行区块 `N` 中的交易，同时开始就区块 `N+1` 达成共识。

这样就可以获得与整个区块时间相对应的 Gas 预算，因为执行过程只需紧跟共识即可。此外，这种方法对精确计算时间变化的容忍度更高，普遍而言，执行只需紧跟共识即可。

### **延迟merkle根仍能确保状态机复制**

人们可能对上述观点提出的主要反对意见是：

* 如果其中一个节点是恶意的，没有执行共识中指定的确定性交易，会发生什么情况？(例如，它忽略了某些交易，或者只是将状态变量设置为自己选择的任意值）。
* 如果其中一个节点在执行过程中出错，会发生什么情况？

为了解决以上问题，在 Monad 中，区块提议包含有一个延迟了 `D` 个区块的 merkle 根，其中 `D` 是一个全局参数（目前预计为 10）。因为这种延迟的 merkle 根：

1. 在网络就区块 `N` 达成共识（2/3 的多数票）后，意味着网络已同意区块 `N-D` 的官方结果处于遵循 merkle 根 `M` 的状态，此时轻客户端可以检索全节点，以获得区块 `N-D` 的状态变量值的 merkle 证明。
2. 在区块 `N-D` 执行中出现错误的任何节点将从区块 `N` 开始脱离共识层，这将触发该类节点回滚到区块 `N-D-1` 的结束状态，重新执行区块 `N-D` 中的交易（希望能实现 merkle 根匹配），接着重新执行 `N-D+1` 、`N-D+2` 等区块中的交易。

以太坊的方法是使用共识，以非常严格的方式执行状态机复制：在节点达成共识后，我们知道绝大多数认同官方排序和由该排序产生的状态结果。然而这种严格的方法带来了巨大的代价——极其有限的吞吐量，Monad 在此处稍微放宽了，取得了很好的效果。

### **最终确定性**

在 MonadBFT 中，最终确定性采用单时隙确定性（时间为 1 秒），对于使用全节点的人来说，执行结果一般会滞后不到 1 秒。让我们来解读一下这一点：

**Monad 中的最终确定性采用单时隙确定性（时间为 1 秒）**，如果你提交了一笔交易，你将在一个区块后看到该交易的官方排序（在所有其他交易中）。除非网络中的绝大多数人采取恶意行为，否则不存在回滚重新排序的可能性，这使得 Monad 的最终确定性速度远快于以太坊（2 个 epochs，时间为 12.8 分钟）。

**交易的执行结果**（成功还是失败？交易后的余额是多少？）通常会**在全节点上延迟不到1秒的最终确定性**，任何需要快速了解交易结果的人（例如，想要了解交易状态的高频交易员）都可以运行全节点。Monad 会最大限度地减少全节点的运行成本，更多信息请参阅[硬件要求](broken://pages/GeYkVy1UG4YtfzYC4b8v)。

任何人如果想在不运行全节点的情况下安全地查询交易结果，可以运行一个轻客户端，同时用 merkle 证明查询全节点的余额，在这种情况下，查询将滞后于 merkle 根（延迟`D=10` 个区块，即 10 秒）。请注意，目前大多数用户都是使用软件/浏览器钱包或通过区块浏览器查看区块链状态，此类查询方式均不涉及轻客户端。

有些读者可能会错误地将 merkle 根（延迟了 `D=10` 个区块）与最终确定性混为一谈，误以为最终确定性就是 10 个区块的时间。事实并非如此，官方交易排序是在 1 个区块后确定的，在此之后，如果没有绝大多数的拜占庭行为，就不会有任何更改。


# 共享内存池

### **内存池**

待处理的用户交易存储在每个验证者的内存池中，直到它们被包含在最终确认的区块中。待处理交易通过纠删码与其他验证者内存池共享，然后通过广播树进行通信，以提高效率。

### **交易哈希**

MonadBFT 是就任意有效负载达成一致的有效方法，然而区块广播仍然是一个重大瓶颈。例如，一个包含 10,000 笔交易和 500 个字节交易的区块将达到 5 MB，这种大小的区块将对验证者节点的带宽提出过高要求。

为了缓解这一问题，区块提议只通过哈希值引用交易，这大大节省了哈希，因为哈希值是 32 字节。因此所有验证者内存池在对提议进行投票以及提交区块时，都需要在自己的内存池中保存交易。提交给验证者内存池的交易会通过纠删码与其他验证者内存池共享，然后通过广播树进行通信，以提高效率。


# 传输成本和储备余额

### **方法与动机**

延迟执行的功能非常强大，因为它允许执行和共识并行作业，从而大大增加了执行的时间预算。

一个显而易见的反对意见是：既然共识节点没有最新的状态视图，那么如何防止它们误将已消耗掉所有 Gas的账户的交易打包进区块，这将会产生 DoS 攻击。

为了防止这种情况发生，Monad 为区块链上的交易传输设置了成本（即"传输成本"）。每个账户将保留一个储备余额，在交易达成共识时更新，并根据储备余额收取传输成本。

### **传输成本**

在 Monad 中，通过区块网络进行交易需要支付费用（"传输成本"），这是一项独立于执行成本的费用。

传输成本是防止垃圾交易所必需存在的，费用极低，但反映了利用网络资源的成本。

交易有可能被纳入共识（并被收取传输成本），但相对于指定的 Gas 限额，假设执行预算不足，在这种情况下，交易在执行时会失败，但仍会收取失败交易的 Gas 费用。请注意，这与以太坊并无不同：当账户中 ETH 不足时提交交易，将耗尽ETH并失败。为防止执行交易时出现失败，用户有必要在交易前为账户充值足够多的 Gas。

### **储备余额**

对于每个账户，节点保持同步两个余额：

* **储备余额**，用于支付传输成本
* **执行余额**，用于支付交易执行费用

当交易被纳入区块（达成共识）时，传输成本从储备余额中扣除；当交易执行时，费用从执行余额中扣除（双重费用）；在 `D` 个区块延迟（10 秒）后，对储备余额中的传输成本进行递减操作。

储备余额实际上是"待确认"交易的费用预算，它的存在是为了确保区块中只打包了已支付交易费用的交易。你可以认为储备余额是实时递减的（即在达成共识时），虽然节点对全局状态的洞察是滞后的，但储备余额总是反映最新的交易费用支出。

### **预留储备余额**

预留储备余额是每个账户已设定的参数，默认值预计为传输成本的较大倍数（200 倍），这样用户就可以顺利提交大量待确认交易。

如果用户计划从同一 EOA 账户发送大量待确认交易，则可通过与嵌入式智能合约交互来更改预留储备余额。预留储备余额的更改被视为执行，即只有在延迟期过后才会反映在储备余额中。


# 执行机制


# 并行执行

Monad 以并行方式执行交易，乍看起来，这似乎有着与以太坊不同的执行原语。实际并非如此，Monad 区块与以太坊区块相同：是一组线性有序的交易集，区块中执行交易的结果在 Monad 和以太坊中是相同的。

### **乐观执行**

在基础层面上，Monad 使用乐观执行，这意味着 Monad 会在区块中较早的交易完成之前开始执行当前交易。有时（但并不总是），这会导致执行错误。

思考两笔交易（在区块中按此顺序排列）：

1. `交易1`：读取并更新账户 A 的余额（例如，接收来自账户 B 的转账）。
2. `交易2`：仍会读取和更新账户 A 的余额（例如，向账户 C 转账）。

如果这些交易是并行执行的，而 `交易2` 在 `交易1` 完成之前就开始执行，那么它为账户 A 读取的余额可能与按顺序执行时的余额不同， 这可能导致执行错误。

乐观执行解决这个问题的方法是跟踪 `交易2` 执行时的输入，并将其与 `交易1` 的输出进行比较。如果两者不同，我们就检测到 `交易2` 在执行时使用了错误的数据，此时需要使用正确的数据再次执行。

在 Monad 并行执行交易的同时，每个交易的更新状态都是按顺序"合并”的，以便检查是否有上述问题出现。

于此相关的计算机科学研究有[乐观并发控制](https://en.wikipedia.org/wiki/Optimistic_concurrency_control)（OCC）和[软件事务内存](https://en.wikipedia.org/wiki/Software_transactional_memory)（STM）。

### **乐观执行的影响**

在乐观执行的朴素方式中，直到区块中的早期交易完成后，我们才会发现交易需要再次执行。此时，所有早期交易的状态更新都已合并，因此该交易不可能再次因乐观执行而失败。

在执行交易的过程中，有些步骤并不依赖于状态。例如，重复签名是一项昂贵的计算，再次执行交易时，这项工作无需重复。

此外，由于合并失败而再次执行交易时，访问的账户和存储往往不会改变，因为状态仍缓存在内存中，因此这项昂贵的工作不需要重复操作。

### **执行调度**

乐观执行的朴素方式会在处理器有可用资源时尝试开始执行下一笔交易，区块中可能存在相互依赖的长"链“交易，并行执行这些交易会导致大量故障。

提前确定交易之间的依赖关系，可以让 Monad 只在前序交易完成后才调度交易执行，从而避免资源浪费。Monad 采用静态代码分析技术，可以尝试做出这样的预测。在良好状态下，Monad 可以提前预测出许多依赖关系；在极端情况下，Monad 会退回到朴素执行方式。

### **未来工作**

探索更多避免重复执行交易的方法，并实现它们。


# MonadDb 数据库

MonadDb 是用于存储区块链状态的自定义数据库。

大多数以太坊客户端使用的键值数据库都是以 B-Tree（例如[LMDB](https://www.symas.com/lmdb)）或 LSM-Tree（例如 [LevelDB](https://github.com/google/leveldb) 和 [RocksDB](https://rocksdb.org/)）数据结构实现的，然而以太坊却使用 [Merkle Patricia Trie](https://ethereum.org/zh/developers/docs/data-structures-and-encoding/patricia-merkle-trie/)（MPT）数据结构来存储状态。这是一种次优解决方案，一种数据结构被嵌入到另一种不同类型的数据结构中。为了避免这种情况发生，MonadDb 在磁盘和内存中都原生实现了 Patricia Trie 数据结构。

Monad 可以并行执行多笔交易，当一笔交易需要从磁盘读取状态时，系统不应停滞等待前序操作完成，而应启动读取，然后在此期间同步处理另一笔交易。关键在于此操作要求数据库支持[异步输入/输出](/monad-architecture/concepts/asynchronous-i-o)（async i/o），而上述提到的键值数据库缺乏相应的异步输入/输出支持（尽管在这方面有一些改进）。MonadDb 充分利用了最新内核支持异步输入/输出（在 Linux 上是 [io\_uring](https://unixism.net/loti/index.html)），这就避免了为了异步执行交易而产生大量内核线程来处理待处理的输入/输出请求。

MonadDb 还对输入/输出进行了其他一些优化，例如绕过文件系统，因为文件系统会增加昂贵的开销。


# Monad 的交易生命周期

### 交易提交 <a href="#block-22af2c5f82f043228d62ccbe7d8ad026" id="block-22af2c5f82f043228d62ccbe7d8ad026"></a>

交易的生命周期开始于用户发起一个已签名的交易并将其提交给 RPC 节点。

交易通常由应用程序前端准备，然后提交给用户钱包进行签名。大多数钱包都会调用 `eth_estimateGas` RPC来预设该笔交易的 Gas **限制**，不过用户也可以在钱包中修改该限额，用户通常还会被要求选择交易的 Gas **价格**，即每单位 Gas 的本机代币数量。

用户在其钱包中批准签名后，签名交易将通过 `eth_sendTransaction` 或 `eth_sendRawTransaction` API 调用提交到 RPC 节点。

值得注意的是，在 Monad 中，Gas 限额是传输成本 Gas 和执行成本 Gas 之和，传输 Gas 是一个常数。

### 内存池广播 <a href="#block-657dc51bf3b540e3ba2aaad028492ebf" id="block-657dc51bf3b540e3ba2aaad028492ebf"></a>

RPC 节点会将待处理交易广播给参与共识的其他 Monad 节点，待处理交易集也叫"内存池"。有关内存池作业的更多详情，请参阅[内存池](/monad-architecture/consensus/shared-mempool)章节。

出于防止垃圾交易的原因，只有当[储备金余额](/monad-architecture/consensus/carriage-cost-and-reserve-balance)中有足够的 Gas 时，节点才会将该笔交易添加到其内存池中。

### 区块打包 <a href="#block-4f4825341e524560986b525f079e828d" id="block-4f4825341e524560986b525f079e828d"></a>

MonadBFT 采用轮值领导人机制来生成区块，每一轮的领导人都会从待处理交易集中选出一个区块。在将一笔交易打包进区块后，领导人会对储备金余额中的传输成本进行递减操作。

如 [MonadBFT](/monad-architecture/consensus/monadbft) 所述，区块会在网络中广播，该区块的法定人数证书（QC）会在随后一轮共识中广播（即由下一任领导人发出）；接收到 QC 证书后，投票节点会相互发送投票；当一个节点检测到 2/3 的投票权投同意票时，它就会最终确认该区块。

一旦区块被最终确认，该笔交易就在区块链交易历史上正式"发生"了。由于其排序已确定，因此其真值（即成功还是失败，以及执行后的结果）也就确定了。

### 本地执行 <a href="#block-fbd2d4f7131a40519c852bc20a1b451c" id="block-fbd2d4f7131a40519c852bc20a1b451c"></a>

节点一旦确认一个区块，就会开始执行该区块中的交易。出于效率考虑，交易以并行方式优化执行，由于结果总是按原始排序提交，因此就像串行执行交易一样。

### 结果查询 <a href="#block-0432fa8485ec4af5a93af1d14b51beef" id="block-0432fa8485ec4af5a93af1d14b51beef"></a>

用户可以在任何 RPC 节点上调用 `eth_getTransactionByHash` 或 `eth_getTransactionReceipt` 来查询交易结果，RPC 节点上的本地执行完成后，将立即返回结果。


# 硬件要求

运行 Monad 全节点的硬件要求如下：

* 中央处理器: 16 core CPU
* 内存: 32 GB RAM
* 硬盘: 2 TB NVMe SSD
* 带宽: 100 Mb/s


# 其他详细信息

### 账户 <a href="#block-0e0c4d2be856453c98d9e071c1482c1a" id="block-0e0c4d2be856453c98d9e071c1482c1a"></a>

Monad 中的账户与[以太坊账户](https://ethereum.org/en/developers/docs/accounts/)相同，使用与以太坊相同的地址空间（ ECDSA 的 20 字节地址）。与以太坊账户一样，Monad 也分外部账户（EOA）和合约账户。

### 交易 <a href="#block-7af06f7875d2419bb62672151ba60eb6" id="block-7af06f7875d2419bb62672151ba60eb6"></a>

Monad 中的交易格式与[以太坊一致](https://ethereum.org/en/developers/docs/transactions/)，即符合 [EIP-2718](https://eips.ethereum.org/EIPS/eip-2718) 标准，交易使用 [RLP](https://ethereum.org/en/developers/docs/data-structures-and-encoding/rlp/) 编码。

支持可选访问列表 ([EIP-2930](https://eips.ethereum.org/EIPS/eip-2930))，但不是必需的。

### 区块和交易的线性 <a href="#block-1bc773c53b0a4b128696ae7c98a9d171" id="block-1bc773c53b0a4b128696ae7c98a9d171"></a>

区块仍然是线性的，区块内的交易也是线性的。并行执行仅用于提高效率，绝不会影响一系列交易的真实结果或结束状态。

### 燃料（Gas） <a href="#block-07e2a88f989443bea7514ba3d26cf84f" id="block-07e2a88f989443bea7514ba3d26cf84f"></a>

[Gas](https://ethereum.org/en/developers/docs/gas/)（或许更明确地命名为 "本币的计算单位"）的设置与以太坊相同，每个操作码都需要花费一定量的 Gas。在 Monad 中，每个操作码的 Gas 成本与以太坊相同，但未来可能会更新。

当用户提交交易时，会在交易中加入 Gas 限额（该函数调用在交易失败前可消耗的最大 Gas 数量）和 Gas 价格（每单位 Gas 成本，以本币为单位）。

默认 Monad 客户端中的领导人使用优先 Gas 竞拍（PGA）提交交易，即按照 Gas 报价从高到低排序交易，未来可能会有其他的交易排序机制。排序的选择与下游发生的一切无关，有效的排序选择并不包含在 Monad 协议中。


# 参考资料


# RPC 概述

Monad 是一个等效于 EVM 的第 1 层区块链。对于以前为以太坊开发的开发者来说，开始在 Monad 上构建应该很熟悉。

Monad 支持用于与区块链交互的 [JSON-RPC](https://www.jsonrpc.org/specification) 接口。有关支持方法的参考，请参阅 [RPC-API](https://docs.monad.xyz/docs/openrpc/json-rpc-api)。

Monad 正在积极开发中，目前在内部开发网中运行。有关公共 RPC 终端节点的详细信息将在未来几个月内披露。


# RPC 故障代码

Monad 支持用于与区块链交互的 [JSON-RPC](https://www.jsonrpc.org/specification) 接口。Monad JSON-RPC 旨在等效于以太坊 JSON-RPC，但由于以太坊客户端之间缺乏标准化，一些故障代码可能略有偏差，以下仅供参考。

### Monad 故障代码参考

<table><thead><tr><th width="148">故障代码</th><th width="239">消息提示</th><th>故障解释</th></tr></thead><tbody><tr><td><strong>-32601</strong></td><td>Parse error</td><td>无法解析 JSON-RPC 请求</td></tr><tr><td><strong>-32601</strong></td><td>Invalid request</td><td>请求无效，例如请求超出大小限制</td></tr><tr><td><strong>-32601</strong></td><td>Method not found</td><td>不符合 JSON-RPC 规范</td></tr><tr><td><strong>-32601</strong></td><td>Method not supported</td><td>符合 JSON-RPC 规范，但 Monad 尚未支持</td></tr><tr><td><strong>-32602</strong></td><td>Invalid block range</td><td>eth_getLogs 过滤器范围限制为 1000 个区块</td></tr><tr><td><strong>-32602</strong></td><td>Invalid params</td><td>请求包含与特定方法关联的错误参数</td></tr><tr><td><strong>-32603</strong></td><td>Internal error</td><td>由于内部错误而无法完成的请求</td></tr><tr><td><strong>-32603</strong></td><td>Execution reverted</td><td>eth_call 和 eth_estimateGas 模拟还原交易</td></tr><tr><td><strong>-32603</strong></td><td>Transaction decoding error</td><td>请求包含无法解码的原始交易</td></tr></tbody></table>


# Monad 官方链接

**Monad Twitter：**<https://twitter.com/monad_xyz>

**Monad** **Discord：**<https://discord.gg/monad>

**Monad 官网：**<https://monad.xyz/>

**Monad 文档：**<https://docs.monad.xyz/>

**Monad 博客：**<https://monadlabs.substack.com/>

**Monad 招聘：**<https://boards.greenhouse.io/monad>


# 相关链接


# DocsZH 相关链接

* Twitter：<https://x.com/Scaling_News>
* DocsZH | 致力于前沿区块链技术文档中文本地化
  * 网站：[https://www.docszh.com](https://www.docszh.com/)
* Scaling News | 致力于探索 scaling & parallel & modular 生态
  * 网站：[https://scaling.news](https://scaling.news/)
  * GuideHub：<https://guide.scaling.news>
* Monad News | 致力于探索 Monad 生态
  * 网站：[https://monad.news](https://monad.news/)


