阅读(2769) (12)

使用命令行编译器

2022-05-23 17:56:03 更新
笔记
本节不适用于solcjs,即使它在命令行模式下使用也是如此。

基本用法

Solidity 存储库的构建目标之一是soliditysolc命令行编译器。使用为您提供所有选项的解释。编译器可以产生各种输出,从简单的二进制文件和抽象语法树(解析树)上的汇编到气体使用量的估计。如果你只想编译一个文件,你运行它,它会打印二进制文件。如果您想获得一些更高级的输出变体,最好告诉它输出所有内容以使用.solc --helpsolc --bin sourceFile.solsolcsolc -o outputDirectory --bin --ast-compact-json --asm sourceFile.sol

优化器选项

在部署合约之前,请在编译时使用. 默认情况下,优化器将优化合约,假设它在其生命周期内被调用 200 次(更具体地说,它假设每个操作码被执行大约 200 次)。如果您希望最初的合约部署更便宜,而后来的功能执行更昂贵,请将其设置为. 如果您期望有很多事务并且不关心更高的部署成本和输出大小,请设置为较高的数字。此参数对以下内容有影响(将来可能会更改):solc --optimize --bin sourceFile.sol--optimize-runs=1--optimize-runs

  • 函数调度例程中二分查找的大小

  • 存储大数或字符串等常量的方式

基本路径和导入重新映射

命令行编译器会自动从文件系统读取导入的文件,但也可以使用以下方式提供路径重定向:prefix=path

solc github.com/ethereum/dapp-bin/=/usr/local/lib/dapp-bin/ file.sol

这实际上指示编译器搜索以 github.com/ethereum/dapp-bin/under开头的任何内容/usr/local/lib/dapp-bin

在访问文件系统以搜索导入时,不以 ./ 或 ../ 开头的路径被视为相对于使用 --base-path--include-path选项指定的目录(如果未指定基本路径,则为当前工作目录)。此外,通过这些选项添加的路径部分不会出现在合约元数据中。

出于安全原因,编译器对其可以访问的目录有限制。在命令行上指定的源文件目录和重新映射的目标路径自动允许文件阅读器访问,但默认情况下会拒绝其他所有内容。可以通过开关允许其他路径(及其子目录) 。始终允许通过指定路径内的所有内容。--allow-paths /sample/path,/another/sample/path--base-path

以上只是对编译器如何处理导入路径的简化。有关极端情况的示例和讨论的详细说明,请参阅 路径解析部分。

图书馆链接

如果您的合同使用,您会注意到字节码包含表单的子字符串__$53aea86b7d70b31448b230b20ae141a537$__。这些是实际图书馆地址的占位符。占位符是完全限定库名称的 keccak256 散列的十六进制编码的 34 个字符前缀。字节码文件最后还将包含表单行,以帮助识别占位符代表哪些库。请注意,完全限定的库名称是其源文件的路径,库名称由. 您可以用作链接器,这意味着它将在这些点为您插入库地址:// <placeholder> -> <fq library name>:solc

添加到您的命令以提供每个库的地址(使用逗号或空格作为分隔符)或将字符串存储在文件中(每行一个库)并使用.--libraries "file.sol:Math=0x1234567890123456789012345678901234567890 file.sol:Heap=0xabCD567890123456789012345678901234567890"solc--libraries fileName

笔记
从 Solidity 0.8.1 开始接受=库和地址之间:的分隔符,并且不推荐使用分隔符。将来会被删除。目前也可以。--libraries "file.sol:Math:0x1234567890123456789012345678901234567890 file.sol:Heap:0xabCD567890123456789012345678901234567890"

如果solc使用 option 调用--standard-json,它将期望标准输入上的 JSON 输入(如下所述),并在标准输出上返回 JSON 输出。对于更复杂且特别是自动化的使用,这是推荐的界面。该过程将始终以“成功”状态终止,并通过 JSON 输出报告任何错误。该选项--base-path也在标准 json 模式下处理。

如果solc使用 option 调用--link,所有输入文件都被解释为上面给出的 -format 中未链接的二进制文件(十六进制编码)__$53aea86b7d70b31448b230b20ae141a537$__并就地链接(如果从 stdin 读取输入,则将其写入 stdout)。在这种情况下,除 之外的所有选项都--libraries将被忽略(包括-o)。

警告
不鼓励在生成的字节码上手动链接库,因为它不会更新合约元数据。由于元数据包含编译时指定的库列表,而字节码包含元数据哈希,因此您将获得不同的二进制文件,具体取决于执行链接的时间。
如果您使用编译器的标准 JSON 接口,您应该要求编译器在编译合约时使用--libraries选项solc或密钥来链接库。libraries
笔记
库占位符曾经是库本身的完全限定名称,而不是它的哈希。仍然支持这种格式,但编译器将不再输出它。进行此更改是为了减少库之间发生冲突的可能性,因为只能使用完全限定库名称的前 36 个字符。solc --link