# solc:solidity的編譯器solidity編寫的以太坊智能合約可通過命令列編譯工具solc來進行編譯,成為以太坊虛擬機器中的代碼。solc編譯後最終部署到鏈上形成我們所見到的各種智能合約。作為一個solidity命令列編譯工具,我們來看看官網都怎麼說solc。solc的安裝很簡單:```npm install -g solc//或者npm install -g solc-cli//或者sudo apt-get install solc```安裝完成後我們來看,```solc --help```,solc --help命令顯示所有的solc命令選項。編譯器可以產生各種輸出,比如最終的二進位合約檔案、文法樹的彙編或者需要預計的要花費的gas等。```solc --bin sourceFile.sol```,可以編譯後輸出一個名為sourceFile.sol的智能合約檔案。如果你想從```solc```獲得更豐富的一些輸出變數,你可以使用```solc -o outputDirectory --bin --ast --asm sourceFile.sol```。你在部署[以太坊智能合約](http://xc.hubwiz.com/course/5a952991adb3847553d205d1)之前可以用```solc --optimize --bin sourceFile.sol```最佳化一下。預設情況下solc編譯器會幫你最佳化200次。你也可以設定 ```--runs=1```,這樣就按照最小化的方式進行編譯,如果你希望多次交易不太在乎成本,那你可以設定成你想要的次數:)。命令列編譯器會自動讀取需要匯入的檔案,也可以通過使用```prefix = path```來指定路徑,例如:>```solc github.com/ethereum/dapp-bin/=/usr/local/lib/dapp-bin/ =/usr/local/lib/fallback file.sol```這樣編譯器就會從指定目錄```github.com/ethereum/dapp-bin/```下的```/usr/local/lib/dapp-bin/```目錄開始搜尋,如果沒有找到檔案,它將查看```/usr/local/lib/fallback```。solc將唯讀取你指定的這兩個路徑的,因此像```import "/etc/passwd";```必須要通過```/=```重新對應才起作用。如果有多個匹配,則選擇具有最長公用首碼的進行匹配。出於安全上的考慮,編譯器限制了它可以訪問的一些目錄。在命令列中指定的源檔案的路徑(及其子目錄)和命令列指定的路徑外其他所有內容都會被拒絕。```--allow-paths /sample/path,/another/sample/path```來切換。如果智能合約使用了[libraries](https://solidity.readthedocs.io/en/v0.4.24/contracts.html#libraries),你會注意到位元組碼包含了```__LibraryName______```的子字串。您可以使用solc作為連結器,這意味著它將在這些點為您插入庫地址。可以通過添加庫```--libraries "Math:0x12345678901234567890 Heap:0xabcdef0123456"```到您的命令,以提供每個庫的地址,或者使用檔案中的說明字串(每行一個庫),並使用```--libraries fileName```運行solc。如果用選項```--link```調用Solc,則所有輸入檔案都被解釋為未連結的二進位檔案(HEX編碼),在上面給出的```__LibraryName____```格式中,將其連結到適當地址(如果從stdin讀取輸入,則將其寫入stdout)。在這種情況下,除了庫外,所有選項都被忽略(包括```-o```)。如果用```--standard-json```調用SOLC,它就將標準的JSON輸入(如下所述),並返回JSON輸出。#solc編譯器輸入輸出JSON描述這些JSON格式通過編譯器API使用,可以通過SOLC獲得。內容都是可以修改的,一些對象是可選的(如前所述),其目的是向後相容。編譯器的API需要一個JSON格式的輸入,然後以JSON格式輸出編譯結果。**注意不允許注釋**。下面樣本中的注釋,是官網為了學習者更好的理解標註的。* 輸入格式說明:```{ // Required: Source code language, such as "Solidity", "serpent", "lll", "assembly", etc. language: "Solidity", // Required sources: { // The keys here are the "global" names of the source files, // imports can use other files via remappings (see below). "myFile.sol": { // Optional: keccak256 hash of the source file // It is used to verify the retrieved content if imported via URLs. "keccak256": "0x123...", // Required (unless "content" is used, see below): URL(s) to the source file. // URL(s) should be imported in this order and the result checked against the // keccak256 hash (if available). If the hash doesn't match or none of the // URL(s) result in success, an error should be raised. "urls": [ "bzzr://56ab...", "ipfs://Qma...", "file:///tmp/path/to/file.sol" ] }, "mortal": { // Optional: keccak256 hash of the source file "keccak256": "0x234...", // Required (unless "urls" is used): literal contents of the source file "content": "contract mortal is owned { function kill() { if (msg.sender == owner) selfdestruct(owner); } }" } }, // Optional settings: { // Optional: Sorted list of remappings remappings: [ ":g/dir" ], // Optional: Optimizer settings optimizer: { // disabled by default enabled: true, // Optimize for how many times you intend to run the code. // Lower values will optimize more for initial deployment cost, higher values will optimize more for high-frequency usage. runs: 200 }, evmVersion: "byzantium", // Version of the EVM to compile for. Affects type checking and code generation. Can be homestead, tangerineWhistle, spuriousDragon, byzantium or constantinople // Metadata settings (optional) metadata: { // Use only literal content and not URLs (false by default) useLiteralContent: true }, // Addresses of the libraries. If not all libraries are given here, it can result in unlinked objects whose output data is different. libraries: { // The top level key is the the name of the source file where the library is used. // If remappings are used, this source file should match the global path after remappings were applied. // If this key is an empty string, that refers to a global level. "myFile.sol": { "MyLib": "0x123123..." } } // The following can be used to select desired outputs. // If this field is omitted, then the compiler loads and does type checking, but will not generate any outputs apart from errors. // The first level key is the file name and the second is the contract name, where empty contract name refers to the file itself, // while the star refers to all of the contracts. // // The available output types are as follows: // abi - ABI // ast - AST of all source files // legacyAST - legacy AST of all source files // devdoc - Developer documentation (natspec) // userdoc - User documentation (natspec) // metadata - Metadata // ir - New assembly format before desugaring // evm.assembly - New assembly format after desugaring // evm.legacyAssembly - Old-style assembly format in JSON // evm.bytecode.object - Bytecode object // evm.bytecode.opcodes - Opcodes list // evm.bytecode.sourceMap - Source mapping (useful for debugging) // evm.bytecode.linkReferences - Link references (if unlinked object) // evm.deployedBytecode* - Deployed bytecode (has the same options as evm.bytecode) // evm.methodIdentifiers - The list of function hashes // evm.gasEstimates - Function gas estimates // ewasm.wast - eWASM S-expressions format (not supported atm) // ewasm.wasm - eWASM binary format (not supported atm) // // Note that using a using `evm`, `evm.bytecode`, `ewasm`, etc. will select every // target part of that output. Additionally, `*` can be used as a wildcard to request everything. // outputSelection: { // Enable the metadata and bytecode outputs of every single contract. "*": { "*": [ "metadata", "evm.bytecode" ] }, // Enable the abi and opcodes output of MyContract defined in file def. "def": { "MyContract": [ "abi", "evm.bytecode.opcodes" ] }, // Enable the source map output of every single contract. "*": { "*": [ "evm.bytecode.sourceMap" ] }, // Enable the legacy AST output of every single file. "*": { "": [ "legacyAST" ] } } }}```* 輸出格式說明```{ // Optional: not present if no errors/warnings were encountered errors: [ { // Optional: Location within the source file. sourceLocation: { file: "sourceFile.sol", start: 0, end: 100 ], // Mandatory: Error type, such as "TypeError", "InternalCompilerError", "Exception", etc. // See below for complete list of types. type: "TypeError", // Mandatory: Component where the error originated, such as "general", "ewasm", etc. component: "general", // Mandatory ("error" or "warning") severity: "error", // Mandatory message: "Invalid keyword" // Optional: the message formatted with source location formattedMessage: "sourceFile.sol:100: Invalid keyword" } ], // This contains the file-level outputs. In can be limited/filtered by the outputSelection settings. sources: { "sourceFile.sol": { // Identifier (used in source maps) id: 1, // The AST object ast: {}, // The legacy AST object legacyAST: {} } }, // This contains the contract-level outputs. It can be limited/filtered by the outputSelection settings. contracts: { "sourceFile.sol": { // If the language used has no contract names, this field should equal to an empty string. "ContractName": { // The Ethereum Contract ABI. If empty, it is represented as an empty array. // See https://github.com/ethereum/wiki/wiki/Ethereum-Contract-ABI abi: [], // See the Metadata Output documentation (serialised JSON string) metadata: "{...}", // User documentation (natspec) userdoc: {}, // Developer documentation (natspec) devdoc: {}, // Intermediate representation (string) ir: "", // EVM-related outputs evm: { // Assembly (string) assembly: "", // Old-style assembly (object) legacyAssembly: {}, // Bytecode and related details. bytecode: { // The bytecode as a hex string. object: "00fe", // Opcodes list (string) opcodes: "", // The source mapping as a string. See the source mapping definition. sourceMap: "", // If given, this is an unlinked object. linkReferences: { "libraryFile.sol": { // Byte offsets into the bytecode. Linking replaces the 20 bytes located there. "Library1": [ { start: 0, length: 20 }, { start: 200, length: 20 } ] } } }, // The same layout as above. deployedBytecode: { }, // The list of function hashes methodIdentifiers: { "delegate(address)": "5c19a95c" }, // Function gas estimates gasEstimates: { creation: { codeDepositCost: "420000", executionCost: "infinite", totalCost: "infinite" }, external: { "delegate(address)": "25000" }, internal: { "heavyLifting()": "infinite" } } }, // eWASM related outputs ewasm: { // S-expressions format wast: "", // Binary format (hex string) wasm: "" } } } }}```* 錯誤類型說明:1. JSONError:JSON錯誤,JSON輸入不符合要求的格式,例如輸入不是JSON對象,不支援語言,等等。2. IOError:IO錯誤,IO和匯入處理錯誤,如提供的源中的不可解析URL或hash不匹配。3. ParserError:文法f分析錯誤,原始碼不符合語言規則。4. DocstringParsingError:文檔解析錯誤,無法解析註解區塊中的NATSPEC標記。5. SytRealError:語法錯誤,如```continue ```在```for```迴圈之外使用。6. DeclarationError:聲明錯誤,無效、不可解析或衝突的標識符名稱。例如未找到標識符7. TypeError:類型錯誤,如無效類型轉換、無效賦值等。8. UnimplementedFeatureError:編譯器不支援該特性,但希望在將來的版本中得到支援。9. InternalCompilerError:編譯器中觸發內部錯誤,這應該作為一個問題來反饋。10. Exception:例外,編譯過程中未知的故障,這應該作為一個問題反饋。11. CompilerError:編譯錯誤,編譯器堆棧的使用無效,這應該作為一個問題來反饋。12. FatalError:致命錯誤,這應該作為一個問題來反饋。13. Warning:警告並沒有停止編譯,但如果可能的話,應該加以處理。原文請訪問:[solc](http://blog.hubwiz.com/2018/06/14/solc-compiler/)如果你希望馬上開始學習以太坊DApp開發,推薦訪問一個線上教程:* [以太坊智能合約](http://xc.hubwiz.com/course/5a952991adb3847553d205d1?affid=studygolang616),主要介紹智能合約與dapp應用開發,適合入門。* [以太坊開發](http://xc.hubwiz.com/course/5abbb7acc02e6b6a59171dd6?affid=studygolang616),主要是介紹使用node.js、mongodb、區塊鏈、ipfs實現去中心化電商DApp實戰,適合進階。281 次點擊