寫在前面: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元
更多福利:
點擊「閱讀原文」便可查看完整中文文檔