智能合約開發

在這個入門教程中咱們將創建以太坊智能合約開發一個應用的環境並學習開發一個投票類智能合約。咱們將構建一個簡單的"Hello World!" 應用程序, 這是一個投票應用程序。node

該應用程序很是簡單,它所作的只是初始化一組候選人,讓任何人投票給候選人,並顯示每一個候選人收到的總票數。linux

我有意避免使用任何DAPP框架構建這個應用程序,由於框架抽象掉不少細節,你不瞭解系統的內部。此外,當你使用框架時,將對框架所作的繁重工做有更多的體會!web

1. 設置智能合約開發環境

咱們使用一個模擬的內存區塊鏈(ganache)代替真實的區塊鏈在進行開發。在本教程的2章,咱們將與真實的區塊鏈交互。下面是安裝ganache、web3js的步驟,而後在linux上啓動一個測試鏈。在macOS上安裝過程也是同樣的。npm

智能合約開發

你能夠看到ganache-cli自動建立了10個測試帳號,每一個帳號預分配了100(虛構的)ethers編程

2.開發簡單的投票智能合約

咱們將使用solidity編程語言來開發咱們的智能合約。若是您熟悉面向對象編程,學習用solidity開發合約應該是垂手可得的事。咱們將開發一個合約對象,含有一個構造函數初始化候選人數組。合約對象有2個方法:數組

  1. 返回候選人得到的總票數
  2. 增長候選人的投票數。

注意:構造函數只被調用一次,當您部署智能合約到區塊鏈。不像在網絡世界裏的每個部署你的代碼覆蓋舊的代碼,部署後的代碼在區塊鏈上是不變的。例如,若是你更新你的合約而且再次部署,舊合約仍然會在區塊鏈上, 它所存儲的數據不受影響,新的部署將建立一個新實例的合約。網絡

下面是投票合約的代碼:架構

pragma solidity ^0.4.18;  
    // We have to specify what version of compiler this code will compile with  
      
    contract Voting {  
      /* mapping field below is equivalent to an associative array or hash.  
      The key of the mapping is candidate name stored as type bytes32 and value is  
      an unsigned integer to store the vote count  
      */  
        
      mapping (bytes32 => uint8) public votesReceived;  
        
      /* Solidity doesn't let you pass in an array of strings in the constructor (yet).  
      We will use an array of bytes32 instead to store the list of candidates  
      */  
        
      bytes32[] public candidateList;  
      
      /* This is the constructor which will be called once when you  
      deploy the contract to the blockchain. When we deploy the contract,  
      we will pass an array of candidates who will be contesting in the election  
      */  
      function Voting(bytes32[] candidateNames) public {  
        candidateList = candidateNames;  
      }  
      
      // This function returns the total votes a candidate has received so far  
      function totalVotesFor(bytes32 candidate) view public returns (uint8) {  
        require(validCandidate(candidate));  
        return votesReceived[candidate];  
      }  
      
      // This function increments the vote count for the specified candidate. This  
      // is equivalent to casting a vote  
      function voteForCandidate(bytes32 candidate) public {  
        require(validCandidate(candidate));  
        votesReceived[candidate] += 1;  
      }  
      
      function validCandidate(bytes32 candidate) view public returns (bool) {  
        for(uint i = 0; i < candidateList.length; i++) {  
          if (candidateList[i] == candidate) {  
            return true;  
          }  
        }  
        return false;  
      }  
    }

複製上面的代碼,在hello_world_voting目錄下建立一個Voting.sol文件。如今讓咱們來編譯代碼並將其部署到ganache的區塊鏈上.app

爲了編譯solidity代碼,咱們須要安裝名字爲solc的npm模塊框架

~/hello_world_voting$ npm install solc

咱們將在node控制檯中使用這個庫來編譯咱們的合約。在上一篇文章中咱們提到,web3js是一個讓咱們能夠經過rpc訪問區塊鏈的庫。咱們將使用該庫來部署咱們的應用程序並與之交互。

首先,在命令行中斷運行node命令進入node控制檯,初始化solc和文本對象。下面的全部代碼片斷都須要在node控制檯中鍵入

~/hello_world_voting$ node  
> Web3 = require('web3')  
> web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545"));

爲了確保web3對象已經初始化、區塊鏈可以訪問,讓咱們試一下查詢區塊鏈上的全部帳戶。您應該看到以下的結果:

> web3.eth.accounts  
    ['0x9c02f5c68e02390a3ab81f63341edc1ba5dbb39e',  
    '0x7d920be073e92a590dc47e4ccea2f28db3f218cc',  
    '0xf8a9c7c65c4d1c0c21b06c06ee5da80bd8f074a9',  
    '0x9d8ee8c3d4f8b1e08803da274bdaff80c2204fc6',  
    '0x26bb5d139aa7bdb1380af0e1e8f98147ef4c406a',  
    '0x622e557aad13c36459fac83240f25ae91882127c',  
    '0xbf8b1630d5640e272f33653e83092ce33d302fd2',  
    '0xe37a3157cb3081ea7a96ba9f9e942c72cf7ad87b',  
    '0x175dae81345f36775db285d368f0b1d49f61b2f8',  
    '0xc26bda5f3370bdd46e7c84bdb909aead4d8f35f3']

從voting.sol加載代碼,保存在一個字符串變量中,而後開始編譯

> code = fs.readFileSync('Voting.sol').toString()  
> solc = require('solc')  
> compiledCode = solc.compile(code)

當你的代碼編譯成功並打印了合約對象的內容(在node控制檯中輸出的內容),有2個字段很重要,須要理解它們:

  • compiledCode.contracts[‘:Voting’].bytecode: Voting.sol源代碼編譯後獲得的字節碼。這是將被部署到blockchain的代碼。
  • compiledCode.contracts[‘:Voting’].interface: 合約接口或模板(稱爲ABI)告訴用戶合約含有哪些方法。
相關文章
相關標籤/搜索