使用 Motsu 测试 Arbitrum Stylus 智能合约

OpenZeppelin 发布于 2025-06-27 阅读 1908

本文介绍了 Motsu,一个专为 Arbitrum Stylus 智能合约设计的 Rust 原生测试框架。

目录

介绍

随着以太坊扩容解决方案的成熟,Arbitrum Stylus 作为一个引人入胜的创新脱颖而出,它允许开发者使用 Rust 编写智能合约。 这提供了显著的性能改进,并将 Rust 强大的类型系统和内存安全保证带到了区块链世界。

但正如任何有经验的智能合约开发者都知道的那样,彻底的测试是不可协商的。 这就是 Motsu 的用武之地——一个专门为 Stylus 合约设计的测试框架,它既让 Rust 开发者感到熟悉,又在概念上类似于 Solidity 开发者熟知的 Hardhat 和 Foundry 等工具。

在本教程中,我们将探讨如何使用 Motsu 有效地测试你的 Stylus 合约。 如果你来自 Solidity 背景,并具有 Foundry 或 Hardhat 等工具的经验,你将发现许多相似之处,这些相似之处将帮助你快速上手。

你可以在我们的 GitHub 存储库中找到包含所有示例的完整工作项目:https://github.com/0xNeshi/motsu-tutorial

使 Motsu 与众不同的原因?

Motsu 解决了测试 Stylus 智能合约中的一个核心挑战:模拟区块链环境。 正如 Hardhat 提供了一个 JavaScript 环境来测试 Solidity 合约,Foundry 提供了一个 Solidity 原生的测试体验一样,Motsu 通过模拟 vm affordances,为 Stylus 合约提供了一个纯 Rust 测试体验。 与 Hardhat 或 Foundry 启动轻量级区块链节点来执行测试不同,Motsu 采用了一种不同的方法,通过在 Wasm 级别直接拦截和模拟 Stylus host 函数。 这实现了快速、独立的测试,而无需完整的区块链运行时,使其成为纯粹在 Rust 中进行 Stylus 合约单元测试的理想选择。

“Motsu”(持つ,日语,意为“持有”)这个名字巧妙地引用了“手持触控笔 (holding a stylus in our hand)”——这是一个恰当的比喻,它代表着一种让你控制 Stylus 合约测试的工具。

设置你的项目

在深入研究 Motsu 之前,请确保你的项目已正确配置。 以下是本项目所需的依赖项:

Arbitrum Stylus OpenZeppelin Motsu 代码段 1让我们在 src/lib.rs 中添加合约:Arbitrum Stylus OpenZeppelin Motsu 代码段 2

编写你的首个测试

让我们从一个简单的例子开始。 如果你以前用 Rust 编写过测试,那么结构会看起来很熟悉,但有一个关键区别:我们不使用 #[test],而是使用 #[motsu::test]。

这是我们的 Vault 合约的一个基本测试:Arbitrum Stylus OpenZeppelin Motsu 代码段 3让我们分解一下这里发生的事情:

  1. #[motsu::test] attribute 转换你的测试函数以提供对 VM 环境的访问
  2. 测试函数的参数被自动注入:
    • contract: Contract<Vault> 创建你的合约的一个实例
    • alice: Address 创建一个测试地址

这在概念上类似于 Foundry 的 setUp() 函数准备你的测试环境,但以一种更符合 Rust 习惯的方式通过函数参数来实现。

账户和地址

Motsu 提供了两种类型来表示区块链账户:

  1. Address - 一个简单的以太坊地址(如以太坊的 address 类型)
  2. Account - 一个带有用于签名操作的关联私钥的地址

你可以将它们用作测试函数中的参数:Arbitrum Stylus OpenZeppelin Motsu 代码段 4请注意,你需要将 alloy-signer@0.11.1 添加到 Cargo.toml 中的 [dev-dependencies] 才能执行签名操作。

除非你需要在测试中访问私钥或底层 signer,否则我们建议使用 Address,因为它更轻量级。

带标签的确定性账户

在调试测试时,拥有命名一致的账户可以帮助跟踪问题。 Motsu 提供了一个 FromTag trait,它包含在其 prelude 中,用于从字符串标识符创建确定性地址,并且这个 trait 用于注入测试参数:Arbitrum Stylus OpenZeppelin Motsu 代码段 5

与合约交互

Motsu 测试的核心围绕 Contract<T> 类型展开,它表示智能合约的一个已部署实例。

基本交互

要在你的合约上调用函数:Arbitrum Stylus OpenZeppelin Motsu 代码段 6sender() 方法设置交易的调用者,类似于 Hardhat 的 connect() 或 Foundry 的 vm.prank()。

通过调用传递 Value

假设我们向 Vault 添加了一个 payable deposit 函数,它接受底层的 gas 代币:Arbitrum Stylus OpenZeppelin Motsu 代码段 7对于 payable 函数,你可以使用 sender_and_value() 发送 ETH。Arbitrum Stylus OpenZeppelin Motsu 代码段 8

测试事件

智能合约通常会发出你想要在测试中验证的事件。

首先,让我们更新 deposit 函数,以便在成功存款时发出一个事件:Arbitrum Stylus OpenZeppelin Motsu 代码段 9Motsu 提供了一种优雅的方式来检查发出的事件:Arbitrum Stylus OpenZeppelin Motsu 代码段 10如果事件断言失败,Motsu 会提供格式良好的 panic 消息,并将账户/合约地址替换为适当的标签(如果使用标签来实例化它们)。Arbitrum Stylus OpenZeppelin Motsu 代码段 11

处理 Revert

测试失败场景与测试成功操作同样重要。 让我们向 Vault 添加一个 decrease_balance 函数,该函数在余额下溢时会 revert 并显示错误:Arbitrum Stylus OpenZeppelin Motsu 代码段 12Motsu 提供了几种正确处理 revert 的方法:Arbitrum Stylus OpenZeppelin Motsu 代码段 13用于处理 revert 的关键方法有:

  • motsu_unwrap() - 解封装结果或使用错误详细信息 panic
  • motsu_unwrap_err() - 期望一个错误并返回它,如果成功则 panic
  • motsu_expect() - 类似于 unwrap(),但带有自定义消息
  • motsu_expect_err() - 类似于 unwrap_err(),但带有自定义消息
  • motsu_res() - 如果出现错误,则 revert 交易,但返回 Result

这些方法确保在交易失败时正确地 revert 合约状态,类似于真实区块链交易的行为方式。 如果上述任何方法 panic,panic 消息将被漂亮地打印出来以提高清晰度,并且地址将被替换为适当的标签(如果这是它们被实例化的方式)。Arbitrum Stylus OpenZeppelin Motsu 代码段 14

测试合约间交互

Motsu 的一个强大功能是能够测试多个合约之间的交互。 这对于复杂的 DeFi 应用程序或任何具有多个交互组件的系统至关重要。

让我们设置一个简单的代理合约实现:Arbitrum Stylus OpenZeppelin Motsu 代码段 15Motsu 处理内部合约到合约的连接,允许我们轻松测试上述代理:Arbitrum Stylus OpenZeppelin Motsu 代码段 16

操纵 VM 环境

有时你需要模拟特定的区块链条件。 Motsu 允许你修改某些环境变量,如链 ID,这使你可以模拟链分叉。Arbitrum Stylus OpenZeppelin Motsu 代码段 17

实际示例:测试 ERC-20 代币

让我们将所有内容放在一起,测试一个 ERC-20 代币实现。

我们将继承 openzeppelin-stylus 库的 ERC-20 实现,因此让我们将必要的依赖项添加到我们的 Cargo.toml:Arbitrum Stylus OpenZeppelin Motsu 代码段 18我们现在可以打开 src/lib.rs 并实现我们的 ERC-20 代币以及一个全面的转移测试:Arbitrum Stylus OpenZeppelin Motsu 代码段 19

有效测试的技巧

基于我们探索的模式,以下是使用 Motsu 进行测试的一些最佳实践:

  1. 使用带标签的确定性账户 以方便调试
  2. 使用适当的 motsu_* 函数测试成功和失败情况
  3. 验证事件 以确保你的合约正确地传达状态变化
  4. 测试多个合约之间的复杂交互
  5. 检查涉及价值转移的操作之前和之后的余额
  6. 适当地使用账户类型 - Address 用于简单情况,Account 用于需要签名的情况
  7. 记住为没有 #[entrypoint] 的合约实现 TopLevelStorage

结论

Motsu 为 Arbitrum Stylus 合约提供了一个强大的、Rust 原生的测试环境。 虽然在概念上类似于 Hardhat 和 Foundry 等工具,但它利用 Rust 的类型系统来提供更集成的测试体验。

对于来自 Solidity 的开发者来说,思维模式是相当可以转移的 - 你仍然在处理合约、地址和交易。 但是 Motsu 的设计利用了 Rust 的特性,使测试更加简洁且更易于推理。

在你继续使用 Stylus 进行开发时,请继续探索 Motsu 的功能。 投入编写彻底测试的时间将为你的智能合约的可靠性和安全性带来回报。

祝你测试愉快!

  • 原文链接: blog.openzeppelin.com/te...
  • 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~

相关文章

0 条评论