2个不稳定版本

0.2.0 2023年9月21日
0.0.0 2023年9月20日

#2396 in 魔法豆

Download history 138/week @ 2024-04-14 117/week @ 2024-04-21 96/week @ 2024-04-28 65/week @ 2024-05-05 117/week @ 2024-05-12 547/week @ 2024-05-19 743/week @ 2024-05-26 1123/week @ 2024-06-02 954/week @ 2024-06-09 1088/week @ 2024-06-16 598/week @ 2024-06-23 129/week @ 2024-06-30 107/week @ 2024-07-07 98/week @ 2024-07-14 125/week @ 2024-07-21 72/week @ 2024-07-28

435 每月下载量
7 包中(3 直接使用)

MIT/Apache

305KB
6K SLoC

配置

Foundry的配置系统允许你根据你自己的意愿配置工具,同时提供一组合理的默认值。

配置文件

配置可以通过配置文件进行任意命名空间。Foundry的默认配置也命名为default,但你也可以任意命名和配置配置文件,并设置FOUNDRY_PROFILE环境变量为所选配置文件的名字。这导致Foundry的工具(forge)会优先选择在FOUNDRY_PROFILE中设置的具有相应名字的配置文件中的值。但所有自定义配置文件都继承自default配置文件。

foundry.toml

Foundry的工具在当前工作目录中搜索foundry.tomlFOUNDRY_CONFIG环境变量中指定的文件名。如果没有找到,将搜索父目录、父目录的父目录等,直到找到文件或到达根目录。但典型的全局foundry.toml位置是~/.foundry/foundry.toml,该路径也会被检查。如果FOUNDRY_CONFIG中设置的路径是绝对路径,则不会执行此类搜索,而是直接使用绝对路径。

foundry.toml中,你可以定义多个配置文件,因此该文件被认为是嵌套的,因此每个顶级键都声明了一个配置文件及其值配置该配置文件。

以下是一个这样的文件的示例。这也可以通过forge config获取

## defaults for _all_ profiles
[profile.default]
src = "src"
out = "out"
libs = ["lib"]
solc = "0.8.10" # to use a specific local solc install set the path as `solc = "<path to solc>/solc"`
eth-rpc-url = "https://mainnet.infura.io"

## set only when the `hardhat` profile is selected
[profile.hardhat]
src = "contracts"
out = "artifacts"
libs = ["node_modules"]

## set only when the `spells` profile is selected
[profile.spells]
## --snip-- more settings

默认配置文件

当确定要使用的配置文件时,Config会按照以下顺序,以每个键为级别从以下源读取和合并:

  1. [Config::default()],为所有参数提供默认值。
  2. foundry.tomlFOUNDRY_CONFIG 环境变量中的 TOML 文件路径。
  3. FOUNDRY_DAPP_ 前缀的环境变量。

选定的配置文件是 FOUNDRY_PROFILE 环境变量的值,如果没有设置,则为 "default"。

所有选项

以下是一个设置了所有配置选项的 foundry.toml 文件。另请参阅 /config/src/lib.rs/cli/tests/it/config.rs

## defaults for _all_ profiles
[profile.default]
src = 'src'
test = 'test'
script = 'script'
out = 'out'
libs = ['lib']
auto_detect_remappings = true # recursive auto-detection of remappings
remappings = []
# list of libraries to link in the form of `<path to lib>:<lib name>:<address>`: `"src/MyLib.sol:MyLib:0x8De6DDbCd5053d32292AAA0D2105A32d108484a6"`
# the <path to lib> supports remappings
libraries = []
cache = true
cache_path = 'cache'
broadcast = 'broadcast'
# additional solc allow paths
allow_paths = []
# additional solc include paths
include_paths = []
force = false
evm_version = 'shanghai'
gas_reports = ['*']
gas_reports_ignore = []
## Sets the concrete solc version to use, this overrides the `auto_detect_solc` value
# solc = '0.8.10'
auto_detect_solc = true
offline = false
optimizer = true
optimizer_runs = 200
model_checker = { contracts = { 'a.sol' = [
    'A1',
    'A2',
], 'b.sol' = [
    'B1',
    'B2',
] }, engine = 'chc', targets = [
    'assert',
    'outOfBounds',
], timeout = 10000 }
verbosity = 0
eth_rpc_url = "https://example.com/"
# Setting this option enables decoding of error traces from mainnet deployed / verfied contracts via etherscan
etherscan_api_key = "YOURETHERSCANAPIKEY"
# ignore solc warnings for missing license and exceeded contract size
# known error codes are: ["unreachable", "unused-return", "unused-param", "unused-var", "code-size", "shadowing", "func-mutability", "license", "pragma-solidity", "virtual-interfaces", "same-varname"]
# additional warnings can be added using their numeric error code: ["license", 1337]
ignored_error_codes = ["license", "code-size"]
deny_warnings = false
match_test = "Foo"
no_match_test = "Bar"
match_contract = "Foo"
no_match_contract = "Bar"
match_path = "*/Foo*"
no_match_path = "*/Bar*"
ffi = false
# These are the default callers, generated using `address(uint160(uint256(keccak256("foundry default caller"))))`
sender = '0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38'
tx_origin = '0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38'
initial_balance = '0xffffffffffffffffffffffff'
block_number = 0
fork_block_number = 0
chain_id = 1
# NOTE due to a toml-rs limitation, this value needs to be a string if the desired gas limit exceeds `i64::MAX` (9223372036854775807)
# `gas_limit = "Max"` is equivalent to `gas_limit = "18446744073709551615"`
gas_limit = 9223372036854775807
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 = 33554432
extra_output = ["metadata"]
extra_output_files = []
names = false
sizes = false
via_ir = false
# caches storage retrieved locally for certain chains and endpoints
# can also be restricted to `chains = ["optimism", "mainnet"]`
# by default all endpoints will be cached, alternative options are "remote" for only caching non localhost endpoints and "<regex>"
# to disable storage caching entirely set `no_storage_caching = true`
rpc_storage_caching = { chains = "all", endpoints = "all" }
# this overrides `rpc_storage_caching` entirely
no_storage_caching = false
# Whether to store the referenced sources in the metadata as literal data.
use_literal_content = false
# use ipfs method to generate the metadata hash, solc's default.
# To not include the metadata hash, to allow for deterministic code: https://docs.soliditylang.cn/en/latest/metadata.html, use "none"
bytecode_hash = "ipfs"
# Whether to append the metadata hash to the bytecode
cbor_metadata = true
# How to treat revert (and require) reason strings.
# Possible values are: "default", "strip", "debug" and "verboseDebug".
#  "default" does not inject compiler-generated revert strings and keeps user-supplied ones.
# "strip" removes all revert strings (if possible, i.e. if literals are used) keeping side-effects
# "debug" injects strings for compiler-generated internal reverts, implemented for ABI encoders V1 and V2 for now.
# "verboseDebug" even appends further information to user-supplied revert strings (not yet implemented)
revert_strings = "default"
# If this option is enabled, Solc is instructed to generate output (bytecode) only for the required contracts
# this can reduce compile time for `forge test` a bit but is considered experimental at this point.
sparse_mode = false
build_info = true
build_info_path = "build-info"
root = "root"
# Configures permissions for cheatcodes that touch the filesystem like `vm.writeFile`
# `access` restricts how the `path` can be accessed via cheatcodes
#    `read-write` | `true`   => `read` + `write` access allowed (`vm.readFile` + `vm.writeFile`)
#    `none`| `false` => no access
#    `read` => only read access (`vm.readFile`)
#    `write` => only write access (`vm.writeFile`)
# The `allowed_paths` further lists the paths that are considered, e.g. `./` represents the project root directory
# By default, only read access is granted to the project's out dir, so generated artifacts can be read by default
# following example enables read-write access for the project dir :
#       `fs_permissions = [{ access = "read-write", path = "./"}]`
fs_permissions = [{ access = "read", path = "./out"}]
[fuzz]
runs = 256
max_test_rejects = 65536
seed = '0x3e8'
dictionary_weight = 40
include_storage = true
include_push_bytes = true

[invariant]
runs = 256
depth = 15
fail_on_revert = false
call_override = false
dictionary_weight = 80
include_storage = true
include_push_bytes = true
shrink_sequence = true

[fmt]
line_length = 100
tab_width = 2
bracket_spacing = true

额外的优化器设置

可以使用 OptimizerDetails 对象调整优化器组件。

请参阅 编译器输入描述 settings.optimizer.details

optimizer_detailsoptimizerDetails 也有效)设置必须以对应的配置文件前缀:[profile.default.optimizer_details] 属于 [profile.default] 配置文件。

[profile.default.optimizer_details]
constantOptimizer = true
yul = true
# this sets the `yulDetails` of the `optimizer_details` for the `default` profile
[profile.default.optimizer_details.yulDetails]
stackAllocation = true
optimizerSteps = 'dhfoDgvulfnTUtnIf'

RPC 端点设置

rpc_endpoints 值接受一系列 alias = "<url|env var>" 对。

以下示例声明了两个对:别名 optimism 直接引用端点 URL。别名 mainnet 引用了环境变量 RPC_MAINNET,它包含整个 URL。别名 goerli 引用了一个将使用 GOERLI_API_KEY 中的值进行插值的端点。

环境变量需要用 ${} 包装。

[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 值接受一系列 alias = "{key = "", url? ="", chain?= """}" 项目。

属性 key 是必需的,应包含该链的实际 API 密钥或包含密钥的 env var,格式为 ${ENV_VAR}。如果别名已经是链名,则 chain 属性是可选的,例如在 mainnet = { key = "${ETHERSCAN_MAINNET_KEY}"} 中。可选的 url 属性可以用于显式设置 Etherscan API URL,这是不支持以名称原生支持的链的推荐设置。

[etherscan]
mainnet = { key = "${ETHERSCAN_MAINNET_KEY}" }
mainnet2 = { key = "ABCDEFG", chain = "mainnet" }
optimism = { key = "1234576" }
unknownchain = { key = "ABCDEFG", url = "https://<etherscan-api-url-for-that-chain>" }
额外的模型检查器设置

Solidity内置模型检查器是一个可选模块,可以通过ModelChecker对象启用。

请参阅编译器输入描述 settings.modelChecker模型检查器的选项

该模块在OSX和Linux的solc发布二进制文件中可用。后者需要在系统中安装z3库版本[4.8.8, 4.8.14](SO版本4.8)。

类似于上面的优化器设置,model_checker设置必须以它们对应的配置文件名作为前缀:[profile.default.model_checker]属于[profile.default]配置文件。

[profile.default.model_checker]
contracts = { 'src/Contract.sol' = [ 'Contract' ] }
engine = 'chc'
timeout = 10000
targets = [ 'assert' ]

上述字段是使用模型检查器时的推荐设置。设置要验证的合约非常重要,否则将验证所有可用的合约,这可能会消耗很多时间。推荐的引擎是chc,但bmcall(运行两者)也接受。设置适当的超时(以毫秒为单位)也很重要,因为默认分配给底层求解器的时间可能不够。如果没有指定验证目标,则仅检查断言。

在调用forge build时将运行模型检查器,如果有任何发现,将显示为警告。

环境变量

Foundry的工具读取所有以FOUNDRY_为前缀的环境变量名,使用_后的字符串作为配置值的名称,作为参数的值。但同时也支持相应的dapptools配置变量,这意味着FOUNDRY_SRCDAPP_SRC是等效的。

由于安全问题,一些上述内容被显式忽略

环境变量优先于foundry.toml中的值。值被解析为TOML语法的松散形式。以下是一些示例

依赖关系

~25–41MB
~697K SLoC