写在前面:HiBlock区块链社区成立了翻译小组,翻译区块链相关的技术文档及资料,本文为Solidity文档翻译的第八部分《使用编译器》,特发布出来邀请solidity爱好者、开发者作公开的审校,您能够添加微信baobaotalk_com,验证输入“solidity”,而后将您的意见和建议发送给咱们,也能够在文末“留言”区留言,有效的建议咱们会采纳及合并进下一版本,同时将送一份小礼物给您以示感谢。git
solc 是 Solidity 源码库的构建目标之一,它是 Solidity 的命令行编译器。你可以使用 solc --help命令来查看它的全部选项的解释。该编译器能够生成各类输出,范围从简单的二进制文件、汇编文件到用于估计“gas”使用状况的抽象语法树(解析树)。若是你只想编译一个文件,你能够运行 solc --bin sourceFile.sol 来生成二进制文件。若是你想经过 solc 得到一些更高级的输出信息,能够经过 solc -o outputDirectory --bin --ast --asm sourceFile.sol 命令将全部的输出都保存到一个单独的文件夹中。github
Before you deploy your contract, activate the optimizer while compiling using solc --optimize --bin sourceFile.sol. By default, the optimizer will optimize the contract for 200 runs. If you want to optimize for initial contract deployment and get the smallest output, set it to --runs=1. If you expect many transactions and don't care for higher deployment cost and output size, set --runs to a high number.express
命令行编译器会自动从文件系统中读取并导入的文件,但同时,它也支持经过 prefix=path 选项将路径重定向。好比:json
这实质上是告诉编译器去搜索 /usr/local/lib/dapp-bin 目录下的全部以 github.com/ethereum/dapp-bin/ 开头的文件,若是编译器找不到这样的文件,它会接着读取 /usr/local/lib/fallback 目录下的全部文件(空前缀意味着始终匹配)。solc 不会从位于重定向目标以外和显式指定的源文件所在目录以外的文件系统读取文件,因此,相似 import "/etc/passwd"; 这样的语句,编译器只会在你添加了 =/ 选项以后,才会尝试到根目录下加载 /etc/passwd 文件。数组
若是重定向路径下存在多个匹配,则选择具备最长公共前缀的那个匹配。安全
出于安全缘由,编译器限制了它能够访问的目录。在命令行中指定的源文件的路径(及其子目录)和经过重定向定义的路径可用于 import 语句,其余的则会被拒绝。额外路径(及其子目录)能够经过 --allow-paths /sample/path,/another/sample/path 进行配置。微信
若是您的合约使用 libraries ,您会注意到在编译后的十六进制字节码中会包含形如 LibraryName__ 的字符串。当您将 solc 做为连接器使用时,它会在下列状况中为你插入库的地址:要么在命令行中添加 --libraries "Math:0x12345678901234567890 Heap:0xabcdef0123456" 来为每一个库提供地址,或者将这些字符串保存到一个文件中(每行一个库),并使用 --libraries fileName 参数。app
若是在调用 solc 命令时使用了 --link 选项,则全部的输入文件会被解析为上面提到过的__LibraryName____ 格式的未连接的二进制数据(十六进制编码),而且就地连接。(若是输入是从stdin读取的,则生成的数据会被写入stdout)。在这种状况下,除了 --libraries 外的其余选项(包括 -o )都会被忽略。函数
若是在调用 solc 命令时使用了 --standard-json 选项,它将会按JSON格式解析标准输入上的输入,并在标准输出上返回JSON格式的输出。布局
下面展现的这些JSON格式是编译器API使用的,固然,在 solc 上也是可用的。有些字段是可选的(参见注释),而且它们可能会发生变化,但全部的变化都应该是后向兼容的。
编译器API须要JSON格式的输入,并以JSON格式输出编译结果。
注释是不容许的,这里仅用于解释目的。
输入说明
{ // 必选: 源代码语言,好比“Solidity”,“serpent”,“lll”,“assembly”等 language: "Solidity", // 必选 sources: { // 这里的键值是源文件的“全局”名称,能够经过remappings引入其余文件(参考下文) "myFile.sol": { // 可选: 源文件的kaccak256哈希值,可用于校验经过URL加载的内容。 "keccak256": "0x123...", // 必选(除非声明了 "content" 字段): 指向源文件的URL。 // URL(s) 会按顺序加载,而且结果会经过keccak256哈希值进行检查(若是有keccak256的话) // 若是哈希值不匹配,或者没有URL返回成功,则抛出一个异常。 "urls": [ "bzzr://56ab...", "ipfs://Qma...", "file:///tmp/path/to/file.sol" ] }, "mortal": { // 可选: 该文件的keccak256哈希值 "keccak256": "0x234...", // 必选(除非声明了 "urls" 字段): 源文件的字面内容 "content": "contract mortal is owned { function kill() { if (msg.sender == owner) selfdestruct(owner); } }" } }, // 可选 settings: { // 可选: 重定向参数的排序列表 remappings: [ ":g/dir" ], // 可选: 优化器配置 optimizer: { // 默认为 disabled enabled: true, // 基于你但愿运行多少次代码来进行优化。 // 较小的值可使初始部署的费用获得更多优化,较大的值可使高频率的使用获得优化。 runs: 200 }, // 指定需编译的EVM的版本。会影响代码的生成和类型检查。可用的版本为:homestead,tangerineWhistle,spuriousDragon,byzantium,constantinople evmVersion: "byzantium", // 可选: 元数据配置 metadata: { // 只可以使用字面内容,不可用URLs (默认设为 false) useLiteralContent: true }, // 库的地址。若是这里没有把全部须要的库都给出,会致使生成输出数据不一样的未连接对象 libraries: { // 最外层的 key 是使用这些库的源文件的名字。 // 若是使用了重定向, 在重定向以后,这些源文件应该能匹配全局路径 // 若是源文件的名字为空,则全部的库为全局引用 "myFile.sol": { "MyLib": "0x123123..." } } // 如下内容能够用于选择所需的输出。 // 若是这个字段被忽略,那么编译器会加载并进行类型检查,但除了错误以外不会产生任何输出。 // 第一级的key是文件名,第二级是合约名称,若是合约名为空,则针对文件自己(进行输出)。 // 若使用通配符*,则表示全部合约。 // // 可用的输出类型以下所示: // abi - ABI // ast - 全部源文件的AST // legacyAST - 全部源文件的legacy AST // devdoc - 开发者文档(natspec) // userdoc - 用户文档(natspec) // metadata - 元数据 // ir - 去除语法糖(desugaring)以前的新汇编格式 // evm.assembly - 去除语法糖(desugaring)以后的新汇编格式 // evm.legacyAssembly - JSON的旧样式汇编格式 // evm.bytecode.object - 字节码对象 // evm.bytecode.opcodes - 操做码列表 // evm.bytecode.sourceMap - 源码映射(用于调试) // evm.bytecode.linkReferences - 连接引用(若是是未连接的对象) // evm.deployedBytecode* - 部署的字节码(与evm.bytecode具备相同的选项) // evm.methodIdentifiers - 函数哈希值列表 // evm.gasEstimates - 函数的gas预估量 // ewasm.wast - eWASM S-expressions 格式(不支持atm) // ewasm.wasm - eWASM二进制格式(不支持atm) // // 请注意,若是使用 `evm` ,`evm.bytecode` ,`ewasm` 等选项,会选择其全部的子项做为输出。 另外,`*`能够用做通配符来请求全部内容。 // outputSelection: { // 为每一个合约生成元数据和字节码输出。 "*": { "*": [ "metadata","evm.bytecode" ] }, // 启用“def”文件中定义的“MyContract”合约的abi和opcodes输出。 "def": { "MyContract": [ "abi","evm.bytecode.opcodes" ] }, // 为每一个合约生成源码映射输出 "*": { "*": [ "evm.bytecode.sourceMap" ] }, // 每一个文件生成legacy AST输出 "*": { "": [ "legacyAST" ] } } } }
输出说明
{ // 可选:若是没有遇到错误/警告,则不出现 errors: [ { // 可选:源文件中的位置 sourceLocation: { file: "sourceFile.sol", start: 0, end: 100 ], // 强制: 错误类型,例如 “TypeError”, “InternalCompilerError”, “Exception”等. // 可在文末查看完整的错误类型列表 type: "TypeError", // 强制: 发生错误的组件,例如“general”,“ewasm”等 component: "general", // 强制:错误的严重级别(“error”或“warning”) severity: "error", // 强制 message: "Invalid keyword" // 可选: 带错误源位置的格式化消息 formattedMessage: "sourceFile.sol:100: Invalid keyword" } ], // 这里包含了文件级别的输出。能够经过outputSelection来设置限制/过滤。 sources: { "sourceFile.sol": { // 标识符(用于源码映射) id: 1, // AST对象 ast: {}, // legacy AST 对象 legacyAST: {} } }, // 这里包含了合约级别的输出。 能够经过outputSelection来设置限制/过滤。 contracts: { "sourceFile.sol": { // 若是使用的语言没有合约名称,则该字段应该留空。 "ContractName": { // 以太坊合约的应用二进制接口(ABI)。若是为空,则表示为空数组。 // 请参阅 https://github.com/ethereum/wiki/wiki/Ethereum-Contract-ABI abi: [], // 请参阅元数据输出文档(序列化的JSON字符串) metadata: "{...}", // 用户文档(natspec) userdoc: {}, // 开发人员文档(natspec) devdoc: {}, // 中间表示形式 (string) ir: "", // EVM相关输出 evm: { // 汇编 (string) assembly: "", // 旧风格的汇编 (object) legacyAssembly: {}, // 字节码和相关细节 bytecode: { // 十六进制字符串的字节码 object: "00fe", // 操做码列表 (string) opcodes: "", // 源码映射的字符串。 请参阅源码映射的定义 sourceMap: "", // 若是这里给出了信息,则表示这是一个未连接的对象 linkReferences: { "libraryFile.sol": { // 字节码中的字节偏移;连接时,从指定的位置替换20个字节 "Library1": [ { start: 0,length: 20 }, { start: 200,length: 20 } ] } } }, // 与上面相同的布局 deployedBytecode: { }, // 函数哈希的列表 methodIdentifiers: { "delegate(address)": "5c19a95c" }, // 函数的gas预估量 gasEstimates: { creation: { codeDepositCost: "420000", executionCost: "infinite", totalCost: "infinite" }, external: { "delegate(address)": "25000" }, internal: { "heavyLifting()": "infinite" } } }, // eWASM相关的输出 ewasm: { // S-expressions格式 wast: "", // 二进制格式(十六进制字符串) wasm: "" } } } } }
错误类型
JSONError: JSON输入不符合所需格式,例如,输入不是JSON对象,不支持的语言等。
IOError: IO和导入处理错误,例如,在提供的源里包含没法解析的URL或哈希值不匹配。
ParserError: 源代码不符合语言规则。
DocstringParsingError: 注释块中的NatSpec标签没法解析。
SyntaxError: 语法错误,例如 continue 在 for 循环外部使用。
DeclarationError:无效的,没法解析的或冲突的标识符名称 好比 Identifier not found。
TypeError: 类型系统内的错误,例如无效类型转换,无效赋值等。
UnimplementedFeatureError: 编译器当前不支持该功能,但预计将在将来的版本中支持。
InternalCompilerError: 在编译器中触发的内部错误——应将此报告为一个issue。
Exception: 编译期间的未知失败——应将此报告为一个issue。
CompilerError: 编译器堆栈的无效使用——应将此报告为一个issue。
FatalError: 未正确处理致命错误——应将此报告为一个issue。
Warning: 警告,不会中止编译,但应尽量处理。
延伸阅读:智能合约-Solidity官方文档(1)
根据例子学习Solidity-Solidity官方文档(3)
深刻理解Solidity之源文件及合约结构——Solidity中文文档(4)
应用二进制接口(ABI) 说明——Solidity中文文档(7)
点击“阅读原文”便可查看完整中文文档
注:本文为solidity翻译的第八部分《使用编译器》,特发布出来邀请solidity爱好者、开发者作公开的审校,您能够添加微信baobaotalk_com,验证输入“solidity”,而后将您的意见和建议发送给咱们,也可在文末“留言”区留言,或经过原文连接访问咱们的Github。有效的建议咱们会收纳并及时改进,同时将送一份小礼物给您以示感谢。
本文内容来源于HiBlock区块链社区翻译小组,感谢全体译者的辛苦工做。点击“阅读原文”便可查看完整中文文档。
**线上课程推荐 **
线上课程:《8小时区块链智能合约开发实践》
培训讲师:《白话区块链》做者 蒋勇
课程原价:999元,现价 399元
更多福利:
点击“阅读原文”便可查看完整中文文档