初识foundry框架(二)

foundry常用

目录架构

我们先看看安装了foundry后各个目录的作用,下面是一张图片,我们挨个讲解

屏幕截图 2024-11-01 105603.png

lib/forge-std

我们安装的库都会在这里面。

src目录

编写合约的目录

scripts目录

部署合约的脚本目录

指定网络

forge script script/Counter.s.sol --rpc-url <write> --broadcast --private -key <write>

forge script script/Counter.s.sol:CounterScript --rpc-url http://localhost:8545 --broadcast --account defaultKey --sender 0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266<公钥地址>

forge script script/DeploySimpleStorage.s.sol:DeploySimpleStorage --rpc-url $OP_SEPOLIA_RPC_URL --broadcast  --account defaultKey --sender
  • RPC_URL 可以在 Alchemy - the web3 development platform 注册得到

  • script/Counter.s.sol:CounterScript :script目录下的合约的合约函数

    一般都是部署合约的函数

  • --broadcast :在链上进行广播,没有这个参数的话,合约是不会部署在链上的

  • --account : 跟 私钥

test目录

专门用于测试的目录。

forge test -v

-vv 参数

-vv 是一个选项,用于增加输出的详细程度。在 Foundry 中,-v 表示“verbose”(详细的),每增加一个 v 就会进一步增加详细程度。

  • -v:显示基本的详细信息。
  • -vv:显示更多详细信息,包括每个测试的日志输出。
  • -vvv:显示更详细的信息,可能包括内部调试信息。
  • -vvvv:显示最详细的信息,通常用于调试。
  • -vvv-vvvv:用于需要更详细的调试信息时。
  • --gas-report:生成 Gas 使用报告。
  • --mt: 指定函数进行测试

指定网络测试

forge test --mt testConvert -vvvv  --fork-url $OP_SEPOLIA_RPC_URL

覆盖测试

forge coverage --fork-url $OP_SEPOLIA_RPC_URL

特殊文件

.env

这个是自己创建的隐藏敏感信息的文件,像上面跟个 “$" ,就是引用里面的变量,其实框架自己也有工具可以,只是为了平时测试的方便这么做。所以进行测试的钱包不要有真实资金在里面。

先加载环境变量

source .env

再引用里面定义好的变量

部分变量

RPC_URL=http://localhost:8545

使用

forge coverage --fork-url $OP_SEPOLIA_RPC_URL

特殊功能后面跟个参数名即可

foundry.toml

可以方便我们导入文件的时候,不用再去修改文件路径。

[profile.default]
src = "src"
out = "out"
libs = ["lib"]
remappings = ["@chainlink/contracts/=lib/forge-std/chainlink-brownie-contracts/contracts/"]

@chainlink/contracts/ 替换成 lib/forge-std/chainlink-brownie-contracts/contracts/

配合这个命令我们可以看到我们替换的内容是啥

## remappings.txt 文件

forge remapping > remapping.txt
//显示依赖库导入到该txt文件里面

.gitignore

这个文件非常重要,当我们push代码到GitHub的时候,可以避免敏感文件被上传上去

文件内容,我们的 .env 就在里面

# Compiler files
cache/
out/

# Ignores development broadcast logs
!/broadcast
/broadcast/*/31337/
/broadcast/**/dry-run/

# Docs
docs/

# Dotenv file
.env

常用命令

安装库

forge install <  >  --no-commit

如果存在无法获取github代码的情况,一般是你的WSL网络配置没配好,针对具体问题询问GPT可以解决 我们也可以不使用这个命令,我们前面是配置过 GitHub信息的,可以通过 git 命令来获取远程库。

git clone <github库的https链接 or ssh的链接>

编译合约

forge compile 

启用anvil链

本地链,这个是foundry框架自带的功能,可以显示对应的虚拟用户公钥和私钥

anvil

cast使用

cast call <公钥> "retrieve()<函数名>"

调用函数

cast send <合约地址>  "函数名(参数)"  参数  --rpc-url --broadcast http://localhost:8545 --account defaultKey 

cast send 0x5FbDB2315678afecb367f032d93F642f64180aa3   "store(uint256)"  123  --rpc-url http://localhost:8545 --account defaultKey 

cast call <合约地址> "retrieve()<函数名>"
cast call 0x5FbDB2315678afecb367f032d93F642f64180aa3 "retrieve()" 

将bytecode 编码转化 十进制

cast call 0x5FbDB2315678afecb367f032d93F642f64180aa3 "retrieve()" 
0x000000000000000000000000000000000000000000000000000000000000007b  //调用该函数的返回值

cast --to-base 0x000000000000000000000000000000000000000000000000000000000000007b dec //dec 表示目标进制是 十进制

函数选择器查看是否跟我们要调用的函数匹配

cast sig "fund() <函数名称>"

gas预估

  1. 指定函数测试预估gas

    forge snapshot --mt  testWithdrawWithOwner <函数名>
  2. 之后会在 .gas-snapshot.txt 文件里面看到

    FundMeTest:testWithdrawWithOwner() (gas: 104736)
  3. gas预估流程

           uint256 gas_start = gasleft();
           vm.prank(fundMe.getOwner());
           fundMe.withdraw();
           uint256 gas_end = gasleft();
           uint256 gas_used = (gas_start - gas_end) * tx.gasprice; //数量 * 当前gas价格
           console.log(gas_used);

cheatcode 作弊码

下面就列举一些常用的

  1. 下面操作由上面的用户执行 -- vm.prank(USER);

    modifier funded() {
           //避免代码重复
           vm.prank(USER);
           fundMe.fund{ value: SEND_VALUE }();
           _;
       }

    这里使用的修饰器,便携写代码

    用户通过makeAddr定义

      address USER = makeAddr("user"); //用作弊码创建的一个用户
  2. 给用户铸造一些代币

    uint256 constant STARTING_BALANCE = 10 ether;
    vm.deal(USER, STARTING_BALANCE) //前面是用户,后面是代币数量
  3. 操作期望回退

    vm.expectRevert(); //预期下面的操作会回退,来测试判断条件
  4. vm.startBroadcast(); vm.stopBroadcast(); 这个常用于我们部署合约的时候

    pragma solidity ^0.8.18;
    
    import {Script,console} from "forge-std/Script.sol";
    import {FundMe} from "../src/FundMe.sol";
    
    contract DeployFundMe is Script{
    
       function run() public{ //run函数是默认进行合约部署的
           vm.startBroadcast();
           new FundMe();
           vm.stopBroadcast();
       }
    }

    注意!:vm.prank(user) 不能和 vm.startbroadcast vm.stopbroadcast 合用

点赞 0
收藏 0
分享
本文参与登链社区写作激励计划 ,好文好收益,欢迎正在阅读的你也加入。

0 条评论

请先 登录 后评论
浪迹陨灭
浪迹陨灭
0x0c37...a92b
专注于solidity智能合约的开发