博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
如何通过solc编译solidity编写的以太坊智能合约
阅读量:5786 次
发布时间:2019-06-18

本文共 10150 字,大约阅读时间需要 33 分钟。

solc:solidity的编译器

solidity编写的以太坊智能合约可通过命令行编译工具solc来进行编译,成为以太坊虚拟机中的代码。solc编译后最终部署到链上形成我们所见到的各种智能合约。

作为一个solidity命令行编译工具,我们来看看官网都怎么说solc。

solc的安装很简单:

npm install -g solc//或者npm install -g solc-cli//或者sudo apt-get install solc复制代码

安装完成后我们来看,solc --help,solc --help命令显示所有的solc命令选项。编译器可以生成各种输出,比如最终的二进制合约文件、语法树的汇编或者需要预计的要花费的gas等。solc --bin sourceFile.sol,可以编译后输出一个名为sourceFile.sol的智能合约文件。如果你想从solc获得更丰富的一些输出变量,你可以使用solc -o outputDirectory --bin --ast --asm sourceFile.sol

你在部署之前可以用solc --optimize --bin sourceFile.sol优化一下。默认情况下solc编译器会帮你优化200次。你也可以设置 --runs=1,这样就按照最小化的方式进行编译,如果你希望多次交易不太在乎成本,那你可以设置成你想要的次数:)。

命令行编译器会自动读取需要导入的文件,也可以通过使用prefix = path来指定路径,例如:

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

这样编译器就会从指定目录github.com/ethereum/dapp-bin/下的/usr/local/lib/dapp-bin/目录开始搜索,如果没有找到文件,它将查看/usr/local/lib/fallback。solc将只读取你指定的这两个路径的,因此像import "/etc/passwd";必须要通过/=重新映射才起作用。如果有多个匹配,则选择具有最长公共前缀的进行匹配。

出于安全上的考虑,编译器限制了它可以访问的一些目录。在命令行中指定的源文件的路径(及其子目录)和命令行指定的路径外其他所有内容都会被拒绝。--allow-paths /sample/path,/another/sample/path来切换。

如果智能合约使用了,你会注意到字节码包含了__LibraryName______的子字符串。您可以使用solc作为链接器,这意味着它将在这些点为您插入库地址。

可以通过添加库--libraries "Math:0x12345678901234567890 Heap:0xabcdef0123456"到您的命令,以提供每个库的地址,或者使用文件中的说明字符串(每行一个库),并使用--libraries fileName运行solc。

如果用选项--link调用Solc,则所有输入文件都被解释为未链接的二进制文件(HEX编码),在上面给出的__LibraryName____格式中,将其链接到适当地址(如果从stdin读取输入,则将其写入stdout)。在这种情况下,除了库外,所有选项都被忽略(包括-o)。

如果用--standard-json调用SOLC,它就将标准的JSON输入(如下所述),并返回JSON输出。

#solc编译器输入输出JSON描述

这些JSON格式通过编译器API使用,可以通过SOLC获得。内容都是可以修改的,一些对象是可选的(如前所述),其目的是向后兼容。

编译器的API需要一个JSON格式的输入,然后以JSON格式输出编译结果。

注意不允许注释。下面示例中的注释,是官网为了学习者更好的理解标注的。

  • 输入格式说明:
{  // Required: Source code language, such as "Solidity", "serpent", "lll", "assembly", etc.  language: "Solidity",  // Required  sources:  {    // The keys here are the "global" names of the source files,    // imports can use other files via remappings (see below).    "myFile.sol":    {      // Optional: keccak256 hash of the source file      // It is used to verify the retrieved content if imported via URLs.      "keccak256": "0x123...",      // Required (unless "content" is used, see below): URL(s) to the source file.      // URL(s) should be imported in this order and the result checked against the      // keccak256 hash (if available). If the hash doesn't match or none of the      // URL(s) result in success, an error should be raised.      "urls":      [        "bzzr://56ab...",        "ipfs://Qma...",        "file:///tmp/path/to/file.sol"      ]    },    "mortal":    {      // Optional: keccak256 hash of the source file      "keccak256": "0x234...",      // Required (unless "urls" is used): literal contents of the source file      "content": "contract mortal is owned { function kill() { if (msg.sender == owner) selfdestruct(owner); } }"    }  },  // Optional  settings:  {    // Optional: Sorted list of remappings    remappings: [ ":g/dir" ],    // Optional: Optimizer settings    optimizer: {      // disabled by default      enabled: true,      // Optimize for how many times you intend to run the code.      // Lower values will optimize more for initial deployment cost, higher values will optimize more for high-frequency usage.      runs: 200    },    evmVersion: "byzantium", // Version of the EVM to compile for. Affects type checking and code generation. Can be homestead, tangerineWhistle, spuriousDragon, byzantium or constantinople    // Metadata settings (optional)    metadata: {      // Use only literal content and not URLs (false by default)      useLiteralContent: true    },    // Addresses of the libraries. If not all libraries are given here, it can result in unlinked objects whose output data is different.    libraries: {      // The top level key is the the name of the source file where the library is used.      // If remappings are used, this source file should match the global path after remappings were applied.      // If this key is an empty string, that refers to a global level.      "myFile.sol": {        "MyLib": "0x123123..."      }    }    // The following can be used to select desired outputs.    // If this field is omitted, then the compiler loads and does type checking, but will not generate any outputs apart from errors.    // The first level key is the file name and the second is the contract name, where empty contract name refers to the file itself,    // while the star refers to all of the contracts.    //    // The available output types are as follows:    //   abi - ABI    //   ast - AST of all source files    //   legacyAST - legacy AST of all source files    //   devdoc - Developer documentation (natspec)    //   userdoc - User documentation (natspec)    //   metadata - Metadata    //   ir - New assembly format before desugaring    //   evm.assembly - New assembly format after desugaring    //   evm.legacyAssembly - Old-style assembly format in JSON    //   evm.bytecode.object - Bytecode object    //   evm.bytecode.opcodes - Opcodes list    //   evm.bytecode.sourceMap - Source mapping (useful for debugging)    //   evm.bytecode.linkReferences - Link references (if unlinked object)    //   evm.deployedBytecode* - Deployed bytecode (has the same options as evm.bytecode)    //   evm.methodIdentifiers - The list of function hashes    //   evm.gasEstimates - Function gas estimates    //   ewasm.wast - eWASM S-expressions format (not supported atm)    //   ewasm.wasm - eWASM binary format (not supported atm)    //    // Note that using a using `evm`, `evm.bytecode`, `ewasm`, etc. will select every    // target part of that output. Additionally, `*` can be used as a wildcard to request everything.    //    outputSelection: {      // Enable the metadata and bytecode outputs of every single contract.      "*": {        "*": [ "metadata", "evm.bytecode" ]      },      // Enable the abi and opcodes output of MyContract defined in file def.      "def": {        "MyContract": [ "abi", "evm.bytecode.opcodes" ]      },      // Enable the source map output of every single contract.      "*": {        "*": [ "evm.bytecode.sourceMap" ]      },      // Enable the legacy AST output of every single file.      "*": {        "": [ "legacyAST" ]      }    }  }}复制代码
  • 输出格式说明
{  // Optional: not present if no errors/warnings were encountered  errors: [    {      // Optional: Location within the source file.      sourceLocation: {        file: "sourceFile.sol",        start: 0,        end: 100      ],      // Mandatory: Error type, such as "TypeError", "InternalCompilerError", "Exception", etc.      // See below for complete list of types.      type: "TypeError",      // Mandatory: Component where the error originated, such as "general", "ewasm", etc.      component: "general",      // Mandatory ("error" or "warning")      severity: "error",      // Mandatory      message: "Invalid keyword"      // Optional: the message formatted with source location      formattedMessage: "sourceFile.sol:100: Invalid keyword"    }  ],  // This contains the file-level outputs. In can be limited/filtered by the outputSelection settings.  sources: {    "sourceFile.sol": {      // Identifier (used in source maps)      id: 1,      // The AST object      ast: {},      // The legacy AST object      legacyAST: {}    }  },  // This contains the contract-level outputs. It can be limited/filtered by the outputSelection settings.  contracts: {    "sourceFile.sol": {      // If the language used has no contract names, this field should equal to an empty string.      "ContractName": {        // The Ethereum Contract ABI. If empty, it is represented as an empty array.        // See https://github.com/ethereum/wiki/wiki/Ethereum-Contract-ABI        abi: [],        // See the Metadata Output documentation (serialised JSON string)        metadata: "{...}",        // User documentation (natspec)        userdoc: {},        // Developer documentation (natspec)        devdoc: {},        // Intermediate representation (string)        ir: "",        // EVM-related outputs        evm: {          // Assembly (string)          assembly: "",          // Old-style assembly (object)          legacyAssembly: {},          // Bytecode and related details.          bytecode: {            // The bytecode as a hex string.            object: "00fe",            // Opcodes list (string)            opcodes: "",            // The source mapping as a string. See the source mapping definition.            sourceMap: "",            // If given, this is an unlinked object.            linkReferences: {              "libraryFile.sol": {                // Byte offsets into the bytecode. Linking replaces the 20 bytes located there.                "Library1": [                  { start: 0, length: 20 },                  { start: 200, length: 20 }                ]              }            }          },          // The same layout as above.          deployedBytecode: { },          // The list of function hashes          methodIdentifiers: {            "delegate(address)": "5c19a95c"          },          // Function gas estimates          gasEstimates: {            creation: {              codeDepositCost: "420000",              executionCost: "infinite",              totalCost: "infinite"            },            external: {              "delegate(address)": "25000"            },            internal: {              "heavyLifting()": "infinite"            }          }        },        // eWASM related outputs        ewasm: {          // S-expressions format          wast: "",          // Binary format (hex string)          wasm: ""        }      }    }  }}复制代码
  • 错误类型说明:
  1. JSONError:JSON错误,JSON输入不符合要求的格式,例如输入不是JSON对象,不支持语言,等等。
  2. IOError:IO错误,IO和导入处理错误,如提供的源中的不可解析URL或hash不匹配。
  3. ParserError:语法f分析错误,源代码不符合语言规则。
  4. DocstringParsingError:文档解析错误,无法解析注释块中的NATSPEC标记。
  5. SytRealError:语法错误,如continuefor循环之外使用。
  6. DeclarationError:声明错误,无效、不可解析或冲突的标识符名称。例如未找到标识符
  7. TypeError:类型错误,如无效类型转换、无效赋值等。
  8. UnimplementedFeatureError:编译器不支持该特性,但希望在将来的版本中得到支持。
  9. InternalCompilerError:编译器中触发内部错误,这应该作为一个问题来反馈。
  10. Exception:例外,编译过程中未知的故障,这应该作为一个问题反馈。
  11. CompilerError:编译错误,编译器堆栈的使用无效,这应该作为一个问题来反馈。
  12. FatalError:致命错误,这应该作为一个问题来反馈。
  13. Warning:警告并没有停止编译,但如果可能的话,应该加以处理。

原文请访问:

转载地址:http://autyx.baihongyu.com/

你可能感兴趣的文章
网络流24题 -No.18 分配问题
查看>>
mysql 5.7版本目录无data文件夹的解决办法
查看>>
源码分析 脱壳神器ZjDroid工作原理
查看>>
gcc与g++
查看>>
spring读取多个配置properties报错"Could not resolve placeholder"的解决方案
查看>>
SqlDataReader引起的超时?
查看>>
获得表中字段说明
查看>>
推荐系统-05-Spark电影推荐、评估与部署
查看>>
WCF入门(一)——基本知识
查看>>
MongoDb 快速入门教程
查看>>
java中的socket编程有关printStream的println方法和write方法
查看>>
Android图片设计问题
查看>>
【转】android中webview使用的一些细节
查看>>
Ionic 2 开发(一)_安装与目录结构
查看>>
获取select当前选择的值和文本
查看>>
Remove Duplicates from Sorted List
查看>>
51nod - 1136 欧拉函数(欧拉函数)
查看>>
Selenium2+python自动化3-解决pip使用异常
查看>>
php-超全局变量
查看>>
对大学的看法
查看>>