本地搭建以太坊(Ethereum)詳細教程
本篇教程旨在自己的電腦上安裝配置以太坊開發環境,搭建以太坊私有鏈,編寫一個簡單的智慧合約,通過以太坊JSON RPC和JavaScript API程式設計介面將其部署到所建立的以太坊私有鏈,並可呼叫合約獲得正確的合約執行結果。
一、以太坊開發環境搭建
1.1 Mac OS X系統安裝go環境
官網連結:https://golang.org/dl/
官網下載最新的穩定版本:go1.11.2.darwin-amd64.pkg,直接雙擊完成安裝,安裝目錄在/usr/local/go/下。
配置環境變數:
vim ~/.bash_profile
export PATH=$PATH:/usr/local/go/bin
檢視是否配置成功
go version
go version go1.11.2 darwin/amd64
1.2 安裝Node.js、Npm
官網連結:https://nodejs.org/en/download/
檢視是否安裝成功
node -version或node –v
NPM是隨同NodeJS一起安裝的包管理工具。
npm -version或npm -v
1.3 以太坊Ethereum安裝
apt install ethereum
檢視以太坊是否安裝成功
geth version
1.4 solc編輯器安裝
npm install -g solc
檢視solc支援的功能
solcjs --help
注意:solcjs命令與Solidity編譯器提供的solc包並不相容,因此不能通過eth.compile.solidity() RPC的方式與以太坊客戶端結合使用。
二、以太坊整合開發環境
建立賬戶
geth account new
輸入兩遍密碼後,生成賬戶地址。
以太坊賬戶地址 528301230cb94d1649534b13e991be243780d3bd
檢視賬戶
geth account list
初始化創世塊檔案
geth --datadir "./" init genesis.json
注意:"./"表示以太坊的路徑。
執行以太坊私有鏈,首先要定義自己的創世區塊,創世區塊資訊寫在一個 JSON 格式的配置檔案中,即genesis.json。
其中,chainID指定了獨立的區塊鏈網路ID。網路ID在連線到其他節點的時候會用到,以太坊公網的網路ID是1,為了不與公有鏈網路衝突,執行私有鏈節點的時候要指定自己的網路ID。不同ID網路的節點無法相互連線。配置檔案還對當前挖礦難度difficulty、區塊Gas消耗限制gasLimit等引數進行了設定。
啟動以太坊
geth --datadir "./" console
啟動挖礦
miner.start()
其中start可以設定引數,表示挖礦使用的執行緒數。第一次啟動挖礦會先生成挖礦所需的DAG檔案,等進度達到100%後,就會開始挖礦。
停止挖礦
miner.stop()
挖礦所得的獎勵會進入礦工的賬戶,這個賬戶叫做coinbase,預設情況下coinbase是本地賬戶中的第一個賬戶,可以通過miner.setEtherbase()將其他賬戶設定成coinbase。另外注意第一次停止挖礦需要一段時間,因為節點需要為工作證明演算法生成1GB資料集。
三、以太坊程式設計介面
3.1 通過json rpc編譯合約
curl --data '{"jsonrpc":"2.0","method": "eth_compileSolidity", "params": ["contract Multiply7 {event Print(uint);function multiply(uint input) returns (uint) {Print(input * 7);return input * 7;}}"], "id": 5}' localhost:8545
提示 port 8545: Connection refused
開啟rpc埠
geth --datadir "./" --rpcport "8545" --rpc console
開啟8545埠後執行編譯指令
curl --data '{"jsonrpc":"2.0","method": "eth_compileSolidity", "params": ["contract Multiply7 {event Print(uint);function multiply(uint input) returns (uint) {Print(input * 7);return input * 7;}}"], "id": 5}' localhost:8545
提示 only application/json is supported
新增頭部後執行編譯指令
curl -H "Content-Type: application/json" --data '{"jsonrpc":"2.0","method": "eth_compileSolidity", "params": ["contract Multiply7 {event Print(uint);function multiply(uint input) returns (uint) {Print(input * 7);return input * 7;}}"], "id": 5}' localhost:8545
提示 eth_compileSolidity is not available
新版本中已不能通過json rpc部署合約,官方推薦用Remix進行合約的部署任務。
3.2 通過JavaScript API編譯合約
定義合約
var source = 'contract Multiply7 {event Print(uint);function multiply(uint input)
returns (uint) {Print(input * 7);return input * 7;}}'
編譯合約
var compiled = web3.eth.compile.solidity(source)
提示 eth_compileSolidity is not available
3.3 通過線上Remix web3編譯合約
var multiply7Contract = web3.eth.contract([{"constant":false,"inputs":[{"name":"input","type":"uint256"}],"name":"multiply","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"anonymous":false,"inputs":[{"indexed":false,"name":"","type":"uint256"}],"name":"Print","type":"event"}]);
var multiply7 = multiply7Contract.new(
{
from: web3.eth.accounts[0],
data: '0x608060405234801561001057600080fd5b5060f58061001f6000396000f300608060405260043610603f576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063c6888fa1146044575b600080fd5b348015604f57600080fd5b50606c600480360381019080803590602001909291905050506082565b6040518082815260200191505060405180910390f35b60007f24abdb5865df5079dcc5ac590ff6f01d5c16edbc5fab4e195d9febd1114503da600783026040518082815260200191505060405180910390a16007820290509190505600a165627a7a723058201d5375a8266e2b7567b08952c4bc14f1536831ea67d18c9f6046297b3540f53b0029',
gas: '4700000'
}, function (e, contract){
console.log(e, contract);
if (typeof contract.address !== 'undefined') {
console.log('Contract mined! address: ' + contract.address + ' transactionHash: ' + contract.transactionHash);
}
})
合約部署
合約地址
INFO [10-15|16:24:29.097] Submitted contract creation fullhash=0x281bc3c1169db4a96172c7c6a73e2642f31fe4195934a97bf4a0416acc2cfcfa contract=0xb7bdeBf286e03793382f3F1Bd4E8Fd32D99D9377
null [object Object]
檢視multiply7合約
multiply7
呼叫call()測試合約函式結果
multiply7.multiply.call(uint);
發起交易之前解鎖賬戶
personal.unlockAccount(eth.coinbase)
發起交易
multiply7.multiply.sendTransaction(7,{from:eth.accounts[0],gas:200000})
獲取交易hash 0x831354bf01a9a2033701b17537915b71273420005a43372053ffa8e37f4dd4e9
檢視交易
eth.getTransaction("0x831354bf01a9a2033701b17537915b71273420005a43372053ffa8e37f4dd4e9")
3.4 通過線上Remix編譯部署合約
本地私有鏈監聽的RPC埠
OK提示 is open (via IPC or RPC)
以web方式連線私有鏈,必須開啟–rpccorsdomain引數
設定IP請求白名單 * 為所有
geth --datadir "./" --rpcport "8545" --rpccorsdomain "*" --rpc console
成功後讀取Account列表
部署資訊
控制檯檢視合約部署的合約地址
發起交易
curl -H "Content-Type: application/json" -X POST --data '{"jsonrpc":"2.0", "method": "eth_sendTransaction", "params":[{"from":"0x528301230cb94d1649534b13e991be243780d3bd", "to":"0x1269e13d9df9f64b9cbf0bdfaf0dcb0e67f4cf06", "data":"0xc6888fa10000000000000000000000000000000000000000000000000000000000000006"}], "id": 8}' localhost:8545
交易提交
檢視交易
eth.getTransaction("0x596477fd2d977bc67d5bea5e5146d95fff2fd141a04085e42ae34e9d3ca60759")