1. 程式人生 > >如何通過solc編譯solidity編寫的以太坊智慧合約

如何通過solc編譯solidity編寫的以太坊智慧合約

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

你在部署以太坊智慧合約之前可以用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,你會注意到位元組碼包含了__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:語法錯誤,如continuefor迴圈之外使用。
    6. DeclarationError:宣告錯誤,無效、不可解析或衝突的識別符號名稱。例如未找到識別符號
    7. TypeError:型別錯誤,如無效型別轉換、無效賦值等。
    8. UnimplementedFeatureError:編譯器不支援該特性,但希望在將來的版本中得到支援。
    9. InternalCompilerError:編譯器中觸發內部錯誤,這應該作為一個問題來反饋。
    10. Exception:例外,編譯過程中未知的故障,這應該作為一個問題反饋。
    11. CompilerError:編譯錯誤,編譯器堆疊的使用無效,這應該作為一個問題來反饋。
    12. FatalError:致命錯誤,這應該作為一個問題來反饋。
    13. Warning:警告並沒有停止編譯,但如果可能的話,應該加以處理。

原文請訪問:solc

如果你希望馬上開始學習以太坊DApp開發,推薦訪問一個線上教程:
* 以太坊智慧合約,主要介紹智慧合約與dapp應用開發,適合入門。
* 以太坊開發,主要是介紹使用node.js、mongodb、區塊鏈、ipfs實現去中心化電商DApp實戰,適合進階。

相關推薦

如何通過solc編譯solidity編寫智慧合約

solc:solidity的編譯器 solidity編寫的以太坊智慧合約可通過命令列編譯工具solc來進行編譯,成為以太坊虛擬機器中的程式碼。solc編譯後最終部署到鏈上形成我們所見到的各種智慧合約。 作為一個solidity命令列編譯工具,我們來看看官網都

區塊鏈技術進階-深入詳解智慧合約語言 solidity(含原始碼)-熊麗兵-專題視訊課程...

區塊鏈技術進階-深入詳解以太坊智慧合約語言 solidity(含原始碼)—103人已學習 課程介紹         區塊鏈開發技術進階-深入詳解以太坊智慧合約語言 solidity視訊培訓教程:本課

solidity語言開發智慧合約中的繼承

我們【天恆幸運飛艇原始碼下載】【征途原始碼論壇http://zhengtuwangluo.com】聯絡方式:QQ:2747044651已經探索了很多主題,在編寫智慧合約時我們發現經常使用相同的模式:例如,智慧合約具有在建構函式中設定的所有者,然後生成修改器以便僅

區塊鏈2.0智慧合約solidity之helloworld

由於只能合約是放在區塊鏈上面的程式碼,這給我們的除錯帶來了很多的困難,還好有線上的編譯器:https://remix.ethereum.org第一個程式碼:pragma solidity ^0.4.4;contract Counter {uint count = 0;addr

區塊鏈100講:智慧合約solidity如何節省GAS費?

1 摘要 在以太坊上,程式碼即法律,交易即金錢。每一筆智慧合約的執行,都要根據複雜度消耗一筆GAS費(ETH)。那麼,智慧合約solidity語言的編寫,不僅要考慮安全,也要考慮語言的優化,以便高效便宜了。 本文將從以下一些方面分析如何節約GAS的程式設計總結

Android通過web3j智慧合約互動

如果要下載整個以太坊區塊鏈並保持本地節點同步。當區塊鏈佔用了我計算機上超過100GB的空間。這在臺式計算機上可能有意義,但在移動裝置上則不太合理。 解決此限制的一種方法是使用像Infura這樣的服務。Infura允許你連線到遠端以太坊節點並執行交易,而無需擔心維護和同步本地

編寫除錯智慧合約/blockchain

一、        智慧合約IDE簡介     目前以太坊上支援三種語言編寫智慧合約,     Solidity:類似JavaScript,這是以太坊官方推薦語言,也是最流行的智慧合約語言。具體用法參加Solidity文件,地址:https://solidity

動手編寫一個智慧合約

本文節選自圖書《區塊鏈開發指南》,本書由 申屠青春 主編,宋波、張鵬、汪曉明、季宙棟、左川民 聯合編著。 區塊鏈相關約稿、文章糾錯、尋求報道等可郵件聯絡 [email protected] 如何部署、呼叫智慧合約 RPC 之前的

智慧合約學習筆記:網頁互動

沒搞過web程式,花了幾天研究一下,總算是搞懂了網頁與以太坊節點的互動流程。 網頁與智慧合約互動,需要使用web3.js,它實現了通用JSON PRC規範,通過JSON RPC協議與以太坊節點進行互動。除了js以外,以太坊還提供了Java、Python等語言的API,對於沒有提供API的語言

智慧合約學習筆記:使用Truffle框架開發部署智慧合約

truffle是一個智慧合約的開發框架,具體的就不介紹了,我們主要是說說怎麼使用這個框架來進行智慧合約的開發,官網戳這裡。 文章目錄 #安裝 首先我們要先安裝npm和truffle,安裝命令如下 sudo apt install npm sudo n

智慧合約學習筆記:開發流程及工具鏈使用

本文主要介紹開發流程和工具鏈的使用,安裝過程百度上有好多,這裡就不贅述了 網上隨便找了一個智慧合約的例子,咱們來做一個投票系統,先用傳統的中心化方案去實現,然後在過度到區塊鏈1.0,最後再用區塊鏈2.0,感受一下開發思想的不同。 業務分析 傳統

iOS應用程式如何呼叫智慧合約

以太坊智慧合約有各種各樣的用例,但到目前為止,從你的iOS應用程式中呼叫它們非常困難。不過如果使用以太坊iOS開發套件和EtherKit,這種情況會改善很多,你可以立即開始使用。在本教程結束時,你將能夠呼叫其ABI(應用程式二進位制介面)中定義的任何公共合約函式。 對於這個專案,我們將使

如何實現一鍵呼叫智慧合約

今天有人問如何用按鈕呼叫智慧合約,我不知道在哪裡找,所以我決定寫這個,很快就可以。 在這篇文章中,我將給出一個簡單但有希望有效的演示,說明JavaScript開發人員如何建立一個能夠呼叫智慧合約的網頁,並通過單擊即可向其匯款(以太幣)。 要做到這一點,使用者將需要使用支援Web

olidity語言開發智慧合約中的繼承

我們已經探索了很多主題,在編寫智慧合約時我們發現經常使用相同的模式:例如,智慧合約具有在建構函式中設定的所有者,然後生成修改器以便僅讓所有者使用一些功能。如果我們制定實施這些功能的基礎合約並在未來的智慧合約中重複使用它們那該怎麼辦?你一定猜得到,我們將使用繼承。 在Solidity中,繼承與經典的面向物

web3j教程:java使用web3j開發智慧合約交易

從廣義上講,有web3j支援三種類型的以太坊交易: 1.以太幣從一方交易到另一方 2.建立一個智慧合約 3.與智慧合約交易 為了進行這些交易,必須有以太幣(以太坊區塊鏈的代幣)存在於交易發生的以太坊賬戶中。這是為了支付gas成本,這是為支付參與交易的以太坊客戶端的交

java如何在Spring Boot中用web3j開始開發智慧合約

通過Spring的依賴注入將web3j整合到Spring Boot應用程式中。此處提供了示例應用程式: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25

關於智慧合約在專案實戰過程中的設計及經驗總結(1)

此文已由作者蘇州授權網易雲社群釋出。 歡迎訪問網易雲社群,瞭解更多網易技術產品運營經驗 1.智慧合約的概述 近幾年,區塊鏈概念的大風吹遍了全球各地,有的人覺得這是一個大風口,有的人覺得他是個泡沫。眾所周知,比特幣是區塊鏈1.0,而以太坊被稱為了區塊鏈2.0,而區塊鏈1.0和2.0最主要的差別就在於以太坊擁有

關於智慧合約在專案實戰過程中的設計及經驗總結(2)

此文已由作者蘇州授權網易雲社群釋出。 歡迎訪問網易雲社群,瞭解更多網易技術產品運營經驗 7.智慧合約經驗分享 1)智慧合約開發的工具的問題 古人云“工欲善其事必先利其器”,同意良好的智慧合約的開發工具對智慧合約的開發效率有極大的提升。以下是一些比較好的智慧合約的開發組合: &nb

智慧合約的奇幻漂流

“A smart contract is a computer program executed in a secure environment that directly controls digital assets.” – Vitalik Buterin 作為以太坊

區塊鏈開發(二)部署並執行第一個智慧合約

        網路上不少部署智慧合約的文章,但是都有一個共同的特點,就是採用命令列的方式來部署,先是建立SOLC的編譯環境,然後部署Geth或者Eth節點,然後一步一步生成錢包、ABI、合約地址進行部署,對初學者來說晦澀難懂而且容易失敗,本文主要介紹如何在圖形化介面下一鍵部