23 个版本
0.4.20 | 2024 年 4 月 26 日 |
---|---|
0.4.19 | 2024 年 2 月 26 日 |
0.4.13 | 2023 年 12 月 1 日 |
0.4.12 | 2023 年 11 月 15 日 |
0.3.2 | 2023 年 9 月 18 日 |
#1173 在 神奇豆子
573 每月下载量
83KB
865 行
扩展 EVM 工具生态系统。
概述
仲裁器 是一个闪电般的以太坊沙箱,让开发者可以编排事件驱动的模拟。该框架允许对(Rust)以太坊虚拟机(EVM)进行细粒度控制,以提供有状态的以太坊智能合约交互和创建可以合并为复杂场景或自动化的行为。我们在 ethers-rs
中间件之上使用 revm,它也用于如 reth
以及 foundry
这样的 ETH 客户端。这使我们拥有了速度、可配置性和模块化,感觉就像是一个轻量级的自定义以太坊节点。
仲裁器的主要用途是探测智能合约的机制安全性。如果您对此感兴趣,请参阅漏洞语料库。
仲裁器工作区有五个组件
arbiter
:一个二进制文件,提供用于分叉和绑定合约的命令行界面。arbiter-core
:一个库,包含仲裁器框架的核心逻辑,包括前面讨论的ArbiterMiddleware
和我们的沙箱Environment。
arbiter-engine
:一个库,提供构建模拟、代理和行为的高级抽象。arbiter-macros
:一个库组件,包含用于简化使用仲裁器开发的宏。arbiter-bindings
:一个包含用于测试和开发的实用智能合约绑定的lib crate。
书籍
在这里,您可以找到Arbiter 文档。这是一个mdbook,它提供了对如何使用Arbiter框架的整体理解的更高层次的理解。
动机
Arbiter被构建来允许您在具有状态的沙盒中与智能合约一起工作,并设计可以与合约一起使用的代理。这为您提供了许多功能。例如,智能合约工程师必须测试他们的合约针对各种潜在的敌对环境和参数,而不是依赖于静态无状态测试。
在去中心化金融(DeFi)中,各种复杂去中心化应用程序可以使用上述测试。然而,隐含的金融策略也包含了许多代理和参数化。金融工程师可能希望测试他们的策略针对数千种市场状况、合约设置、冲击以及自主或随机的AI代理,同时确保他们的方法不会被字节码级别的漏洞利用。同样,同一个工程师可能还希望开发搜索代理、求解代理或其他可以在区块链上运行的自主代理。
使用Arbiter框架
要使用Arbiter,您必须在您的机器上安装Rust。您可以通过此处的说明安装Rust。获取cargo-generate
包也会有帮助,您可以通过以下操作安装它
cargo install cargo-generate
示例
我们有一个示例,它将在模板中运行我们已设置的内容。要运行此示例,您可以克隆存储库并更新子模块
git clone https://github.com/primitivefinance/arbiter.git
cd arbiter
git submodule update --init --recursive
从现在起,您现在可以从克隆的根目录尝试运行以下命令
cargo run --example template
此命令将进入模板CLI并显示命令和标志。
要运行ModifiedCounter.sol
示例并查看一些日志,请尝试
cargo run --example template simulate examples/template/configs/example.toml -vvv
此命令将日志级别设置为debug
,以便您可以查看内部发生了什么。
初始化
要从我们的模板arbiter-template创建自己的Arbiter项目,您可以运行以下命令
cd <your/chosen/directory>
cargo generate https://github.com/primitivefinance/arbiter-template.git
您将被提示提供项目名称,其余的将由系统为您设置!
二进制文件
要安装Arbiter二进制文件,请运行
cargo install arbiter
这将安装Arbiter二进制文件到您的机器上。然后,您可以运行arbiter --help
以查看Arbiter是否正确安装并查看帮助菜单。
绑定
您可以在模板项目的contracts/
目录中加载或编写自己的智能合约,并开始编写自己的模拟。Arbiter将Rust智能合约绑定视为一等公民。合约绑定是通过Foundry的forge
命令生成的。arbiter bind
将forge
包装起来,提供便利的功能,将所有绑定生成到src/bindings
作为Rust模块。Foundry的高级用户可以直接使用forge
。
分叉
要分叉EVM网络的某个状态,您必须首先创建一个分叉配置文件。示例在examples/fork
目录中提供。基本上,您提供数据存储位置、您想要的网络、您想要的区块号以及您想要分叉的合约的元数据。
arbiter fork <fork_config.toml>
这将在配置文件中指定的网络创建一个分支,并将其存储在您指定的位置。然后,可以使用Fork::from_disk()
方法将其加载到arbiter-core
Environment
中。
以这种方式进行分支是为了确保所有仿真都不需要持续连接到RPC端点。您可能会发现Anvil的分支接口更容易访问。然而,在线分支机制会根据需要调用RPC调用以更新状态。Arbiter Environment
分支是为了创建一个状态,将其本地存储,并在需要时从该状态初始化模拟。我们计划在未来允许arbiter-engine
与其他网络类型(如Anvil)集成!
可选参数 您可以运行arbiter fork <fork_config.toml> --overwrite
来覆盖已存在的分支。
Cargo 文档
要查看Arbiter crate的Cargo文档,请访问以下链接
您可以在crates.io上找到这些。
基准测试
在arbiter-core
中,我们有一个小的基准测试套件,它比较了ArbiterMiddleware
实现与Anvil本地测试网链实现的对比。我们选择构建Arbiter的主要原因是为了更好地控制EVM环境,并拥有更健壮的仿真框架。尽管如此,我们还希望提高速度,因此我们选择构建自己的接口,而不是使用Anvil(Anvil在底层使用revm
)。对于以下内容,Anvil被设置为为每笔交易挖矿区块,而不是设置强制性的区块时间。《Environment》被配置为10.0的区块率。以下表格给出了ArbiterMiddleware
接口在revm
上与Anvil的初步基准测试结果。
要自己运行基准测试代码,可以运行
cargo bench --package arbiter-core
操作 | ArbiterMiddleware | Anvil | 相对差异 |
---|---|---|---|
部署 | 238.975µs | 7712.436µs | ~32.2729x |
查找 | 565.617µs | 17880.124µs | ~31.6117x |
无状态调用 | 1402.524µs | 10397.55µs | ~7.413456x |
有状态调用 | 2043.88µs | 154553.225µs | ~75.61756x |
上述结果可以描述为
-
部署:在EVM中部署合约。在这个方法中,我们部署了
ArbiterToken
和ArbiterMath
,因此您可以将时间除以2来估计部署单个合约所需的时间。 -
查找:查找
ArbiterToken
客户地址的balanceOf
。在这个方法中,我们调用了100次ArbiterToken
的balanceOf
函数。除以100得到查找单个余额的时间。 -
无状态调用:调用不更改状态的合约。在这个方法中,我们调用了100次
ArbiterMath
的cdf
函数。除以100得到调用单个无状态函数的时间。 -
有状态调用:调用会改变状态的合约。在这个调用中,我们调用了
ArbiterToken
的mint
函数 100 次。除以 100 得到调用单个有状态函数的时间。
基准测试代码可以在 arbiter-core/benches/
目录中找到,这些特定的时间是在 1000 次运行的平均值上实现的。上述是通过运行 cargo bench --package arbiter-core
实现的,这将自动以发布配置运行。在配备 8 个性能核心和 2 个效率核心以及 32GB RAM 的 Apple Macbook Pro M1 Max 上实现了这些时间。
当然,Anvil 和 ArbiterMiddleware
的用例可能不同。Anvil 代表了一个更真实的具有网络和挖矿的环境。同时,ArbiterMiddleware
是一个更简单的环境,仅包含运行有状态模拟的基本要素。Anvil 还为每笔交易挖掘区块,而 ArbiterMiddleware
则不这样做。
如果您对这些基准测试或改进建议有任何疑问,请告诉我们!
测试
如果您有贡献,请为任何新编写的代码编写测试。要运行测试,您可以运行以下命令
cargo test --all --all-features
贡献
查看我们的贡献指南
依赖项
~77–115MB
~2.5M SLoC