以太坊私鏈與智慧合約部署入門教程

買賣虛擬貨幣
一、環境配置和程式安裝

1.1 安裝 geth

mac osx

首先確保已安裝 homebrew,沒有安裝過的可以在命令列下執行/usr/bin/ruby -e "$(curl -fssl https://raw.githubusercontent.com/homebrew/install/master/install)" 進行安裝
brew tap ethereum/ethereum
brew install ethereum

windows

訪問 https://geth.ethereum.org/downloads/
下載並安裝 geth for windows

linux

git clone https://github.com/ethereum/go-ethereum
sudo apt-get install -y build-essential golang
cd go-ethereum
make geth

在命令列下輸入 geth -h , 有如下回顯表示成功


1.2 安裝 solc

首先確保安裝過npm, 沒有安裝過的可以訪問 npm網站下載安裝
npm install -g solc
在命令列下輸入 solc --help , 有如下回顯表示成功


二、配置私鏈節點

2.1 創世塊設定

新建資料夾,命名隨意,在此資料夾下建立genesis.json檔案和data資料夾
genesis.json 的內容如下:

{
"config": {
       "chainid": 123456,
       "homesteadblock": 0,
       "eip155block": 0,
       "eip158block": 0
},
"nonce": "0x0000000000000042",
"difficulty": "0x020000",
"mixhash": "0x0000000000000000000000000000000000000000000000000000000000000000",
"coinbase": "0x0000000000000000000000000000000000000000",
"timestamp": "0x00",
"parenthash": "0x0000000000000000000000000000000000000000000000000000000000000000",
"extradata": "0x11bbe8db4e347b4e8c937c1c8370e4b5ed33adb3db69cbdb7a38e1e50b1b82fa",
"gaslimit": "0x4c4b40",
"alloc": {}
}


2.2 初始化

在命令列下進入剛才建立的資料夾,輸入如下命令:
geth --datadir data init genesis.json

各引數代表的含義如下:

init 表示初始化區塊,後面跟著創世塊的配置檔案genesis.json
datadir 資料存放的位置

2.3 啟動節點

geth --datadir data --networkid 123456 --rpc --rpccorsdomain "*" --nodiscover console

各引數代表的含義如下:

networkid 設定當前區塊鏈的網路id,用於區分不同的網路,1表示公鏈
rpc 表示啟動rpc通訊,可以進行智慧合約的部署和除錯
console 表示啟動命令列模式,可以在geth中執行命令

執行成功後將進入區塊鏈的javascript控制檯環境


2.4 geth javascript控制檯環境使用說明

建立新賬號
personal.newaccount()
或者 personal.newaccount("123456")

檢視節點資訊
admin.nodeinfo

挖礦
開始挖礦 miner.start(1)
停止挖礦 miner.stop()

檢視當前礦工賬號
eth.coinbase 預設為第一個賬戶

修改礦工賬號
miner.setetherbase(eth.accounts[1])

檢視賬戶資訊
eth.accounts[0]

檢視賬戶餘額
eth.getbalance(eth.accounts[0])
或者 web3.fromwei(eth.getbalance(eth.accounts[0]), "ether")

解鎖賬號
personal.unlockaccount(eth.accounts[0])
使用賬戶資金前都需要先解鎖賬號

轉賬eth.sendtransaction({from:eth.accounts[0],to:"0x587e57a516730381958f86703b1f8e970ff445d9",value:web3.towei(3,"ether")})
使用 txpool.status 可以看到交易狀態

檢視區塊資料
eth.blocknumber
eth.gettransaction("0x0c59f431068937cbe9e230483bc79f59bd7146edc8ff5ec37fea6710adcab825")
eth.getblock(1) 透過區塊號檢視區塊

三、智慧合約

3.1 編輯合約程式碼

建立一個 token.sol 檔案,內容如下:

contract token {
   address issuer;
   mapping (address => uint) balances;

   event issue(address account, uint amount);
   event transfer(address from, address to, uint amount);

   function token() {
       issuer = msg.sender;
   }

   function issue(address account, uint amount) {
       if (msg.sender != issuer) throw;
       balances[account] += amount;
   }

   function transfer(address to, uint amount) {
       if (balances[msg.sender] < amount) throw;

       balances[msg.sender] -= amount;
       balances[to] += amount;

       transfer(msg.sender, to, amount);
   }

   function getbalance(address account) constant returns (uint) {
       return balances[account];
   }
}

這份程式碼實現了一個簡單的token合約功能。
issue 函式可以向充值以太到合約賬戶
transfer 函式可以向其他賬號傳送token
getbalance 函式可以獲取某個賬號的token餘額

3.2 編譯與部署

壓縮合約程式碼
命令列下執行 cat token.sol | tr '\n' ' '
這條命令將程式碼中的換行符替換成空格,這樣我們的程式碼就只有一行了。命令執行成功後將回顯複製下來。

將合約程式碼儲存為一個變數
回到geth javascript 控制檯,執行如下命令,等於號後面的內容就是我們剛才複製下來的壓縮後的合約程式碼。

var tokensource = 'contract token { address issuer; mapping (address => uint) balances; event issue(address account, uint amount); event transfer(address from, address to, uint amount); function token() { issuer = msg.sender; } function issue(address account, uint amount) { if (msg.sender != issuer) throw; balances[account] += amount; } function transfer(address to, uint amount) { if (balances[msg.sender] < amount) throw; balances[msg.sender] -= amount; balances[to] += amount; transfer(msg.sender, to, amount); } function getbalance(address account) constant returns (uint) { return balances[account]; } }';

編譯
var tokencompiled = eth.compile.solidity(tokensource);

若不成功,請參考https://ethereum.stackexchange.com/questions/15435/how-to-compile-solidity-contracts-with-geth-v1-6提供的替代方案

檢視二進位制程式碼
tokencompiled['<stdin>:token'].code

檢視abi
tokencompiled['<stdin>:token'].info.abidefinition

建立合約物件
var contract = eth.contract(tokencompiled['<stdin>:token'].info.abidefinition);
var initializer = {from: web3.eth.accounts[0], data: tokencompiled['<stdin>:token'].code, gas: 300000};
var token = contract.new(initializer)

輸入命令 token 可以看到此時的token有transactionhash 但是沒有address
執行 miner.start(1) 一段時間後停止,我們的合約就釋出到了鏈上

3.3 與合約進行互動

充值

personal.unlockaccount(eth.accounts[0])
token.issue.sendtransaction(eth.accounts[0], 100, {from: eth.accounts[0]});
miner.start(1)
miner.stop()

傳送 token

token.transfer(eth.accounts[1], 30, {from: eth.accounts[0]})
miner.start(1)
miner.stop()

檢視餘額

token.getbalance()

三、qtum

目前qtum的智慧合約完全相容現有 solidity 語法,以太坊中的合約指令碼可以輕鬆移植到qtum中,新一代智慧合約語言 esml 也在穩步開發中。

qtum 將以太坊 evm 搭建在比特幣 utxo 架構上,透過輕錢包就可以登入evm。輕錢包採用spv協議,使用者可以與區塊鏈網路互動,並驗證各自交易資訊,不用下載及同步完整區塊鏈。合併改進版本的比特幣核心基礎架構和可以相互相容的以太坊虛擬機器版本,使得量子鏈既擁有比特幣堅不可摧的區塊鏈網路又能發揮智慧合約的無限可能。

四、參考文獻

以太坊學習筆記:私有鏈搭建操作指南
ethereum go
以太坊本地私有鏈開發環境搭建
ethereum-bootstrap
https://github.com/ethereum/go-ethereum/wiki/private-network

免責聲明:

  1. 本文版權歸原作者所有,僅代表作者本人觀點,不代表鏈報觀點或立場。
  2. 如發現文章、圖片等侵權行爲,侵權責任將由作者本人承擔。
  3. 鏈報僅提供相關項目信息,不構成任何投資建議

推荐阅读

;