使用 Browser-solidity 在 Go-Ethereum1.7.2 上進行簡單的智慧合約部署

Lion發表於2017-11-09

目錄

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

> browser-solidity@0.0.0 start /Users/lion/my_project/_eth/browser-solidity
> npm-run-all -lpr serve watch onchange

[serve   ]
[serve   ] > browser-solidity@0.0.0 serve /Users/lion/my_project/_eth/browser-solidity
[serve   ] > execr --silent http-server .
[serve   ]
[watch   ]
[watch   ] > browser-solidity@0.0.0 watch /Users/lion/my_project/_eth/browser-solidity
[watch   ] > watchify src/index.js -dv -p browserify-reload -o build/app.js
[watch   ]
[onchange]
[onchange] > browser-solidity@0.0.0 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,可以看到以下效果:

<embed>

  

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

<embed>

  
  點選Run選項卡,設定好Gas limitGas Price後,點選Create,能夠建立一個測試例項,對程式碼進行除錯。這時會在中間下面的視窗中,看到輸出的資訊。

  在mshkadd的右側輸入100,點選mshkadd,中間下面的視窗會繼續出現新的資訊,點選Details,能夠看到輸入的值和輸出的值。

<embed>

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

<embed>

  
  釋出以後,在上圖彈出的層中我們可以看到編譯後,能夠通過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-Ethereum1.7.2 上進行簡單的智慧合約部署
轉載宣告:可以轉載, 但必須以超連結形式標明文章原始出處和作者資訊及版權宣告,謝謝合作!


相關文章