21个版本 (6个重大更改)
0.11.0 | 2024年4月26日 |
---|---|
0.10.3 | 2024年2月21日 |
0.9.1 | 2023年12月1日 |
0.8.0 | 2023年11月14日 |
0.5.1 | 2023年9月18日 |
#94 在 #evm
每月554次下载
用于 2 crate
1.5MB
30K SLoC
扩展EVM工具生态系统。
概览
Arbiter 是一个快速的以太坊沙盒,允许开发者编排事件驱动的模拟。该框架允许对(Rust)以太坊虚拟机(EVM)进行细粒度控制,以提供具有状态的以太坊智能合约交互和创建可以合并成复杂场景或自动化的行为。我们使用在 revm 上构建的 ethers-rs
中间件,revm也用于例如 reth
和 foundry
等ETH客户端。这为我们提供了速度、可配置性和模块化,感觉就像一个轻量级的自定义以太坊节点。
Arbiter的主要用途是探测智能合约的机制安全性。如果您对此感兴趣,请参阅 漏洞语料库。
Arbiter工作空间包含五个crate
arbiter
:一个二进制文件,提供了一个命令行界面来分叉和绑定合约。arbiter-core
:一个库,包含Arbiter框架的核心逻辑,包括之前讨论的ArbiterMiddleware
,以及我们的沙盒Environment
。arbiter-engine
:一个库,提供了构建模拟、代理和行为的抽象。arbiter-macros
:一个库crate,包含用于简化Arbiter开发的宏。arbiter-bindings
:一个库crate,包含用于测试和开发的实用智能合约的绑定。
书籍
在这里您可以找到 Arbiter 文档。这是一个mdbook,提供了对如何使用Arbiter框架的整体理解。
动机
仲裁器是为了让您能够在有状态的沙盒中与智能合约一起工作,并设计出可以与合约一起使用的代理。这为您提供了许多功能。例如,智能合约工程师必须测试他们的合约针对各种可能具有对抗性的环境和参数,而不仅仅依赖于静态的无状态测试。
在去中心化金融(DeFi)中,各种复杂的去中心化应用程序可以使用上述测试。然而,隐含的金融策略也涉及许多代理和参数化。金融工程师可能希望测试他们的策略针对数千种市场条件、合约设置、冲击和自主或随机的AI代理,同时确保他们的方法不会受到字节码级别的漏洞攻击。同样,该工程师可能还希望开发搜索代理、求解代理或其他可在区块链上运行的自主代理。
使用仲裁器框架
要使用仲裁器,您必须在您的机器上安装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创建自己的仲裁器项目,您可以运行以下命令:
cd <your/chosen/directory>
cargo generate https://github.com/primitivefinance/arbiter-template.git
您将被提示输入项目名称,其余部分将为您设置!
二进制
要安装仲裁器二进制文件,请运行以下命令:
cargo install arbiter
这将安装仲裁器二进制文件到您的机器上。然后,您可以通过运行arbiter --help
来查看仲裁器是否正确安装并查看帮助菜单。
绑定
您可以在模板项目的contracts/
目录中加载或编写自己的智能合约,并开始编写自己的模拟。仲裁器将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来更新状态。仲裁器Environment
分叉用于创建状态,将其存储在本地,并能够在需要时从这个状态初始化仿真。我们计划将来允许arbiter-engine
与其他网络类型集成,例如Anvil!
可选参数 您可以运行arbiter fork <fork_config.toml> --overwrite
来覆盖已存在的分叉。
Cargo 文档
要查看Arbiter Crates的Cargo文档,请访问以下链接
您可以在crates.io上找到这些。
基准测试
在arbiter-core
中,我们有一个小型的基准测试套件,用于比较ArbiterMiddleware
实现与Environment
相对于Anvil本地测试网链实现的差异。我们选择构建Arbiter的主要原因是为了获得更多对EVM环境的控制权,并拥有一个更健壮的仿真框架。尽管如此,我们也希望提高速度,因此我们选择在revm
上构建自己的接口,而不是使用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以估算部署单个合约所需的时间。 -
查找:查找
balanceOf
客户端地址的ArbiterToken
。在此方法中,我们调用了ArbiterToken
的balanceOf
函数100次。除以100以获得查找单个余额所需的时间。 -
无状态调用:调用不更改状态的合约。在此方法中,我们调用了
ArbiterMath
的cdf
函数100次。除以100以获得调用单个无状态函数所需的时间。 -
有状态调用:调用更改状态的合约。在此调用中,我们调用了
ArbiterToken
的mint
函数100次。除以100以获得调用单个有状态函数所需的时间。
基准测试代码位于arbiter-core/benches/
目录中,这些特定时间是在1000次运行的平均值上实现的。上述结果是通过运行cargo bench --package arbiter-core
获得的,这将自动以发布配置运行。测试是在配备了8个性能核心和2个效率核心以及32GB内存的Apple Macbook Pro M1 Max上实现的。
当然,Anvil和ArbiterMiddleware
的使用场景可能会有所不同。Anvil代表了一个带有网络和挖掘的更真实的环境。同时,ArbiterMiddleware
是一个更简单的环境,只包含运行有状态模拟的最基本要素。Anvil还为每笔交易挖掘区块,而ArbiterMiddleware
则不会。
如果您需要这些基准测试的任何帮助或有改进建议,请告诉我们!
测试
如果您有所贡献,请为任何新编写的代码编写测试。要运行测试,您可以执行以下操作
cargo test --all --all-features
贡献
查看我们的贡献指南
依赖项
~69–105MB
~2M SLoC