使用编译器

翻译原文

date:20170728

使用命令行编译器

Solidity代码库的构建对象之一是solc,Solidity的命令行编译器。使用solc --help可以解释所有参数。编译器可以生成不同的输出,范围从简单的二进制和汇编一个抽象语法树(解析树)到预估gas的用量。如果你只想要编译单个文件,你只是想编译单个文件,使用命令solc --bin sourceFile.sol可以生成二进制。在你发布代码之前,如果想要在编译的时候使用优化器,可以使用命令solc --optimize --bin sourceFile.sol。如果你想要获取solc的一些更加高级的输出变量,你可以让它输出所有的信息到一个单独的文件中,使用命令solc -o outputDirectory --bin --ast --asm sourceFile.sol
命令行编译器会自动的从文件系统中导入文件,但是可能通过如下的方式,使用prefix=path来重定向:

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

这条代码本质上是让编译器在/usr/local/lib/dapp-bin中查找所有github.com/ethereum/dapp-bin/开头的文件。如果没有找到文件,会在/usr/lcoal/lib/fallback目录里查找(空白的前缀总是会匹配)。solc不会在除了制定路径外的其他路径中查找文件,所以像import "/etc/passwd";只会在你添加了=/映射之后才会有效。

如果由于映射,会有多个匹配,那么会选择最多匹配的前缀。

由于安全问题,编译器会限制可访问的路径。源码的路径(和子路径)在命令行中指定,并且重定向定义的路径允许声明导入。但是其他会被拒绝。另外的路径(和子路径)可以通过--allow-paths /sample/path,/another/sample/path来切换。

如果你的合约使用到了,你会发现字节码中包含__LibraryName______形式的字符串。你可以使用solc作为连接器,会在这些地方插入库的地址。

或者在命令行中添加--libraries "Math:0x12345678901234567890 Heap:0xabcdef0123456"参数来为每个库提供地址或者把他们保存在一个文件(一个库一行)里,然后运行solc,使用--libraries fileName参数。

如果solc命令中有--link参数,所有的输入文件都会当做是没有连接的库(十六进制编码),在以上述的__LibraryName____处连接(如果输入从stdin读取,它会写到stdout中)。这种情况下,所有参数,除了--libraries都会被忽略(包含-o)。

如果solc命令中有--standard-json,它会在标准输入中接收JSON输入(会在下文叙述),并且在标准输出中返回JSON输出。

编译输入和输出的JSON描述

这些JSON格式会被用作编译器的api,也可以通过solc使用。这些可能会有更改,有些字段是可选的(已经说过了)。但是只会做一些后向兼容的更改。

编译器API期望JSON格式的输入并输出JSON格式的编译结果。

当然,注释是不允许的,这里只是为了说明情况。

输入描述
{
  // 必须字段:源码语言,可以是"Solidity", "serpent", "lll", "assembly", 等等
  language: "Solidity",
  // 必须字段
  sources:
  {
    // 键是源文件的“全局”名称。
    // imports可以使用其他重定向的文件(看下文)
    "myFile.sol":
    {
      // 可选的参数: 源文件的keccak256 hash值
      // 如果它被导入,它会被用来验证获得的内容。 
      "keccak256": "0x123...",
      // 必须字段(除非使用了“content”字段,看下文): 源文件的URL(s)
      // URL(s) 应该按顺序导入,并且结果要进行keccak256验证。如果hash值不匹配,或者不能正确加载URL(s),就会产生一个错误。
      "urls":
      [
        "bzzr://56ab...",
        "ipfs://Qma...",
        "file:///tmp/path/to/file.sol"
      ]
    },
    "mortal":
    {
      // 可选字段:源文件的keccak256 hash值
      Optional: keccak256 hash of the source file
      "keccak256": "0x234...",
      // 必须字段(除非“urls”字段被使用): 源文件的字面量信息
      "content": "contract mortal is owned { function kill() { if (msg.sender == owner) selfdestruct(owner); } }"
    }
  },
  // 可选字段
  settings:
  {
    // 可选字段: 排过序的重定向
    remappings: [ ":g/dir" ],
    // 可选字段: 优化器设置(enabled默认为false)
    optimizer: {
      enabled: true,
      runs: 500
    },
    // 元数据设置 (可选的)
    metadata: {
      // 只能使用字面量内容,并且不能有URLs(默认不支持)。
      useLiteralContent: true
    },
    // 库的地址。如果这里没有给出所有的库,这会导致生成没有连接的对象,这些对象的输出是不同的。
    libraries: {
      // 最上层的键是所需库的源文件的名称。
      // 如果使用了重定向,这些源文件会在映射作用之后匹配全局路径。
      // 如果键是空字符串,他会被引用到全局层级。
      "myFile.sol": {
        "MyLib": "0x123123..."
      }
    }
    // 下面的参数可以用来指定期望的输出。
    // 如果没有这个字段,编译器会载入并做类型检测,但是不会生成其他输出。除非出现错误。
    // 第一层的键是文件的名称,第二层是合约的名称,如果合约的名称为空,会引用文件的名称。
    // 星号代表着所有合约
    //
    // 有效的输出类型如下所示:
    //   abi - ABI
    //   ast - 所有源文件的AST
    //   legacyAST - 所有源文件的legacy AST 
    //   devdoc - 开发文档 (natspec)
    //   userdoc - 用户手册 (natspec)
    //   metadata - 元素据
    //   ir - 在去语法糖之前的新汇编形式 
    //   evm.assembly - 在去语法糖之后的新汇编形式 
    //   evm.legacyAssembly - JSON格式的旧类型的汇编形式
    //   evm.bytecode.object - 字节码对象
    //   evm.bytecode.opcodes - 操作码列表
    //   evm.bytecode.sourceMap - 源码映射(调试很有用)
    //   evm.bytecode.linkReferences - 引用连接 (如果是没有连接的对象)
    //   evm.deployedBytecode* - 发布字节码 (和evm.bytecode有相同的选项)
    //   evm.methodIdentifiers - 函数列表的hash
    //   evm.gasEstimates - gas估计函数
    //   ewasm.wast - eWASM S-表达式 格式 (不支持 atm)
    //   ewasm.wasm - eWASM 二进制格式 (不支持 atm)
    //
    // 注意使用 `evm`, `evm.bytecode`, `ewasm`, 等. 会选择输出的每个目标部分
    //
    outputSelection: {
      // 使能每个简单合约的元数据和字节码
      "*": {
        "*": [ "metadata", "evm.bytecode" ]
      },
      // 对文件def,使能 MyContract合约的abi和操作码输出。
      "def": {
        "MyContract": [ "abi", "evm.opcodes" ]
      },
      // 使能每个合约的源映射
      "*": {
        "*": [ "evm.sourceMap" ]
      },
      // 使能每个文件的legacyAST输出
      "*": {
        "": [ "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: {},
        // 中间件(字符串)
        ir: "",
        // EVM-相关输出
        evm: {
          // 汇编 (字符串)
          assembly: "",
          // 旧格式汇编 (对象)
          legacyAssembly: {},
          // 字节码和相关详情
          bytecode: {
            // 十六进制字符串的字节码
            object: "00fe",
            // 操作码列表 (字符串)
            opcodes: "",
            // 字符串形式的源码映射。查看源码映射定义。
            sourceMap: "",
            // 如果给定这个字段,这是未连接的对象
            linkReferences: {
              "libraryFile.sol": {
                // 字节码偏移。连接会在指定位置替换20字节
                Byte offsets into the bytecode. Linking replaces the 20 bytes located there.
                "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-表达式 格式
          wast: "",
          // 二进制格式 (十六进制字符串)
          wasm: ""
        }
      }
    }
  }
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,126评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,254评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,445评论 0 341
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,185评论 1 278
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,178评论 5 371
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,970评论 1 284
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,276评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,927评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,400评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,883评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,997评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,646评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,213评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,204评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,423评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,423评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,722评论 2 345

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,599评论 18 139
  • Ubuntu的发音 Ubuntu,源于非洲祖鲁人和科萨人的语言,发作 oo-boon-too 的音。了解发音是有意...
    萤火虫de梦阅读 99,156评论 9 467
  • Spring Boot 参考指南 介绍 转载自:https://www.gitbook.com/book/qbgb...
    毛宇鹏阅读 46,748评论 6 342
  • linux资料总章2.1 1.0写的不好抱歉 但是2.0已经改了很多 但是错误还是无法避免 以后资料会慢慢更新 大...
    数据革命阅读 12,134评论 2 34
  • 我要跟大家坦白一件事,作为一名健康心理学家,我的职责就是让大家过上快乐和健康的生活,但我突然发现,过去十年来,我一...
    拾玥的十月阅读 245评论 0 0