本篇內(nèi)容介紹了“Solidity中怎么使用編譯器”的有關(guān)知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領(lǐng)大家學(xué)習(xí)一下如何處理這些情況吧!希望大家仔細(xì)閱讀,能夠?qū)W有所成!
創(chuàng)新互聯(lián)公司服務(wù)項目包括通川網(wǎng)站建設(shè)、通川網(wǎng)站制作、通川網(wǎng)頁制作以及通川網(wǎng)絡(luò)營銷策劃等。多年來,我們專注于互聯(lián)網(wǎng)行業(yè),利用自身積累的技術(shù)優(yōu)勢、行業(yè)經(jīng)驗、深度合作伙伴關(guān)系等,向廣大中小型企業(yè)、政府機(jī)構(gòu)等提供互聯(lián)網(wǎng)行業(yè)的解決方案,通川網(wǎng)站推廣取得了明顯的社會效益與經(jīng)濟(jì)效益。目前,我們服務(wù)的客戶以成都為中心已經(jīng)輻射到通川省份的部分城市,未來相信會繼續(xù)擴(kuò)大服務(wù)區(qū)域并繼續(xù)獲得客戶的支持與信任!
solc 是 Solidity 源碼庫的構(gòu)建目標(biāo)之一,它是 Solidity 的命令行編譯器。你可使用 solc --help命令來查看它的所有選項的解釋。該編譯器可以生成各種輸出,范圍從簡單的二進(jìn)制文件、匯編文件到用于估計“gas”使用情況的抽象語法樹(解析樹)。如果你只想編譯一個文件,你可以運行 solc --bin sourceFile.sol 來生成二進(jìn)制文件。如果你想通過 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)中讀取并導(dǎo)入的文件,但同時,它也支持通過 prefix=path 選項將路徑重定向。比如:
這實質(zhì)上是告訴編譯器去搜索 /usr/local/lib/dapp-bin 目錄下的所有以 github.com/ethereum/dapp-bin/ 開頭的文件,如果編譯器找不到這樣的文件,它會接著讀取 /usr/local/lib/fallback 目錄下的所有文件(空前綴意味著始終匹配)。solc 不會從位于重定向目標(biāo)之外和顯式指定的源文件所在目錄之外的文件系統(tǒng)讀取文件,所以,類似 import "/etc/passwd"; 這樣的語句,編譯器只會在你添加了 =/ 選項之后,才會嘗試到根目錄下加載 /etc/passwd 文件。
如果重定向路徑下存在多個匹配,則選擇具有最長公共前綴的那個匹配。
出于安全原因,編譯器限制了它可以訪問的目錄。在命令行中指定的源文件的路徑(及其子目錄)和通過重定向定義的路徑可用于 import 語句,其他的則會被拒絕。額外路徑(及其子目錄)可以通過 --allow-paths /sample/path,/another/sample/path 進(jìn)行配置。
如果您的合約使用 libraries ,您會注意到在編譯后的十六進(jìn)制字節(jié)碼中會包含形如 LibraryName__ 的字符串。當(dāng)您將 solc 作為鏈接器使用時,它會在下列情況中為你插入庫的地址:要么在命令行中添加 --libraries "Math:0x12345678901234567890 Heap:0xabcdef0123456" 來為每個庫提供地址,或者將這些字符串保存到一個文件中(每行一個庫),并使用 --libraries fileName 參數(shù)。
如果在調(diào)用 solc 命令時使用了 --link 選項,則所有的輸入文件會被解析為上面提到過的__LibraryName____ 格式的未鏈接的二進(jìn)制數(shù)據(jù)(十六進(jìn)制編碼),并且就地鏈接。(如果輸入是從stdin讀取的,則生成的數(shù)據(jù)會被寫入stdout)。在這種情況下,除了 --libraries 外的其他選項(包括 -o )都會被忽略。
如果在調(diào)用 solc 命令時使用了 --standard-json 選項,它將會按JSON格式解析標(biāo)準(zhǔn)輸入上的輸入,并在標(biāo)準(zhǔn)輸出上返回JSON格式的輸出。
下面展示的這些JSON格式是編譯器API使用的,當(dāng)然,在 solc 上也是可用的。有些字段是可選的(參見注釋),并且它們可能會發(fā)生變化,但所有的變化都應(yīng)該是后向兼容的。
編譯器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哈希值進(jìn)行檢查(如果有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: { // 默認(rèn)為 disabled enabled: true, // 基于你希望運行多少次代碼來進(jìn)行優(yōu)化。 // 較小的值可以使初始部署的費用得到更多優(yōu)化,較大的值可以使高頻率的使用得到優(yōu)化。 runs: 200 }, // 指定需編譯的EVM的版本。會影響代碼的生成和類型檢查。可用的版本為:homestead,tangerineWhistle,spuriousDragon,byzantium,constantinople evmVersion: "byzantium", // 可選: 元數(shù)據(jù)配置 metadata: { // 只可使用字面內(nèi)容,不可用URLs (默認(rèn)設(shè)為 false) useLiteralContent: true }, // 庫的地址。如果這里沒有把所有需要的庫都給出,會導(dǎo)致生成輸出數(shù)據(jù)不同的未鏈接對象 libraries: { // 最外層的 key 是使用這些庫的源文件的名字。 // 如果使用了重定向, 在重定向之后,這些源文件應(yīng)該能匹配全局路徑 // 如果源文件的名字為空,則所有的庫為全局引用 "myFile.sol": { "MyLib": "0x123123..." } } // 以下內(nèi)容可以用于選擇所需的輸出。 // 如果這個字段被忽略,那么編譯器會加載并進(jìn)行類型檢查,但除了錯誤之外不會產(chǎn)生任何輸出。 // 第一級的key是文件名,第二級是合約名稱,如果合約名為空,則針對文件本身(進(jìn)行輸出)。 // 若使用通配符*,則表示所有合約。 // // 可用的輸出類型如下所示: // 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預(yù)估量 // ewasm.wast - eWASM S-expressions 格式(不支持atm) // ewasm.wasm - eWASM二進(jìn)制格式(不支持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 ], // 強(qiáng)制: 錯誤類型,例如 “TypeError”, “InternalCompilerError”, “Exception”等. // 可在文末查看完整的錯誤類型列表 type: "TypeError", // 強(qiáng)制: 發(fā)生錯誤的組件,例如“general”,“ewasm”等 component: "general", // 強(qiáng)制:錯誤的嚴(yán)重級別(“error”或“warning”) severity: "error", // 強(qiáng)制 message: "Invalid keyword" // 可選: 帶錯誤源位置的格式化消息 formattedMessage: "sourceFile.sol:100: Invalid keyword" } ], // 這里包含了文件級別的輸出。可以通過outputSelection來設(shè)置限制/過濾。 sources: { "sourceFile.sol": { // 標(biāo)識符(用于源碼映射) id: 1, // AST對象 ast: {}, // legacy AST 對象 legacyAST: {} } }, // 這里包含了合約級別的輸出。 可以通過outputSelection來設(shè)置限制/過濾。 contracts: { "sourceFile.sol": { // 如果使用的語言沒有合約名稱,則該字段應(yīng)該留空。 "ContractName": { // 以太坊合約的應(yīng)用二進(jìn)制接口(ABI)。如果為空,則表示為空數(shù)組。 // 請參閱 https://github.com/ethereum/wiki/wiki/Ethereum-Contract-ABI abi: [], // 請參閱元數(shù)據(jù)輸出文檔(序列化的JSON字符串) metadata: "{...}", // 用戶文檔(natspec) userdoc: {}, // 開發(fā)人員文檔(natspec) devdoc: {}, // 中間表示形式 (string) ir: "", // EVM相關(guān)輸出 evm: { // 匯編 (string) assembly: "", // 舊風(fēng)格的匯編 (object) legacyAssembly: {}, // 字節(jié)碼和相關(guān)細(xì)節(jié) bytecode: { // 十六進(jìn)制字符串的字節(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預(yù)估量 gasEstimates: { creation: { codeDepositCost: "420000", executionCost: "infinite", totalCost: "infinite" }, external: { "delegate(address)": "25000" }, internal: { "heavyLifting()": "infinite" } } }, // eWASM相關(guān)的輸出 ewasm: { // S-expressions格式 wast: "", // 二進(jìn)制格式(十六進(jìn)制字符串) wasm: "" } } } } }
錯誤類型
JSONError: JSON輸入不符合所需格式,例如,輸入不是JSON對象,不支持的語言等。
IOError: IO和導(dǎo)入處理錯誤,例如,在提供的源里包含無法解析的URL或哈希值不匹配。
ParserError: 源代碼不符合語言規(guī)則。
DocstringParsingError: 注釋塊中的NatSpec標(biāo)簽無法解析。
SyntaxError: 語法錯誤,例如 continue 在 for 循環(huán)外部使用。
DeclarationError:無效的,無法解析的或沖突的標(biāo)識符名稱 比如 Identifier not found。
TypeError: 類型系統(tǒng)內(nèi)的錯誤,例如無效類型轉(zhuǎn)換,無效賦值等。
UnimplementedFeatureError: 編譯器當(dāng)前不支持該功能,但預(yù)計將在未來的版本中支持。
InternalCompilerError: 在編譯器中觸發(fā)的內(nèi)部錯誤——應(yīng)將此報告為一個issue。
Exception: 編譯期間的未知失敗——應(yīng)將此報告為一個issue。
CompilerError: 編譯器堆棧的無效使用——應(yīng)將此報告為一個issue。
FatalError: 未正確處理致命錯誤——應(yīng)將此報告為一個issue。
Warning: 警告,不會停止編譯,但應(yīng)盡可能處理。
“Solidity中怎么使用編譯器”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識可以關(guān)注創(chuàng)新互聯(lián)網(wǎng)站,小編將為大家輸出更多高質(zhì)量的實用文章!