使用編譯器

翻譯原文

date:20170728

使用命令行編譯器

Solidity代碼庫(kù)的構(gòu)建對(duì)象之一是solc,Solidity的命令行編譯器。使用solc --help可以解釋所有參數(shù)。編譯器可以生成不同的輸出,范圍從簡(jiǎn)單的二進(jìn)制和匯編一個(gè)抽象語(yǔ)法樹(shù)(解析樹(shù))到預(yù)估gas的用量。如果你只想要編譯單個(gè)文件,你只是想編譯單個(gè)文件,使用命令solc --bin sourceFile.sol可以生成二進(jìn)制。在你發(fā)布代碼之前,如果想要在編譯的時(shí)候使用優(yōu)化器,可以使用命令solc --optimize --bin sourceFile.sol。如果你想要獲取solc的一些更加高級(jí)的輸出變量,你可以讓它輸出所有的信息到一個(gè)單獨(dú)的文件中,使用命令solc -o outputDirectory --bin --ast --asm sourceFile.sol。
命令行編譯器會(huì)自動(dòng)的從文件系統(tǒng)中導(dǎo)入文件,但是可能通過(guò)如下的方式,使用prefix=path來(lái)重定向:

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

這條代碼本質(zhì)上是讓編譯器在/usr/local/lib/dapp-bin中查找所有github.com/ethereum/dapp-bin/開(kāi)頭的文件。如果沒(méi)有找到文件,會(huì)在/usr/lcoal/lib/fallback目錄里查找(空白的前綴總是會(huì)匹配)。solc不會(huì)在除了制定路徑外的其他路徑中查找文件,所以像import "/etc/passwd";只會(huì)在你添加了=/映射之后才會(huì)有效。

如果由于映射,會(huì)有多個(gè)匹配,那么會(huì)選擇最多匹配的前綴。

由于安全問(wèn)題,編譯器會(huì)限制可訪問(wèn)的路徑。源碼的路徑(和子路徑)在命令行中指定,并且重定向定義的路徑允許聲明導(dǎo)入。但是其他會(huì)被拒絕。另外的路徑(和子路徑)可以通過(guò)--allow-paths /sample/path,/another/sample/path來(lái)切換。

如果你的合約使用到了庫(kù),你會(huì)發(fā)現(xiàn)字節(jié)碼中包含__LibraryName______形式的字符串。你可以使用solc作為連接器,會(huì)在這些地方插入庫(kù)的地址。

或者在命令行中添加--libraries "Math:0x12345678901234567890 Heap:0xabcdef0123456"參數(shù)來(lái)為每個(gè)庫(kù)提供地址或者把他們保存在一個(gè)文件(一個(gè)庫(kù)一行)里,然后運(yùn)行solc,使用--libraries fileName參數(shù)。

如果solc命令中有--link參數(shù),所有的輸入文件都會(huì)當(dāng)做是沒(méi)有連接的庫(kù)(十六進(jìn)制編碼),在以上述的__LibraryName____處連接(如果輸入從stdin讀取,它會(huì)寫到stdout中)。這種情況下,所有參數(shù),除了--libraries都會(huì)被忽略(包含-o)。

如果solc命令中有--standard-json,它會(huì)在標(biāo)準(zhǔn)輸入中接收J(rèn)SON輸入(會(huì)在下文敘述),并且在標(biāo)準(zhǔn)輸出中返回JSON輸出。

編譯輸入和輸出的JSON描述

這些JSON格式會(huì)被用作編譯器的api,也可以通過(guò)solc使用。這些可能會(huì)有更改,有些字段是可選的(已經(jīng)說(shuō)過(guò)了)。但是只會(huì)做一些后向兼容的更改。

編譯器API期望JSON格式的輸入并輸出JSON格式的編譯結(jié)果。

當(dāng)然,注釋是不允許的,這里只是為了說(shuō)明情況。

輸入描述
{
  // 必須字段:源碼語(yǔ)言,可以是"Solidity", "serpent", "lll", "assembly", 等等
  language: "Solidity",
  // 必須字段
  sources:
  {
    // 鍵是源文件的“全局”名稱。
    // imports可以使用其他重定向的文件(看下文)
    "myFile.sol":
    {
      // 可選的參數(shù): 源文件的keccak256 hash值
      // 如果它被導(dǎo)入,它會(huì)被用來(lái)驗(yàn)證獲得的內(nèi)容。 
      "keccak256": "0x123...",
      // 必須字段(除非使用了“content”字段,看下文): 源文件的URL(s)
      // URL(s) 應(yīng)該按順序?qū)?,并且結(jié)果要進(jìn)行keccak256驗(yàn)證。如果hash值不匹配,或者不能正確加載URL(s),就會(huì)產(chǎn)生一個(gè)錯(cuò)誤。
      "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:
  {
    // 可選字段: 排過(guò)序的重定向
    remappings: [ ":g/dir" ],
    // 可選字段: 優(yōu)化器設(shè)置(enabled默認(rèn)為false)
    optimizer: {
      enabled: true,
      runs: 500
    },
    // 元數(shù)據(jù)設(shè)置 (可選的)
    metadata: {
      // 只能使用字面量?jī)?nèi)容,并且不能有URLs(默認(rèn)不支持)。
      useLiteralContent: true
    },
    // 庫(kù)的地址。如果這里沒(méi)有給出所有的庫(kù),這會(huì)導(dǎo)致生成沒(méi)有連接的對(duì)象,這些對(duì)象的輸出是不同的。
    libraries: {
      // 最上層的鍵是所需庫(kù)的源文件的名稱。
      // 如果使用了重定向,這些源文件會(huì)在映射作用之后匹配全局路徑。
      // 如果鍵是空字符串,他會(huì)被引用到全局層級(jí)。
      "myFile.sol": {
        "MyLib": "0x123123..."
      }
    }
    // 下面的參數(shù)可以用來(lái)指定期望的輸出。
    // 如果沒(méi)有這個(gè)字段,編譯器會(huì)載入并做類型檢測(cè),但是不會(huì)生成其他輸出。除非出現(xiàn)錯(cuò)誤。
    // 第一層的鍵是文件的名稱,第二層是合約的名稱,如果合約的名稱為空,會(huì)引用文件的名稱。
    // 星號(hào)代表著所有合約
    //
    // 有效的輸出類型如下所示:
    //   abi - ABI
    //   ast - 所有源文件的AST
    //   legacyAST - 所有源文件的legacy AST 
    //   devdoc - 開(kāi)發(fā)文檔 (natspec)
    //   userdoc - 用戶手冊(cè) (natspec)
    //   metadata - 元素?fù)?jù)
    //   ir - 在去語(yǔ)法糖之前的新匯編形式 
    //   evm.assembly - 在去語(yǔ)法糖之后的新匯編形式 
    //   evm.legacyAssembly - JSON格式的舊類型的匯編形式
    //   evm.bytecode.object - 字節(jié)碼對(duì)象
    //   evm.bytecode.opcodes - 操作碼列表
    //   evm.bytecode.sourceMap - 源碼映射(調(diào)試很有用)
    //   evm.bytecode.linkReferences - 引用連接 (如果是沒(méi)有連接的對(duì)象)
    //   evm.deployedBytecode* - 發(fā)布字節(jié)碼 (和evm.bytecode有相同的選項(xiàng))
    //   evm.methodIdentifiers - 函數(shù)列表的hash
    //   evm.gasEstimates - gas估計(jì)函數(shù)
    //   ewasm.wast - eWASM S-表達(dá)式 格式 (不支持 atm)
    //   ewasm.wasm - eWASM 二進(jìn)制格式 (不支持 atm)
    //
    // 注意使用 `evm`, `evm.bytecode`, `ewasm`, 等. 會(huì)選擇輸出的每個(gè)目標(biāo)部分
    //
    outputSelection: {
      // 使能每個(gè)簡(jiǎn)單合約的元數(shù)據(jù)和字節(jié)碼
      "*": {
        "*": [ "metadata", "evm.bytecode" ]
      },
      // 對(duì)文件def,使能 MyContract合約的abi和操作碼輸出。
      "def": {
        "MyContract": [ "abi", "evm.opcodes" ]
      },
      // 使能每個(gè)合約的源映射
      "*": {
        "*": [ "evm.sourceMap" ]
      },
      // 使能每個(gè)文件的legacyAST輸出
      "*": {
        "": [ "legacyAST" ]
      }
    }
  }
}
輸出描述
{
  // 可選字段:如果沒(méi)有錯(cuò)誤或者警告,就不會(huì)生成這個(gè)字段。
  errors: [
    {
      // 可選字段:源文件的位置
      sourceLocation: {
        file: "sourceFile.sol",
        start: 0,
        end: 100
      ],
      // 強(qiáng)制的: 錯(cuò)誤類型,如"TypeError", "InternalCompilerError", "Exception", 等
      type: "TypeError",
      // 強(qiáng)制的: 發(fā)生錯(cuò)誤的組件,如"general", "ewasm", 等
      component: "general",
      // 強(qiáng)制的 ("error" 或者 "warning")
      severity: "error",
      // 強(qiáng)制的
      message: "Invalid keyword"
      // 可選的: 格式化的信息,說(shuō)明出錯(cuò)的源碼位置。
      formattedMessage: "sourceFile.sol:100: Invalid keyword"
    }
  ],
  // 這包含文件層級(jí)的輸出,它通過(guò) outputSelection 設(shè)置來(lái)限制或者過(guò)濾。
  sources: {
    "sourceFile.sol": {
      // 標(biāo)識(shí)符 (用于源碼映射)
      id: 1,
      // AST 對(duì)象
      ast: {},
      // legacy AST 對(duì)象
      legacyAST: {}
    }
  },
  // 這里包含合約層級(jí)的輸出??梢酝ㄟ^(guò) outputSelection 設(shè)置來(lái)限制或者過(guò)濾.
  contracts: {
    "sourceFile.sol": {
      // 如果語(yǔ)言沒(méi)有合約名稱,這個(gè)字段像是空字段。
      "ContractName": {
        // 以太坊合約 ABI. 如果為空,會(huì)呈現(xiàn)為空數(shù)組。
        // 詳情查看 https://github.com/ethereum/wiki/wiki/Ethereum-Contract-ABI
        abi: [],
        // 查看輸出文檔的元數(shù)據(jù) (JSON 字符串連載)
        metadata: "{...}",
        // 用戶手冊(cè) (natspec)
        userdoc: {},
        // 開(kāi)發(fā)文檔 (natspec)
        devdoc: {},
        // 中間件(字符串)
        ir: "",
        // EVM-相關(guān)輸出
        evm: {
          // 匯編 (字符串)
          assembly: "",
          // 舊格式匯編 (對(duì)象)
          legacyAssembly: {},
          // 字節(jié)碼和相關(guān)詳情
          bytecode: {
            // 十六進(jìn)制字符串的字節(jié)碼
            object: "00fe",
            // 操作碼列表 (字符串)
            opcodes: "",
            // 字符串形式的源碼映射。查看源碼映射定義。
            sourceMap: "",
            // 如果給定這個(gè)字段,這是未連接的對(duì)象
            linkReferences: {
              "libraryFile.sol": {
                // 字節(jié)碼偏移。連接會(huì)在指定位置替換20字節(jié)
                Byte offsets into the bytecode. Linking replaces the 20 bytes located there.
                "Library1": [
                  { start: 0, length: 20 },
                  { start: 200, length: 20 }
                ]
              }
            }
          },
          // 和上面字段結(jié)構(gòu)相同
          deployedBytecode: { },
          // 函數(shù)列表的哈希
          methodIdentifiers: {
            "delegate(address)": "5c19a95c"
          },
          // 函數(shù) gas 估計(jì)
          gasEstimates: {
            creation: {
              codeDepositCost: "420000",
              executionCost: "infinite",
              totalCost: "infinite"
            },
            external: {
              "delegate(address)": "25000"
            },
            internal: {
              "heavyLifting()": "infinite"
            }
          }
        },
        // eWASM 相關(guān)的輸出
        ewasm: {
          // S-表達(dá)式 格式
          wast: "",
          // 二進(jìn)制格式 (十六進(jìn)制字符串)
          wasm: ""
        }
      }
    }
  }
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Spring Cloud為開(kāi)發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見(jiàn)模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,506評(píng)論 19 139
  • Ubuntu的發(fā)音 Ubuntu,源于非洲祖魯人和科薩人的語(yǔ)言,發(fā)作 oo-boon-too 的音。了解發(fā)音是有意...
    螢火蟲(chóng)de夢(mèng)閱讀 100,585評(píng)論 9 468
  • Spring Boot 參考指南 介紹 轉(zhuǎn)載自:https://www.gitbook.com/book/qbgb...
    毛宇鵬閱讀 47,253評(píng)論 6 342
  • linux資料總章2.1 1.0寫的不好抱歉 但是2.0已經(jīng)改了很多 但是錯(cuò)誤還是無(wú)法避免 以后資料會(huì)慢慢更新 大...
    數(shù)據(jù)革命閱讀 13,174評(píng)論 2 33
  • 我要跟大家坦白一件事,作為一名健康心理學(xué)家,我的職責(zé)就是讓大家過(guò)上快樂(lè)和健康的生活,但我突然發(fā)現(xiàn),過(guò)去十年來(lái),我一...
    拾玥的十月閱讀 332評(píng)論 0 0

友情鏈接更多精彩內(nèi)容