1. 程式人生 > >【區塊鏈學習】以Linux為例,通過控制檯部署和執行智慧合約

【區塊鏈學習】以Linux為例,通過控制檯部署和執行智慧合約

安裝環境

安裝以太坊環境

(1) sudo apt-get install software-properties-common

這裡寫圖片描述

這裡寫圖片描述

(2)sudo add-apt-repository -y ppa:ethereum/ethereum

這裡寫圖片描述

(3)sudo add-apt-repository -y ppa:ethereum/ethereum-dev

這裡寫圖片描述

(4)sudo apt-get update

這裡寫圖片描述

(5)sudo apt-get install ethereum,如果這一步失敗,一直重試安裝

這裡寫圖片描述

安裝solidity語言編譯器

(1)Chrome裡面外掛安裝

開啟Chrome網上應用商店,搜尋solidity

這裡寫圖片描述

安裝後開啟,一般solidity語言編寫的智慧合約程式碼會自動編譯,然後在右邊顯示,如果沒有,說明solidity程式碼語法錯誤

例如,solidity智慧合約程式碼編譯通過

這裡寫圖片描述

例如,solidity智慧合約程式碼編譯失敗

這裡寫圖片描述

(2)solidity語言線上編譯器

私有鏈搭建

(1)開啟終端(Ctrl+Alt+T)

這裡寫圖片描述

(2)開啟測試網控制檯:geth --datadir "~/ethdev" --dev console 2>> geth.log

這裡寫圖片描述

(3)檢視personal的屬性:personal

這裡寫圖片描述

(4)建立賬戶: personal.newAccount('123456'),123456是密碼,0xe9f350a2c250fa26b7eb3db6f28d858668b7e45b 是賬戶地址

這裡寫圖片描述

(5)檢視賬戶餘額:web3.eth.getBalance(personal.listAccounts[0]), personal.listAccounts[0] 就是我們第一賬戶,當前賬戶餘額為0

這裡寫圖片描述

(6)啟動挖礦:miner.start(), 如果感覺佔用CPU,可以啟動一個CPU挖礦miner.start(1)

這裡寫圖片描述

(7)開啟另一終端,檢視挖礦資訊(如果一直挖礦,會不斷刷屏,正常,這個終端用來觀察挖礦資訊),檢視挖礦資訊:tail -f geth.log

這裡寫圖片描述

(8)停止挖礦:miner.stop(),如果覺得CPU被佔用覺得還行,忽略這一步,後面交易確認需要挖礦一直進行

這裡寫圖片描述

(9)檢視餘額:web3.eth.getBalance(personal.listAccounts[0]) 或者web3.fromWei(eth.getBalance("0xe9f350a2c250fa26b7eb3db6f28d858668b7e45b"), "ether")

這裡寫圖片描述

這裡寫圖片描述

(10)解鎖發起智慧合約的賬戶:personal.unlockAccount("0xe9f350a2c250fa26b7eb3db6f28d858668b7e45b"), 0xe9f350a2c250fa26b7eb3db6f28d858668b7e45b 是我們發起智慧合約賬戶的地址

這裡寫圖片描述

部署智慧合約

(1)編寫智慧合約:

contract Rating {
    function setRating(bytes32 _key, uint256 _value) {
        ratings[_key] = _value;
    }
    mapping (bytes32 => uint256) public ratings;
}

(2)複製編譯後得到Web3 deploy, 從程式碼上看,定義了2個變數:ratingContractrating

var ratingContract = web3.eth.contract([{"constant":false,"inputs":[{"name":"_key","type":"bytes32"},{"name":"_value","type":"uint256"}],"name":"setRating","outputs":[],"type":"function"},{"constant":true,"inputs":[{"name":"","type":"bytes32"}],"name":"ratings","outputs":[{"name":"","type":"uint256"}],"type":"function"}]);
var rating = ratingContract.new(
   {
     from: web3.eth.accounts[0], 
     data: '606060405260c88060106000396000f360606040526000357c01000000000000000000000000000000000000000000000000000000009004806350b7b7a21460415780636c71d01d14606057603f565b005b605e6004808035906020019091908035906020019091905050608a565b005b6074600480803590602001909190505060ad565b6040518082815260200191505060405180910390f35b8060006000506000848152602001908152602001600020600050819055505b5050565b6000600050602052806000526040600020600091509050548156', 
     gas: 3000000
   }, function(e, contract){
    console.log(e, contract);
    if (typeof contract.address != 'undefined') {
         console.log('Contract mined! address: ' + contract.address + ' transactionHash: ' + contract.transactionHash);
    }
 })

這裡寫圖片描述

(3)複製上面的程式碼到控制檯上,從內容看,裡面是2個變數的定義,所以分開復制更好看一些。

這裡寫圖片描述

(4)這時,我們可以檢查一下交易池,檢視當前交易的待處理狀況:txpool.status,如果pending=1,說明我們的合約還沒得到確認,因為我們剛才停止挖礦。

這裡寫圖片描述

(5)從上面,我們可以看到當前的交易池中有一個交易正在等待確認。然後,我們檢視待確認交易的詳細內容:eth.getBlock("pending",true).transactions

這裡寫圖片描述
我們從顯示出來的結果可以看出當前交易的一些內容。例如,from資料項就是我們傳送交易的地址,input就是合約編譯完成的位元組碼,這些內容均與我們之前的設定相同。而且,我們可以看到新的交易建立在第2016號區塊中。
與此同時,我們也可以檢視一下剛才在新的終端中建立的挖礦日誌。我們在日誌中找到這樣的一行資訊:

這裡寫圖片描述

這說明交易已經發送到區塊鏈中了,正在等待礦工的確認。

(6)啟動挖礦:miner.start()

這裡寫圖片描述

控制檯提示Contract mined,則合約被建立成功,並返回合約的地址(address)和此次交易的雜湊值。可通過這兩個數值在區塊鏈上尋找合約的資訊。

(7)我們發現交易池已經沒有待確認的交易了。我們使用eth.getBlock(2016)命令檢視第2016號區塊的資訊:eth.getBlock(2016)

這裡寫圖片描述

我們發現hash值為0xa20f32030e6114002da1e8c8645023ee02ad43a18dde34f43c916bddc886bc5e的交易確實在第2016號區塊中。

呼叫智慧合約

(1)在部署合約所使用的控制檯視窗下,可直接使用合約名和函式名呼叫合約。假設一個使用者想為1號商品打3分,需要呼叫rating合約的setRating函式,需要執行以下命令:(我這裡是rating,是因為我上面編譯合約的程式碼賦值給rating,這裡這裡要根據自己編譯完合約的程式碼而定)

rating.setRating.sendTransaction(1, 3, {from: personal.listAccounts[0]})

如果出現下面紅色的錯誤,重新解鎖賬戶
這裡寫圖片描述

由於使用者需要發起一個交易並改變區塊鏈的狀態,因此需要用到合約物件的sendTransaction()方法來發起交易。該方法的前幾個引數為setRating函式的引數,最後一個引數為發起交易的地址,也就是需要為本次交易支付費用的賬戶的地址。這裡personal.listAccounts[0]代表錢包內的第1個賬戶,即基準賬戶MAIN ACCOUNT:

"0x3c194bcba9c3b90028fdd22aaad4f4c8973781835c15c57d3879dc5c1c743760"

(2)經過一段時間的確認,該交易被儲存到區塊鏈中,此時可使用rating合約中的ratings陣列來顯示1號商品的打分,其命令如下:rating.ratings(1)

這裡寫圖片描述

這時將會顯示3,表示1號商品被打了3分。由於此時並不需要改變區塊鏈系統的狀態,因此不需要使用sendTransaction方法,也就不需要支付任何費用。

(3) 如果想在其他以太坊節點通過控制檯呼叫合約,則需知道合約的地址和介面。執行以下命令例項化合約物件:var NewRatingContract = eth.contract(interface).at(“address”) 這裡,interface的資訊可從Solidity線上編輯器上獲得,而address在合約部署之後返回得到。之後,使用NewRatingContract.ratings(1)命令就可查詢到1號商品的打分。例如我的:

var NewRatingContract = eth.contract([{"constant":false,"inputs":[{"name":"_key","type":"bytes32"},{"name":"_value","type":"uint256"}],"name":"setRating","outputs":[],"type":"function"},{"constant":true,"inputs":[{"name":"","type":"bytes32"}],"name":"ratings","outputs":[{"name":"","type":"uint256"}],"type":"function"}]).at("0x133e80139ce46615a777ba26f5ee2a39ee709df1")

找到interface資訊:
這裡寫圖片描述

找到address資訊:
這裡寫圖片描述

(3)查詢打分:
這裡寫圖片描述

參考