Web3:Foundry使用指南

Foundry目录

  • [1. 前言](#1. 前言)
  • [2. 什么是Foundry](#2. 什么是Foundry)
  • [3. 安装与环境配置](#3. 安装与环境配置)
    • [1. 安装工具](#1. 安装工具)
    • [2. 重新加载 `.bashrc`](#2. 重新加载 .bashrc)
    • [3. 检查环境变量 `PATH`](#3. 检查环境变量 PATH)
    • [4. 手动运行 `foundryup`](#4. 手动运行 foundryup)
  • [4. Foundry的基本使用](#4. Foundry的基本使用)
  • [5. Cli参考](#5. Cli参考)
    • [1. forge](#1. forge)
    • [2. cast](#2. cast)
    • [3. anvil](#3. anvil)
    • [3. chisel](#3. chisel)
  • [6. 解读 Foundry 配置系统](#6. 解读 Foundry 配置系统)

1. 前言

在区块链开发中,智能合约是构建Web3应用的重要组成部分。为了提升智能合约的开发效率,Foundry应运而生。作为一个新兴的开发框架,Foundry不仅具备高效的编译和测试能力,还拥有强大的调试和性能分析工具。本教程将带你一步步了解Foundry的使用方法,帮助你快速上手Web3开发。

2. 什么是Foundry

Foundry是一个开源的智能合约开发工具包,它为开发者提供了智能合约的编译、部署、测试和调试功能。Foundry更注重性能和灵活性,特别适合进行高频率的合约测试和开发。

  • Foundry的优势:

    • 速度: Foundry的编译和部署速度非常快,能够显著提高开发效率。
    • 简洁的API: 提供简洁的命令行工具,便于快速启动项目和管理智能合约。
    • 原生支持Rust语言: Foundry部分功能基于Rust开发,具有良好的跨平台兼容性。

3. 安装与环境配置

注:执行命令,必须打开 Git Bash

1. 安装工具

  • 打开 Git Bash,执行命令:
bash 复制代码
curl -L https://foundry.paradigm.xyz | bash

2. 重新加载 .bashrc

由于安装过程中系统提示你需要执行 source /c/Users/pc/.bashrc 来刷新环境变量。首先尝试以下操作:

  • 打开 Git Bash,执行命令:
bash 复制代码
source ~/.bashrc

然后尝试再次运行 foundryup

bash 复制代码
foundryup

3. 检查环境变量 PATH

如果 foundryup 仍然无法找到,检查一下 foundryup 是否正确添加到系统的 PATH 环境变量中。

  1. 执行以下命令,检查 foundryup 是否安装成功:
bash 复制代码
foundryup --version
  1. 执行以下命令,检查路径中是否包含 foundryup 安装目录:
bash 复制代码
echo $PATH

你应该看到 foundryup 所在目录,如果没有,可能需要手动将它添加到你的 PATH 环境变量中。

  1. 检查 Foundry 工具是否安装成功
bash 复制代码
forge --version
cast --version
anvil --version
chisel --version

4. 手动运行 foundryup

尝试手动找到 foundryup 可执行文件的位置。你可以使用以下命令来检查 foundryup 是否安装成功,并查看其路径:

bash 复制代码
which foundryup

4. Foundry的基本使用

一旦Foundry安装完成,你就可以开始创建Web3项目了。

1.创建一个新的Foundry项目

在终端中执行以下命令,生成一个新的项目目录。

bash 复制代码
forge init my-first-project

2. 编写智能合约

src目录中创建一个新的Solidity文件(如MyContract.sol),并编写简单的智能合约。

示例:

solidity 复制代码
pragma solidity ^0.8.0;

contract MyContract {
    uint256 public count;

    function increment() public {
        count += 1;
    }
}

3. 编译智能合约

使用forge build命令编译合约。

bash 复制代码
forge build

4. foundry.toml 主要作用

  • 配置编译器:你可以指定要使用的 Solidity 编译器的版本,以及其他编译选项。

  • 优化设置:用于控制 Solidity 合约的优化选项,例如优化程度、优化的次数等。

  • 测试配置:设置与测试相关的参数,例如超时设置和测试运行时环境。

  • 自定义路径:指定合约、测试、脚本等文件的路径。

  • 配置外部库:如果你在项目中使用了外部库,可以在 foundry.toml 中指定相关的路径和设置。

5.部署智能合约

使用forge deploy命令进行部署。

git 复制代码
forge deploy

5. Cli参考

1. forge

shell 复制代码
用法: forge <COMMAND>

命令:
  bind               为智能合约生成 Rust 绑定
  bind-json          通过 JSON cheatcodes 生成项目结构的序列化/反序列化绑定
  build              构建项目的智能合约 [别名: b, compile]
  cache              管理 Foundry 缓存
  clean              移除构建产物和缓存目录 [别名: cl]
  clone              从 Etherscan 克隆合约
  compiler           编译器工具
  completions        生成 shell 完成脚本 [别名: com]
  config             显示当前配置 [别名: co]
  coverage           生成覆盖率报告
  create             部署智能合约 [别名: c]
  debug              作为脚本调试单个智能合约 [别名: d]
  doc                为项目生成文档
  eip712             为给定文件中的结构生成 EIP-712 结构编码
  flatten            将源文件及其所有导入扁平化为一个文件 [别名: f]
  fmt                格式化 Solidity 源文件
  geiger             检测项目及其依赖中不安全 cheat codes 的使用
  generate           生成脚手架文件
  generate-fig-spec  生成 Fig 自动补全规范 [别名: fig]
  help               打印此消息或给定子命令的帮助
  init               创建一个新的 Forge 项目
  inspect            获取关于智能合约的专门信息 [别名: in]
  install            安装一个或多个依赖 [别名: i]
  remappings         获取项目的自动推断重映射 [别名: re]
  remove             移除一个或多个依赖 [别名: rm]
  script             作为脚本运行智能合约,构建可以在链上发送的交易
  selectors          函数选择器工具 [别名: se]
  snapshot           创建每个测试的 gas 使用快照 [别名: s]
  soldeer            Soldeer 依赖管理器
  test               运行项目的测试 [别名: t]
  tree               显示项目依赖图的树状可视化 [别名: tr]
  update             更新一个或多个依赖 [别名: u]
  verify-bytecode    验证已部署的字节码与其在 Etherscan 上的源代码 [别名: vb]
  verify-check       检查在 Etherscan 上的验证状态 [别名: vc]
  verify-contract    在 Etherscan 上验证智能合约 [别名: v]

2. cast

shell 复制代码
用法: cast <COMMAND>

命令:
  4byte                  从 https://openchain.xyz 获取给定选择器的函数签名 [别名: 4, 4b]
  4byte-decode           使用 https://openchain.xyz 解码 ABI 编码的 calldata [别名: 4d, 4bd]
  4byte-event            从 https://openchain.xyz 获取给定主题 0 的事件签名 [别名: 4e, 4be, topic0-event, t0e]
  abi-decode             解码 ABI 编码的输入或输出数据 [别名: ad, --abi-decode]
  abi-encode             ABI 编码给定的函数参数,排除选择器 [别名: ae]
  access-list            为交易创建访问列表 [别名: ac, acl]
  address-zero           打印零地址 [别名: --address-zero, az]
  admin                  获取 EIP-1967 管理账户 [别名: adm]
  age                    获取区块的时间戳 [别名: a]
  balance                获取账户的 wei 余额 [别名: b]
  base-fee               获取区块的 basefee [别名: ba, fee, basefee]
  bind                   从给定 ABI 生成 rust 绑定 [别名: bi]
  block                  获取区块的信息 [别名: bl]
  block-number           获取最新的区块号 [别名: bn]
  call                   在账户上执行调用而不发布交易 [别名: c]
  calldata               ABI 编码带参数的函数 [别名: cd]
  calldata-decode        解码 ABI 编码的输入数据 [别名: --calldata-decode, cdd]
  chain                  获取当前链的符号名称
  chain-id               获取以太坊链 ID [别名: ci, cid]
  client                 获取当前客户端版本 [别名: cl]
  code                   获取合约的运行时字节码 [别名: co]
  codehash               获取账户的 codehash
  codesize               获取合约的运行时字节码大小 [别名: cs]
  completions            生成 shell 完成脚本 [别名: com]
  compute-address        从给定的 nonce 和部署者地址计算合约地址 [别名: ca]
  concat-hex             连接十六进制字符串 [别名: --concat-hex, ch]
  create2                使用 CREATE2 生成确定性合约地址 [别名: c2]
  decode-eof             解码 EOF 容器字节
  decode-transaction     解码原始签名的 EIP 2718 类型交易 [别名: dt, decode-tx]
  disassemble            将十六进制编码的字节码反汇编为单个/可读的操作码 [别名: da]
  estimate               估算交易的 gas 成本 [别名: e]
  etherscan-source       从 Etherscan 获取合约的源代码 [别名: et, src]
  find-block             获取与提供的时间戳最接近的区块号 [别名: f]
  format-bytes32-string  将字符串格式化为 bytes32 编码 [别名: --format-bytes32-string]
  from-bin               将二进制数据转换为十六进制数据 [别名: --from-bin, from-binx, fb]
  from-fixed-point       将定点数转换为整数 [别名: --from-fix, ff]
  from-rlp               解码 RLP 十六进制编码的数据 [别名: --from-rlp]
  from-utf8              将 UTF8 文本转换为十六进制 [别名: --from-ascii, --from-utf8, from-ascii, fu, fa]
  from-wei               将 wei 转换为 ETH 数量 [别名: --from-wei, fw]
  gas-price              获取当前 gas 价格 [别名: g]
  generate-fig-spec      生成 Fig 自动补全规范 [别名: fig]
  hash-message           根据 EIP-191 哈希消息 [别名: --hash-message, hm]
  hash-zero              打印零哈希 [别名: --hash-zero, hz]
  help                   打印此消息或给定子命令的帮助
  implementation         获取 EIP-1967 实现账户 [别名: impl]
  index                  计算映射中条目的存储槽 [别名: in]
  index-erc7201          按照 `ERC-7201: Namespaced Storage Layout` 指定计算存储槽 [别名: index7201, in7201]
  interface              从给定 ABI 生成 Solidity 接口 [别名: i]
  keccak                 使用 Keccak-256 哈希任意数据 [别名: k, keccak256]
  logs                   按签名或主题获取日志 [别名: l]
  lookup-address         执行 ENS 反向查找 [别名: la]
  max-int                打印给定整数类型的最大值 [别名: --max-int, maxi]
  max-uint               打印给定整数类型的最大值 [别名: --max-uint, maxu]
  min-int                打印给定整数类型的最小值 [别名: --min-int, mini]
  mktx                   构建并签名交易 [别名: m]
  namehash               计算名称的 ENS namehash [别名: na, nh]
  nonce                  获取账户的 nonce [别名: n]
  parse-bytes32-address  从 bytes32 编码解析校验和地址 [别名: --parse-bytes32-address]
  parse-bytes32-string   从 bytes32 编码解析字符串 [别名: --parse-bytes32-string]
  pretty-calldata        美化打印 calldata [别名: pc]
  proof                  为给定存储槽生成存储证明 [别名: pr]
  publish                将原始交易发布到网络 [别名: p]
  receipt                获取交易的收据 [别名: re]
  resolve-name           执行 ENS 查找 [别名: rn]
  rpc                    执行原始 JSON-RPC 请求 [别名: rp]
  run                    在本地环境中运行已发布的交易并打印跟踪 [别名: r]
  selectors              从字节码中提取函数选择器和参数 [别名: sel]
  send                   签名并发布交易 [别名: s]
  shl                    执行左移操作
  shr                    执行右移操作
  sig                    获取函数的选择器 [别名: si]
  sig-event              从事件字符串生成事件签名 [别名: se]
  storage                获取合约存储槽的原始值 [别名: st]
  storage-root           获取账户的存储根 [别名: sr]
  to-ascii               将十六进制数据转换为 ASCII 字符串 [别名: --to-ascii, tas, 2as]
  to-base                将一个基数的数字转换为另一个基数 [别名: --to-base, --to-radix, to-radix, tr, 2r]
  to-bytes32             将十六进制数据右填充到 32 字节 [别名: --to-bytes32, tb, 2b]
  to-check-sum-address   将地址转换为校验和格式 (EIP-55) [别名: --to-checksum-address, --to-checksum, to-checksum, ta, 2a]
  to-dec                 将一个基数的数字转换为十进制 [别名: --to-dec, td, 2d]
  to-fixed-point         将整数转换为定点数 [别名: --to-fix, tf, 2f]
  to-hex                 将一个基数的数字转换为另一个基数 [别名: --to-hex, th, 2h]
  to-hexdata             将输入标准化为小写,0x 前缀的十六进制 [别名: --to-hexdata, thd, 2hd]
  to-int256              将数字转换为十六进制编码的 int256 [别名: --to-int256, ti, 2i]
  to-rlp                 RLP 编码十六进制数据或十六进制数据数组 [别名: --to-rlp]
  to-uint256             将数字转换为十六进制编码的 uint256 [别名: --to-uint256, tu, 2u]
  to-unit                将 ETH 数量转换为另一单位 (ether, gwei 或 wei) [别名: --to-unit, tun, 2un]
  to-utf8                将十六进制数据转换为 utf-8 字符串 [别名: --to-utf8, tu8, 2u8]
  to-wei                 将 ETH 数量转换为 wei [别名: --to-wei, tw, 2w]
  tx                     获取交易的信息 [别名: t]
  upload-signature       将给定的签名上传到 https://openchain.xyz [别名: ups]
  wallet                 钱包管理工具 [别名: w]

3. anvil

shell 复制代码
# 启动本地以太坊节点,生成 10 个账户,余额为 10000 以太币,监听 8545 端口
anvil --accounts 10 --balance 10000 --port 8545

# 启动本地节点,连接到远程 RPC 端点,从指定的区块号获取状态
anvil --fork-url http://localhost:8545 --fork-block-number 1400000

# 禁用自动挖矿,按需挖矿
anvil --no-mining

# 将链的状态转储到指定文件(例如 state.json)
anvil --dump-state ./state.json

# 从远程端点加载链的状态
anvil --load-state ./state.json

# 设置区块生成的时间间隔为 10 秒
anvil --block-time 10

# 设置每个开发账户的初始余额为 10000 以太币
anvil --balance 10000

# 设置 RPC URL(例如连接到远程以太坊节点)
anvil --rpc-url http://localhost:8545

# 启用硬分叉(例如 'shanghai')
anvil --hardfork shanghai

# 禁用 CORS(跨域资源共享)
anvil --no-cors

# 启动时不打印任何内容,不输出日志
anvil --silent

# 设置链的最大状态持久化数量
anvil --max-persisted-states 100

# 设置链的 gas 限制
anvil --gas-limit 10000000

# 设置链的 gas 价格
anvil --gas-price 1000000000

# 启用 Alphanet 功能
anvil --alphanet

# 启用 Optimism 链
anvil --optimism

# 打印 Anvil 的版本信息
anvil --version

3. chisel

shell 复制代码
# 列出所有缓存的会话
chisel list

# 加载一个缓存的会话
chisel load <SESSION_NAME>

# 查看缓存会话的源代码
chisel view <SESSION_NAME>

# 清除缓存目录中的所有缓存会话
chisel clear-cache

# 简单评估一个命令而不进入 REPL
chisel eval "<COMMAND>"

# 打印帮助信息
chisel help

# 打印 chisel 的版本信息
chisel --version

# 禁用默认的 Vm 导入
chisel --no-vm

# 指定导入 Solidity 文件的路径,充当 REPL 的前奏
chisel --prelude <PRELUDE_PATH>

# 强制清除缓存并重新编译
chisel --force

# 禁用缓存
chisel --no-cache

# 跳过指定文件的构建
chisel --skip <SKIP_PATTERN>

# 设置预链接的库
chisel --libraries <LIBRARIES_PATH>

# 设置编译器选项,如指定 solc 版本
chisel --use <SOLC_VERSION>

# 不自动检测 solc 版本
chisel --no-auto-detect

# 使用 Yul 中间表示法编译
chisel --via-ir

# 不附加任何元数据到字节码
chisel --no-metadata

# 设置目标 EVM 版本
chisel --evm-version <VERSION>

# 激活 Solidity 优化器
chisel --optimize <true|false>

# 设置优化运行次数
chisel --optimizer-runs <RUNS>

# 生成额外的编译输出(例如 assembly、metadata)
chisel --extra-output <SELECTOR>...

# 设置输出目录,保存合约工件
chisel -o <PATH>

# 设置项目根目录路径
chisel --root <PROJECT_ROOT_PATH>

# 设置合约源目录
chisel -C --contracts <CONTRACTS_PATH>

# 设置项目的重映射
chisel -R --remappings <REMAPPINGS>

# 设置编译器缓存路径
chisel --cache-path <CACHE_PATH>

# 从远程端点获取状态,而不是从空状态开始
chisel -f --fork-url <URL>

# 从远程端点获取特定区块号的状态
chisel --fork-block-number <BLOCK_NUMBER>

# 设置交易来源地址
chisel --tx-origin <ADDRESS>

# 设置区块时间戳
chisel --block-timestamp <TIMESTAMP>

# 设置区块号
chisel --block-number <BLOCK_NUMBER>

# 设置每次 EVM 执行的内存限制(以字节为单位)
chisel --memory-limit <MEMORY_LIMIT>

# 启用隔离模式,在单独的 EVM 上下文中执行顶层调用
chisel --isolate

# 启用 Alphanet 功能
chisel --alphanet

6. 解读 Foundry 配置系统

1. foundry.toml 文件

Foundry 的工具会搜索当前工作目录及其父目录中的 foundry.toml 配置文件。如果没有找到,工具会继续搜索直至根目录。此外,全局配置文件 的默认位置是 ~/.foundry/foundry.toml,这也是会被检查的地方。如果你通过环境变量 FOUNDRY_CONFIG 指定了配置文件的路径,则该路径会被直接使用,不再进行搜索。

foundry.toml 文件支持定义多个 profiles,每个 profile 配置一组参数。每个顶级键代表一个 profile,文件是 嵌套 的,意味着每个顶级键下配置的内容都属于该 profile 的设置。

2.foundry.toml 文件示例

toml 复制代码
## 默认配置 - 对所有 profile 有效
[profile.default]
src = "src"
out = "out"
libs = ["lib"]
solc = "0.8.10"  # 使用本地安装的 solc 编译器,路径可以指定
eth-rpc-url = "https://mainnet.infura.io"

## 当选择 `hardhat` profile 时的配置
[profile.hardhat]
src = "contracts"
out = "artifacts"
libs = ["node_modules"]

## 当选择 `spells` profile 时的配置
[profile.spells]
# --snip-- 更多设置

3,Profile 选择和优先级

当决定使用哪个 profile 时,Foundry 的配置系统会按以下顺序逐一检查配置:

  1. Config::default():提供默认的配置值。
  2. foundry.toml 或通过 FOUNDRY_CONFIG 环境变量指定的 TOML 文件。
  3. 环境变量:使用 FOUNDRY_DAPP_ 前缀的环境变量(它们对应的配置参数值)。
  • 如果 FOUNDRY_PROFILE 环境变量未设置,则默认使用 "default" profile。
  • 环境变量优先于 foundry.toml 中的配置。

3.配置示例说明

foundry.toml 配置文件允许设置非常多的参数,下面是一些重要的选项:

基本配置
  • src :指定 Solidity 合约源码的目录,默认是 "src"
  • test :指定测试文件的目录,默认是 "test"
  • script :指定脚本文件的目录,默认是 "script"
  • out :指定编译输出目录,默认是 "out"
  • libs :外部库的路径,默认是 "lib"
Solidity 编译器设置
  • solc :指定使用的 Solidity 编译器版本,或者你可以提供本地 solc 的路径。
  • auto_detect_solc :是否自动检测 solc 版本,默认为 true
  • optimizer :是否启用优化,默认为 false
  • optimizer_runs:优化运行的次数,默认为 200。
以太坊 RPC URL
  • eth_rpc_url :指定以太坊节点的 RPC 地址(如 https://mainnet.infura.io),用于与以太坊网络进行交互。
文件和库配置
  • libraries :可以链接外部 Solidity 库,格式为 "<path to lib>:<lib name>:<address>"
  • remappings:定义源代码中的 remappings,以便引用外部合约。
  • cache :启用缓存,默认为 true
EVM 配置
  • gas_limit:设置区块的 gas 限制。
  • gas_price:设置 gas 价格。
  • block_timestamp:设置区块时间戳。
调试和模型检查
  • model_checker:启用 Solidity 内置的模型检查器,用于验证合约的安全性。
  • verbosity:设置 EVM 的详细程度,数值越大,输出信息越多。
优化器和额外输出
  • extra_output :设置编译时的额外输出内容,例如 metadataevm.assembly
  • sparse_mode:启用稀疏模式,仅生成必需的字节码,减少编译时间。
权限和文件系统配置
  • fs_permissions:配置文件系统的访问权限,控制是否允许读取或写入某些文件。

RPC 端点配置

rpc_endpoints 配置允许你为多个 RPC 服务设置别名。这样,你可以使用别名来引用不同的端点。

toml 复制代码
[rpc_endpoints]
optimism = "https://optimism.alchemyapi.io/v2/1234567"
mainnet = "${RPC_MAINNET}"
goerli = "https://eth-goerli.alchemyapi.io/v2/${GOERLI_API_KEY}"

Etherscan API 配置

etherscan 部分配置了用于与 Etherscan 交互的 API 密钥,支持多个链和环境变量。

toml 复制代码
[etherscan]
mainnet = { key = "${ETHERSCAN_MAINNET_KEY}" }
optimism = { key = "1234576", chain = 42 }

4. 完整的 foundry.toml 配置文件实例

shell 复制代码
## 默认配置 - 对所有 Profile 有效
[profile.default]
# Solidity 合约源码目录
src = "src"
# 测试文件目录
test = "test"
# 脚本文件目录
script = "script"
# 编译输出目录
out = "out"
# 外部库的路径
libs = ["lib"]
# 是否自动检测 remappings
auto_detect_remappings = true
# 存放 remappings 的列表
remappings = []
# 用于链接的库
libraries = []
# 启用缓存,默认为 true
cache = true
# 缓存路径
cache_path = "cache"
# 广播目录
broadcast = "broadcast"
# solc 额外的允许路径
allow_paths = []
# solc 额外的 include 路径
include_paths = []
# 是否强制重新编译
force = false
# 使用的 EVM 版本
evm_version = "prague"
# 是否启用 gas 报告,默认为 "所有"
gas_reports = ["*"]
gas_reports_ignore = []
# 编译器版本,若为空则自动检测
auto_detect_solc = true
solc = "0.8.10"  # 指定编译器版本
offline = false
optimizer = false
optimizer_runs = 200

# 模型检查配置
model_checker = { 
    contracts = { 'src/Contract.sol' = ['Contract'] },
    engine = 'chc',
    targets = ['assert'],
    timeout = 10000
}

# EVM 相关设置
verbosity = 2
eth_rpc_url = "https://mainnet.infura.io/v3/YOUR_INFURA_PROJECT_ID"

# Etherscan API Key 设置
etherscan_api_key = "YOUR_ETHERSCAN_API_KEY"

# 忽略的 solc 警告
ignored_error_codes = ["license", "code-size"]
ignored_warnings_from = ["path_to_ignore"]
deny_warnings = false

# 线程数,0 表示使用逻辑核心数
threads = 0
# 是否显示测试执行进度
show_progress = true

# 文件系统权限配置
fs_permissions = [{ access = "read-write", path = "./out" }]
assertions_revert = true
legacy_assertions = false

## 专用于 `hardhat` Profile 配置
[profile.hardhat]
src = "contracts"
out = "artifacts"
libs = ["node_modules"]
eth_rpc_url = "https://mainnet.infura.io/v3/YOUR_INFURA_PROJECT_ID"
auto_detect_solc = true
solc = "0.8.10"
cache = true

## 专用于 `spells` Profile 配置
[profile.spells]
src = "spells"
out = "spell_out"
libs = ["lib/spells"]
solc = "0.8.10"
eth_rpc_url = "https://kovan.infura.io/v3/YOUR_INFURA_PROJECT_ID"

## RPC 端点配置
[rpc_endpoints]
optimism = "https://optimism.alchemyapi.io/v2/1234567"
mainnet = "${RPC_MAINNET}"
goerli = "https://eth-goerli.alchemyapi.io/v2/${GOERLI_API_KEY}"

## 默认的测试合约调用者配置
sender = '0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38'
tx_origin = '0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38'
initial_balance = '0xffffffffffffffffffffffff'
block_number = 0
fork_block_number = 0
chain_id = 1

## Gas 限制与费用设置
gas_limit = 1073741824
gas_price = 0
block_base_fee_per_gas = 0
block_coinbase = '0x0000000000000000000000000000000000000000'
block_timestamp = 0
block_difficulty = 0
block_prevrandao = '0x0000000000000000000000000000000000000000'
block_gas_limit = 30000000
memory_limit = 134217728

## 额外输出设置
extra_output = ["metadata"]
extra_output_files = []

# 强制启用 Create2 工厂
always_use_create_2_factory = false
# 是否启用 FFI cheatcode
ffi = false

## 模型检查器设置
[profile.default.model_checker]
contracts = { 'src/Contract.sol' = ['Contract'] }
engine = 'chc'
timeout = 10000
targets = ['assert']

## 配置代码格式化
[fmt]
line_length = 100
tab_width = 2
bracket_spacing = true

## 构建和构建信息设置
build_info = true
build_info_path = "build-info"
root = "root"