本文介绍了 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 解决了测试 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 之前,请确保你的项目已正确配置。 以下是本项目所需的依赖项:
让我们在 src/lib.rs 中添加合约:
让我们从一个简单的例子开始。 如果你以前用 Rust 编写过测试,那么结构会看起来很熟悉,但有一个关键区别:我们不使用 #[test],而是使用 #[motsu::test]。
这是我们的 Vault 合约的一个基本测试:让我们分解一下这里发生的事情:
这在概念上类似于 Foundry 的 setUp() 函数准备你的测试环境,但以一种更符合 Rust 习惯的方式通过函数参数来实现。
Motsu 提供了两种类型来表示区块链账户:
你可以将它们用作测试函数中的参数:请注意,你需要将 alloy-signer@0.11.1 添加到 Cargo.toml 中的 [dev-dependencies] 才能执行签名操作。
除非你需要在测试中访问私钥或底层 signer,否则我们建议使用 Address,因为它更轻量级。
在调试测试时,拥有命名一致的账户可以帮助跟踪问题。 Motsu 提供了一个 FromTag trait,它包含在其 prelude 中,用于从字符串标识符创建确定性地址,并且这个 trait 用于注入测试参数:
Motsu 测试的核心围绕 Contract<T> 类型展开,它表示智能合约的一个已部署实例。
要在你的合约上调用函数:sender() 方法设置交易的调用者,类似于 Hardhat 的 connect() 或 Foundry 的 vm.prank()。
假设我们向 Vault 添加了一个 payable deposit 函数,它接受底层的 gas 代币:对于 payable 函数,你可以使用 sender_and_value() 发送 ETH。
智能合约通常会发出你想要在测试中验证的事件。
首先,让我们更新 deposit 函数,以便在成功存款时发出一个事件:Motsu 提供了一种优雅的方式来检查发出的事件:
如果事件断言失败,Motsu 会提供格式良好的 panic 消息,并将账户/合约地址替换为适当的标签(如果使用标签来实例化它们)。
测试失败场景与测试成功操作同样重要。 让我们向 Vault 添加一个 decrease_balance 函数,该函数在余额下溢时会 revert 并显示错误:Motsu 提供了几种正确处理 revert 的方法:
用于处理 revert 的关键方法有:
这些方法确保在交易失败时正确地 revert 合约状态,类似于真实区块链交易的行为方式。 如果上述任何方法 panic,panic 消息将被漂亮地打印出来以提高清晰度,并且地址将被替换为适当的标签(如果这是它们被实例化的方式)。
Motsu 的一个强大功能是能够测试多个合约之间的交互。 这对于复杂的 DeFi 应用程序或任何具有多个交互组件的系统至关重要。
让我们设置一个简单的代理合约实现:Motsu 处理内部合约到合约的连接,允许我们轻松测试上述代理:
有时你需要模拟特定的区块链条件。 Motsu 允许你修改某些环境变量,如链 ID,这使你可以模拟链分叉。
让我们将所有内容放在一起,测试一个 ERC-20 代币实现。
我们将继承 openzeppelin-stylus 库的 ERC-20 实现,因此让我们将必要的依赖项添加到我们的 Cargo.toml:我们现在可以打开 src/lib.rs 并实现我们的 ERC-20 代币以及一个全面的转移测试:
基于我们探索的模式,以下是使用 Motsu 进行测试的一些最佳实践:
Motsu 为 Arbitrum Stylus 合约提供了一个强大的、Rust 原生的测试环境。 虽然在概念上类似于 Hardhat 和 Foundry 等工具,但它利用 Rust 的类型系统来提供更集成的测试体验。
对于来自 Solidity 的开发者来说,思维模式是相当可以转移的 - 你仍然在处理合约、地址和交易。 但是 Motsu 的设计利用了 Rust 的特性,使测试更加简洁且更易于推理。
在你继续使用 Stylus 进行开发时,请继续探索 Motsu 的功能。 投入编写彻底测试的时间将为你的智能合约的可靠性和安全性带来回报。
祝你测试愉快!
- 原文链接: blog.openzeppelin.com/te...
- 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!