您好,登錄后才能下訂單哦!
本篇內容介紹了“Solidity中怎么使用編譯器”的有關知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領大家學習一下如何處理這些情況吧!希望大家仔細閱讀,能夠學有所成!
solc 是 Solidity 源碼庫的構建目標之一,它是 Solidity 的命令行編譯器。你可使用 solc --help命令來查看它的所有選項的解釋。該編譯器可以生成各種輸出,范圍從簡單的二進制文件、匯編文件到用于估計“gas”使用情況的抽象語法樹(解析樹)。如果你只想編譯一個文件,你可以運行 solc --bin sourceFile.sol 來生成二進制文件。如果你想通過 solc 獲得一些更高級的輸出信息,可以通過 solc -o outputDirectory --bin --ast --asm sourceFile.sol 命令將所有的輸出都保存到一個單獨的文件夾中。
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.
命令行編譯器會自動從文件系統中讀取并導入的文件,但同時,它也支持通過 prefix=path 選項將路徑重定向。比如:
這實質上是告訴編譯器去搜索 /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 參數。
如果在調用 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中怎么使用編譯器”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識可以關注億速云網站,小編將為大家輸出更多高質量的實用文章!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。