1. 程式人生 > >使用 Browser-solidity 在 Go-Ethereum 上進行簡單的智能合約部署

使用 Browser-solidity 在 Go-Ethereum 上進行簡單的智能合約部署

區塊鏈 以太坊 智能合約

1、基本概念

  之前文章中,已經講過 Go-Ethereum 1.7.2 如何安裝及搭建以太坊私有鏈,這裏就不多介紹。

  在本文講解之前,先介紹以下幾點基本概念。

1.1、什麽是智能合約?

  智能合約是存儲在區塊鏈上的一段代碼,它們可以被區塊鏈上的交易所觸發,觸發後,這段代碼可以從區塊鏈上讀取數據或者向區塊鏈上寫入數據。
  

1.2、什麽是Solidity?

  Solidity 是 Ethereum 的一種契約型編程語言,運行在Ethereum虛擬機(EVM)之上。
  

1.2.1、Solidity的語言特性

  它的語法接近於Javascript,是一種面向對象的語言。但作為一種真正意義上運行在網絡上的去中心合約,它又有很多的不同,下面列舉一些:

  • 以太坊底層是基於帳戶,而非UTXO的,所以有一個特殊的Address的類型。用於定位用戶,定位合約,定位合約的代碼(合約本身也是一個帳戶)。

  • 由於語言內嵌框架是支持支付的,所以提供了一些關鍵字,如payable,可以在語言層面直接支持支付。

  • 存儲是使用網絡上的區塊鏈,數據的每一個狀態都可以永久存儲,所以需要確定變量使用內存,還是區塊鏈。

  • 運行環境是在去中心化的網絡上,會比較強調合約或函數執行的調用的方式。因為原來一個簡單的函數調用變為了一個網絡上的節點中的代碼執行。

  • 最後一個非常大的不同則是它的異常機制,一旦出現異常,所有的執行都將會被回撤,這主要是為了保證合約執行的原子性,以避免中間狀態出現的數據不一致。

  

1.3、什麽是 Browser-solidity?

  Browser-solidity 是一個官方提供的一個基於瀏覽器的合約編譯器,非常好用,而且build版本會緊跟最新的 Solidity 的 build 版本。但由於網絡原因以及GFW的存在,有可能會另一部分人訪問很慢,進而影響開發效率。

  可以直接在線使用,訪問後面的地址:https://remix.ethereum.org

  

2、Browser-solidity 的源碼在哪裏?

  https://github.com/ethereum/browser-solidity

  

3、如何在本地安裝 Browser-solidity?

  由於國內網絡的GFW原因,以及在網絡上訪問會影響效率,推薦部署到本地開發。

下面的4行代碼開始將Browser-solidity安裝到本地。

? /Users/lion/my_project/_eth > git clone https://github.com/ethereum/browser-solidity
? /Users/lion/my_project/_eth > cd browser-solidity
? /Users/lion/my_project/_eth/browser-solidity git:(master) > npm install
? /Users/lion/my_project/_eth/browser-solidity git:(master) > npm run prepublish

  
  安裝以後,通過以下命令啟動Browser-solidity

npm start

  
  啟動後,控制臺會輸出如下信息:

? /Users/lion/my_project/_eth/browser-solidity git:(master) >npm start
>[email protected] start /Users/lion/my_project/_eth/browser-solidity
> npm-run-all -lpr serve watch onchange

[serve   ]
[serve   ] > [email protected] serve /Users/lion/my_project/_eth/browser-solidity
[serve   ] > execr --silent http-server .
[serve   ]
[watch   ]
[watch   ] > [email protected] watch /Users/lion/my_project/_eth/browser-solidity
[watch   ] > watchify src/index.js -dv -p browserify-reload -o build/app.js
[watch   ]
[onchange]
[onchange] > [email protected] onchange /Users/lion/my_project/_eth/browser-solidity
[onchange] > onchange build/app.js -- npm-run-all lint
[onchange]
[watch   ] WS server listening on  58651

  
  然後打開瀏覽器,在地址欄輸入:http://127.0.0.1:8080,可以看到以下效果:


  

4、使用 Browser-solidity 編譯代碼

  下面是一個簡單的智能合約代碼,輸入任何數值,都加上2009。

pragma solidity 0.4.9;contract mshkDemo {

     function mshkadd(uint a) public returns (address, uint b) {  
        uint resutl = a+2009;
        return (msg.sender, resutl);
    }  
  }

    
  第一行是聲明使用solidity合約的版本號,在0.4.9版本以前,聲明版本號,在版本號前要加上^,如pragma solidity ^0.4.0solidity 中的智能合約是一種類似javascript的語言,所以在語法上很像。

  在本地打開Browser-solidity後,在右側的Settings選項卡中,在下拉列表中,選擇solidity的版本0.4.9


  
  點擊Run選項卡,設置好Gas limitGas Price後,點擊Create,能夠創建一個測試實例,對代碼進行調試。這時會在中間下面的窗口中,看到輸出的信息。

  在mshkadd的右側輸入100,點擊mshkadd,中間下面的窗口會繼續出現新的信息,點擊Details,能夠看到輸入的值和輸出的值。


  
  點擊Compile選項卡,然後點擊Publish on,會看到提示層,然後點擊Details,可以看到發布後的內容。


  
  發布以後,在上圖彈出的層中我們可以看到編譯後,能夠通過web3部署的代碼在WEB3DEPLOY中,代碼如下:

var browser_mshk_sol_mshkdemoContract = web3.eth.contract([{"constant":false,"inputs":[{"name":"a","type":"uint256"}],"name":"mshkadd","outputs":[{"name":"","type":"address"},{"name":"b","type":"uint256"}],"payable":false,"type":"function","stateMutability":"nonpayable"}]);var browser_mshk_sol_mshkdemo = browser_mshk_sol_mshkdemoContract.new(   {
     from: web3.eth.accounts[0],
     data: '0x6060604052341561000c57fe5b5b60e48061001b6000396000f30060606040526000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063ee64a56014603a575bfe5b3415604157fe5b60556004808035906020019091905050609e565b604051808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019250505060405180910390f35b6000600060006107d9840190503381925092505b509150915600a165627a7a7230582008b5b31ef21a9273b2728793378a837f0b7a4e7517a15041a358e33fbf45899e0029',
     gas: '300000'
   }, function (e, contract){
    console.log(e, contract);
    if (typeof contract.address !== 'undefined') {
         console.log('Contract mined! address: ' + contract.address + ' transactionHash: ' + contract.transactionHash);
    }
 })

  

4.1 將 Browser-solidity 編譯後的合約部署到 Geth

  將上面的代碼貼到geth javascript console中執行

> var browser_mshk_sol_mshkdemo = browser_mshk_sol_mshkdemoContract.new(    
   {
      from: web3.eth.accounts[0],
      data: '0x6060604052341561000c57fe5b5b60e48061001b6000396000f30060606040526000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063ee64a56014603a575bfe5b3415604157fe5b60556004808035906020019091905050609e565b604051808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019250505060405180910390f35b6000600060006107d9840190503381925092505b509150915600a165627a7a7230582008b5b31ef21a9273b2728793378a837f0b7a4e7517a15041a358e33fbf45899e0029',
      gas: '300000'
    }, function (e, contract){
     console.log(e, contract);
     if (typeof contract.address !== 'undefined') {
          console.log('Contract mined! address: ' + contract.address + ' transactionHash: ' + contract.transactionHash);
     }
  })
  null [object Object]
  undefined
> null [object Object]
Contract mined! address: 0xf5f6d56c1c480d9235a4e538f2f2888c683b168c transactionHash: 0xf6203401fd0fe2237b7e53c021622272e7a9aa10d578ac0660c9145e7e700753

from表示調用智能合約的帳戶,代碼中取的是accounts[0]

data是編譯後的代碼,你的代碼越長,這塊的字符串越多

gas調用合約要扣除的gas單位,可以理解為以太幣,gas和ether之間有個匯率,匯率受礦機的算率影響會有調整,在公網上,這些gas用於獎勵給挖礦者

address表示已經部署智能合約的帳戶地址,智能合約也相當於一個帳戶

transactionHash的智能合約產生時的hash值,會永久保存到區塊鏈條裏面

  
  輸入browser_mshk_sol_mshkdemo可以看到合約的一些信息

> browser_mshk_sol_mshkdemo{
  abi: [{
      constant: false,
      inputs: [{...}],
      name: "mshkadd",
      outputs: [{...}, {...}],
      payable: false,
      stateMutability: "nonpayable",
      type: "function"
  }],
  address: "0xf5f6d56c1c480d9235a4e538f2f2888c683b168c",
  transactionHash: "0xf6203401fd0fe2237b7e53c021622272e7a9aa10d578ac0660c9145e7e700753",
  allEvents: function(),
  mshkadd: function()
  }

  
  然後通過browser_mshk_sol_mshkdemo.mshkadd.call調用

> browser_mshk_sol_mshkdemo.mshkadd.call(10)TypeError: Cannot access member 'call' of undefined
    at <anonymous>:1:1

出現TypeError: Cannot access member 'call' of undefined的錯誤,是因為我們沒有挖礦,在之前的章節提到過,如果停止挖礦,是不能進行轉帳和智能合約的部署。

  
  重新啟動挖礦,調用合約,就可以輸出正確的值了。

> miner.start()> browser_mshk_sol_mshkdemo.mshkadd.call(10)
["0xbe323cc4fde114269a9513a27d3e985f82b9e25d", 2019]
> browser_mshk_sol_mshkdemo.mshkadd.call(550)
["0xbe323cc4fde114269a9513a27d3e985f82b9e25d", 2559]


使用 Browser-solidity 在 Go-Ethereum 上進行簡單的智能合約部署