Foundry是一个用Rust语言编写的以太坊部署环境,能够帮助开发者管理依赖项、编译项目、运行测试、部署合约以及从命令行与区块链交互。由于最近开发公链使用了和foundry一样的evm crate,就安装了一下看看,后边可能需要对foundry进行二次开发;这次就简单的测试一下;
Foundry由四个工具组成:
这里我只写一下,我实践过方法;
如果您使用 Linux 或 macOS,使用 foundryup 安装最新版本,对于 Linux 和 macOS 用户来说,这是最简单的选择。打开您的终端并输入以下命令:
curl -L https://foundry.paradigm.xyz | bash
这将下载foundryup。 然后通过运行安装 Foundry:
foundryup
如果一切顺利,您现在可以使用三个二进制文件:forge、cast 、anvil和chisel。
如果您使用 macOS 并显示以下错误,您需要键入 brew install libusb 来安装库
dyld[32719]:Library not loaded:/usr/local/opt/libusb/lib/libusb-1.0.0.dylib
要从源代码构建,您需要获取 Rust和 Cargo。所以需要先按照rust的开发环境;读者自行安装。
安装好环境执行,就比较简单了,方法1或者2,任选一种;
方法1:
cargo install --git https://github.com/foundry-rs/foundry --profile local forge cast chisel anvil
方法2:
# clone the repository
git clone https://github.com/foundry-rs/foundry.git
cd foundry
# install Forge
cargo install --path ./crates/forge --profile local --force
# install Cast
cargo install --path ./crates/cast --profile local --force
# install Anvil
cargo install --path ./crates/anvil --profile local --force
# install Chisel
cargo install --path ./crates/chisel --profile local --force
Linux/macOS使用foundryup,很方便;如果你是在windows,只能从源码构建了;
使用如下命令,创建一个默认的项目
forge init foundry
创建默认项目后,您将看到以下文件:
.
├── foundry.toml
├── lib
│ └── forge-std
│ ├── LICENSE-APACHE
│ ├── LICENSE-MIT
│ ├── README.md
│ ├── foundry.toml
│ ├── lib
│ └── src
├── script
│ └── Counter.s.sol
├── src
│ └── Counter.sol
└── test
└── Counter.t.sol
7 directories, 8 files
foundry.toml
配置 Foundry 的行为。remappings.txt
中指定。src/
。test/
,其中任何具有以test
开头的函数的合约都被视为测试。lib/
中。src文件夹可能已经包含Counter.sol(一个最小的Solidity合约),我可以自行删除此合约。然后添加,一个ERC-20合约。在合约目录中,可以创建一个Token.sol文件,打开文件并添加以下合约:
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.13;
import "openzeppelin-contracts/contracts/token/ERC20/ERC20.sol";
contract Token is ERC20{
constructor(
string memory name,
string memory symbol,
uint256 initialSupply) ERC20(name, symbol){
_mint(msg.sender, initialSupply);
}
}
由于我们使用了OpenZeppelin合约,需要在编译合约之前,安装OpenZeppelin合约作为依赖项。我们使用forge install xxx安装依赖项;(默认情况下,Forge 使用 git submodules管理依赖项,这意味着它可以与任何包含智能合约的 GitHub 代码库一起使用。)所以xxx可以是一个 GitHub 仓库的路径(owner/repo
),详细可以参考forge install
forge install OpenZeppelin/openzeppelin-contracts
安装完所有的依赖项后,您可以开始编译合约:
forge build
编译完成后,将创建两个文件夹:out和cache。您合约的ABI和字节码将包含在out文件夹中。这两个文件夹已被默认Foundry项目初始化中包含的.gitignore忽略。
让我们回顾一下最常见的编写测试的方式,使用 Forge 标准库(forge-std) 的 Test
合约,这是使用 Forge 编写测试的首选方式。它提供基本的日志记录和断言功能。 要访问这些函数,请导入 forge-std/Test.sol
并继承自测试合约 Test
:
import "forge-std/Test.sol";
测试之前,我们先看下一test文件夹底下的Counter.t.sol;注意名字中的.t。
import {Test, console2} from "forge-std/Test.sol";
import {Counter} from "../src/Counter.sol";
contract CounterTest is Test {
Counter public counter;
//setUp:在每个测试用例运行之前调用的可选函数,用于部署环境
function setUp() public {
counter = new Counter();
counter.setNumber(0);
}
//test:以 test 为前缀的函数作为测试用例运行
function test_Increment() public {
counter.increment();
assertEq(counter.number(), 1);
}
//testFail: test 前缀的测试的反面 - 如果函数没有 revert,则测试失败
function testFail_Increment() public {
counter.increment();
assertEq(counter.number(), 99);
}
function testFuzz_SetNumber(uint256 x) public {
counter.setNumber(x);
assertEq(counter.number(), x);
}
}
我们修改创建一个Token.t.sol,用来测试我们的Token.sol;
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.13;
import {Test, console2} from "forge-std/Test.sol";
import {Token} from "../src/Token.sol";
contract TokenTest is Test {
Token public token;
//使用0x9创建一个新的erc20合约
function setUp() public {
vm.prank(address(9));
token = new Token("XQToken","XQ", 10000);
}
//测试0x9的地址上,token数量是不是等于总量
function test_BalanceOf() public {
uint256 bo = token.balanceOf(address(9));
assertEq(bo, 10000);
}
}
然后就可以使用,forge test进行测试啦;
更多细节可以查看Foundry