溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Solidity中怎么使用編譯器

發(fā)布時間:2021-12-07 15:34:00 來源:億速云 閱讀:107 作者:iii 欄目:互聯(lián)網(wǎng)科技

本篇內(nèi)容介紹了“Solidity中怎么使用編譯器”的有關知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領大家學習一下如何處理這些情況吧!希望大家仔細閱讀,能夠?qū)W有所成!

1

使用命令行編譯器

Solidity中怎么使用編譯器

solc 是 Solidity 源碼庫的構(gòu)建目標之一,它是 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.

命令行編譯器會自動從文件系統(tǒng)中讀取并導入的文件,但同時,它也支持通過 prefix=path 選項將路徑重定向。比如:

Solidity中怎么使用編譯器

這實質(zhì)上是告訴編譯器去搜索 /usr/local/lib/dapp-bin 目錄下的所有以 github.com/ethereum/dapp-bin/ 開頭的文件,如果編譯器找不到這樣的文件,它會接著讀取 /usr/local/lib/fallback 目錄下的所有文件(空前綴意味著始終匹配)。solc 不會從位于重定向目標之外和顯式指定的源文件所在目錄之外的文件系統(tǒng)讀取文件,所以,類似 import "/etc/passwd"; 這樣的語句,編譯器只會在你添加了 =/ 選項之后,才會嘗試到根目錄下加載 /etc/passwd 文件。

如果重定向路徑下存在多個匹配,則選擇具有最長公共前綴的那個匹配。

出于安全原因,編譯器限制了它可以訪問的目錄。在命令行中指定的源文件的路徑(及其子目錄)和通過重定向定義的路徑可用于 import 語句,其他的則會被拒絕。額外路徑(及其子目錄)可以通過 --allow-paths /sample/path,/another/sample/path 進行配置。

如果您的合約使用 libraries ,您會注意到在編譯后的十六進制字節(jié)碼中會包含形如 LibraryName__ 的字符串。當您將 solc 作為鏈接器使用時,它會在下列情況中為你插入庫的地址:要么在命令行中添加 --libraries "Math:0x12345678901234567890 Heap:0xabcdef0123456" 來為每個庫提供地址,或者將這些字符串保存到一個文件中(每行一個庫),并使用 --libraries fileName 參數(shù)。

如果在調(diào)用 solc 命令時使用了 --link 選項,則所有的輸入文件會被解析為上面提到過的__LibraryName____ 格式的未鏈接的二進制數(shù)據(jù)(十六進制編碼),并且就地鏈接。(如果輸入是從stdin讀取的,則生成的數(shù)據(jù)會被寫入stdout)。在這種情況下,除了 --libraries 外的其他選項(包括 -o )都會被忽略。

如果在調(diào)用 solc 命令時使用了 --standard-json 選項,它將會按JSON格式解析標準輸入上的輸入,并在標準輸出上返回JSON格式的輸出。

2

編譯器輸入輸出JSON描述

下面展示的這些JSON格式是編譯器API使用的,當然,在 solc 上也是可用的。有些字段是可選的(參見注釋),并且它們可能會發(fā)生變化,但所有的變化都應該是后向兼容的。

編譯器API需要JSON格式的輸入,并以JSON格式輸出編譯結(jié)果。

注釋是不允許的,這里僅用于解釋目的。

輸入說明

{
 // 必選: 源代碼語言,比如“Solidity”,“serpent”,“l(fā)ll”,“assembly”等
 language: "Solidity",
 // 必選
 sources:
 {
   // 這里的鍵值是源文件的“全局”名稱,可以通過remappings引入其他文件(參考下文)
   "myFile.sol":
   {
     // 可選: 源文件的kaccak256哈希值,可用于校驗通過URL加載的內(nèi)容。
     "keccak256": "0x123...",
     // 必選(除非聲明了 "content" 字段): 指向源文件的URL。
     // URL(s) 會按順序加載,并且結(jié)果會通過keccak256哈希值進行檢查(如果有keccak256的話)
     // 如果哈希值不匹配,或者沒有URL返回成功,則拋出一個異常。
     "urls":
     [
       "bzzr://56ab...",
       "ipfs://Qma...",
       "file:///tmp/path/to/file.sol"
     ]
   },
   "mortal":
   {
     // 可選: 該文件的keccak256哈希值
     "keccak256": "0x234...",
     // 必選(除非聲明了 "urls" 字段): 源文件的字面內(nèi)容
     "content": "contract mortal is owned { function kill() { if (msg.sender == owner) selfdestruct(owner); } }"
   }
 },
 // 可選
 settings:
 {
   // 可選: 重定向參數(shù)的排序列表
   remappings: [ ":g/dir" ],
   // 可選: 優(yōu)化器配置
   optimizer: {
     // 默認為 disabled
     enabled: true,
     // 基于你希望運行多少次代碼來進行優(yōu)化。
     // 較小的值可以使初始部署的費用得到更多優(yōu)化,較大的值可以使高頻率的使用得到優(yōu)化。
     runs: 200
   },
   // 指定需編譯的EVM的版本。會影響代碼的生成和類型檢查??捎玫陌姹緸椋篽omestead,tangerineWhistle,spuriousDragon,byzantium,constantinople
   evmVersion: "byzantium",
   // 可選: 元數(shù)據(jù)配置
   metadata: {
     // 只可使用字面內(nèi)容,不可用URLs (默認設為 false)
     useLiteralContent: true
   },
   // 庫的地址。如果這里沒有把所有需要的庫都給出,會導致生成輸出數(shù)據(jù)不同的未鏈接對象
   libraries: {
     // 最外層的 key 是使用這些庫的源文件的名字。
     // 如果使用了重定向, 在重定向之后,這些源文件應該能匹配全局路徑
     // 如果源文件的名字為空,則所有的庫為全局引用
     "myFile.sol": {
       "MyLib": "0x123123..."
     }
   }
   // 以下內(nèi)容可以用于選擇所需的輸出。
   // 如果這個字段被忽略,那么編譯器會加載并進行類型檢查,但除了錯誤之外不會產(chǎn)生任何輸出。
   // 第一級的key是文件名,第二級是合約名稱,如果合約名為空,則針對文件本身(進行輸出)。
   // 若使用通配符*,則表示所有合約。
   //
   // 可用的輸出類型如下所示:
   //   abi - ABI
   //   ast - 所有源文件的AST
   //   legacyAST - 所有源文件的legacy AST
   //   devdoc - 開發(fā)者文檔(natspec)
   //   userdoc - 用戶文檔(natspec)
   //   metadata - 元數(shù)據(jù)
   //   ir - 去除語法糖(desugaring)之前的新匯編格式
   //   evm.assembly - 去除語法糖(desugaring)之后的新匯編格式
   //   evm.legacyAssembly - JSON的舊樣式匯編格式
   //   evm.bytecode.object - 字節(jié)碼對象
   //   evm.bytecode.opcodes - 操作碼列表
   //   evm.bytecode.sourceMap - 源碼映射(用于調(diào)試)
   //   evm.bytecode.linkReferences - 鏈接引用(如果是未鏈接的對象)
   //   evm.deployedBytecode* - 部署的字節(jié)碼(與evm.bytecode具有相同的選項)
   //   evm.methodIdentifiers - 函數(shù)哈希值列表
   //   evm.gasEstimates - 函數(shù)的gas預估量
   //   ewasm.wast - eWASM S-expressions 格式(不支持atm)
   //   ewasm.wasm - eWASM二進制格式(不支持atm)
   //
   // 請注意,如果使用 `evm` ,`evm.bytecode` ,`ewasm` 等選項,會選擇其所有的子項作為輸出。 另外,`*`可以用作通配符來請求所有內(nèi)容。
   //
   outputSelection: {
     // 為每個合約生成元數(shù)據(jù)和字節(jié)碼輸出。
     "*": {
       "*": [ "metadata","evm.bytecode" ]
     },
     // 啟用“def”文件中定義的“MyContract”合約的abi和opcodes輸出。
     "def": {
       "MyContract": [ "abi","evm.bytecode.opcodes" ]
     },
     // 為每個合約生成源碼映射輸出
     "*": {
       "*": [ "evm.bytecode.sourceMap" ]
     },
     // 每個文件生成legacy AST輸出
     "*": {
       "": [ "legacyAST" ]
     }
   }
 }
}

輸出說明

{
 // 可選:如果沒有遇到錯誤/警告,則不出現(xiàn)
 errors: [
   {
     // 可選:源文件中的位置
     sourceLocation: {
       file: "sourceFile.sol",
       start: 0,
       end: 100
     ],
     // 強制: 錯誤類型,例如 “TypeError”, “InternalCompilerError”, “Exception”等.
     // 可在文末查看完整的錯誤類型列表
     type: "TypeError",
     // 強制: 發(fā)生錯誤的組件,例如“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)。如果為空,則表示為空數(shù)組。
       // 請參閱 https://github.com/ethereum/wiki/wiki/Ethereum-Contract-ABI
       abi: [],
       // 請參閱元數(shù)據(jù)輸出文檔(序列化的JSON字符串)
       metadata: "{...}",
       // 用戶文檔(natspec)
       userdoc: {},
       // 開發(fā)人員文檔(natspec)
       devdoc: {},
       // 中間表示形式 (string)
       ir: "",
       // EVM相關輸出
       evm: {
         // 匯編 (string)
         assembly: "",
         // 舊風格的匯編 (object)
         legacyAssembly: {},
         // 字節(jié)碼和相關細節(jié)
         bytecode: {
           // 十六進制字符串的字節(jié)碼
           object: "00fe",
           // 操作碼列表 (string)
           opcodes: "",
           // 源碼映射的字符串。 請參閱源碼映射的定義
           sourceMap: "",
           // 如果這里給出了信息,則表示這是一個未鏈接的對象
           linkReferences: {
             "libraryFile.sol": {
               // 字節(jié)碼中的字節(jié)偏移;鏈接時,從指定的位置替換20個字節(jié)
               "Library1": [
                 { start: 0,length: 20 },
                 { start: 200,length: 20 }
               ]
             }
           }
         },
         // 與上面相同的布局
         deployedBytecode: { },
         // 函數(shù)哈希的列表
         methodIdentifiers: {
           "delegate(address)": "5c19a95c"
         },
         // 函數(shù)的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: 源代碼不符合語言規(guī)則。

DocstringParsingError: 注釋塊中的NatSpec標簽無法解析。

SyntaxError: 語法錯誤,例如 continue 在 for 循環(huán)外部使用。

DeclarationError:無效的,無法解析的或沖突的標識符名稱 比如 Identifier not found。

TypeError: 類型系統(tǒng)內(nèi)的錯誤,例如無效類型轉(zhuǎn)換,無效賦值等。

UnimplementedFeatureError: 編譯器當前不支持該功能,但預計將在未來的版本中支持。

InternalCompilerError: 在編譯器中觸發(fā)的內(nèi)部錯誤——應將此報告為一個issue。

Exception: 編譯期間的未知失敗——應將此報告為一個issue。

CompilerError: 編譯器堆棧的無效使用——應將此報告為一個issue。

FatalError: 未正確處理致命錯誤——應將此報告為一個issue。

Warning: 警告,不會停止編譯,但應盡可能處理。

“Solidity中怎么使用編譯器”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關的知識可以關注億速云網(wǎng)站,小編將為大家輸出更多高質(zhì)量的實用文章!

向AI問一下細節(jié)

免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI