區塊鏈100講:以太坊開發環境部署(附代碼)

image

注:本文的運行環境爲MacOS。javascript

1

安裝

brew tap ethereum/ethereum brew install ethereumjava

完成以後,經過如下命令驗證:git

geth version

2

運行

所謂運行,是指運行一個節點並加入以太坊網絡,它有兩個選擇:公鏈和測試鏈,這兩個網絡都在互聯網上。github

2.1 公鏈web

geth --fast --cache=512 --datadir "你的目錄" consolenpm

2.2 測試鏈編程

geth --testnet --fast --cache=512 --datadir "你的目錄" consolejson

這兩種方式都須要同步區塊,它們存放於datadir指定的目錄之下,所以請確保有足夠的空間。api

3

搭建私鏈

搭建私鏈的目的主要是出於測試的目的,不建議搭建以運營爲目的的私鏈。整個步驟以下:安全

**3.1 編寫genesis.json,定義初始信息。**內容示例以下:

{

    "config": {

        "chainId": 20,

        "homesteadBlock": 0,

        "eip155Block": 0, 

       "eip158Block": 0

    },

    "alloc": {

        "0xeb680f30715f347d4eb5cd03ac5eced297ac5046": {

            "balance":"100000000000000000000000000000000"

        }

    }, 

   "coinbase": "0x0000000000000000000000000000000000000000",   

 "difficulty": "0x01",

    "extraData": "0x777573686f756865",

    "gasLimit": "0xffffffff",

    "nonce": "0x0000000000000001", 

   "mixhase": "0x0000000000000000000000000000000000000000000000000000000000000000", 

   "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000", 

   "timestamp": "0x00"

}

3.2 初始化

geth --datadir "your dir" init genesis.json

3.3 啓動,見到小錘子後,表示已經開始挖礦。

geth --datadir "你的目錄" --rpc --rpcaddr=0.0.0.0 --rpcport 8545 --rpccorsdomain "*" --rpcapi "eth,net,web3,personal,admin,shh,txpool,debug,miner" --nodiscover --maxpeers 30 --networkid 1981 --port 30303 --mine --minerthreads 1 --etherbase "0xeb680f30715f347d4eb5cd03ac5eced297ac5046" console

這裏須要注意的是,在此命令行下「ctrl-c」並不會終止進程。若是要終止運行,在命令行下輸入「exit」。

geth還提供了控制檯,輸入以下命令可進入:

geth --datadir "你的目錄" attach ipc:你的目錄/geth.ipc

該控制檯提供的接口包括:帳戶、交易、合約調用、區塊。

4

智能合約

本節以vscode爲IDE,geth-cli簡要說明智能合約的開發過程。

4.1 環境準備

安裝語言包

brew install solidity

準備IDE插件

https://github.com/juanfranblanco/vscode-solidity,進入「擴展」,搜索「solidity」,第一個就是。

4.2 合約開發

編輯(simpledata.sol),內容以下:

pragma solidity ^0.4.23;

contract SimpleData {

    uint data;

    function set(uint x) public{

        data = x;

    }

    function get() view public returns (uint) {

        return data;

   }

}

編譯

echo "var output=solc --optimize --combined-json abi,bin,interface simpledata.sol" > simpledata.js

部署(利用前面搭建好的私鏈)

  • 啓動私鏈

  • 進入控制檯,如下全部步驟均在控制檯裏完成,採用js語法。

  • 加載編譯過的js:

loadScript('.../simpledata.js')

  • 獲取部署須要的相關參數,其中output爲上面「編譯」步驟中定義的output:
var contractAbi = output.contracts['simpledata.sol:SimpleData'].abi

var contract = eth.contract(JSON.parse(contractAbi))

var binCode = "0x" + output.contracts['simpledata.sol:SimpleData'].bin
  • 建立用戶,同時讓其帳戶有餘額(部署也是要花錢的):
personal.newAccount("123456")  // 參數爲密碼

miner.setEtherbase(eth.accounts[0])  // 設置建立的用戶爲礦工

web3.fromWei(eth.getBalance(eth.accounts[0]), "ether") // 查看餘額
  • 發佈
var deployTx = { from: eth.accounts[0], data: binCode, gas: 1000000};

var instance = contract.new(deployTx)

var contractAddress = eth.getTransactionReceipt(instance.transactionHash).contractAddress // 合約地址

調用(仍在同一條私鏈上,一樣在控制檯執行)

var simpleData = contract.at(contractAddress)

simpleData.get.call()

personal.unlockAccount(eth.accounts[0]) // 此步必需

simpleData.set.sendTransaction(33, {from: eth.accounts[0], gas: 100000})

simpleData.get.call()

此處須要注意的有兩點:

  • 鏈上的變動經過交易完成,同時執行合約是有代價的,即gas,這是與傳統開發很大的不一樣。也是爲什麼前面在部署以前先建立用戶,並將其設置爲礦工,得到餘額的緣由。

    注意:gas和eth不是一類東西,合約最終消耗的eth由:步驟和gasPrice來決定。

  • 執行交易以前須要先解鎖帳戶,這相似我們在用網銀時轉帳前須要輸入「取款密碼」。同時,解鎖是有時限的,爲了不頻繁解鎖能夠用下面的語句:

personal.unlockAccount(eth.accounts[0], 密碼, 時限)

這裏出現了交易,所以也說明一下安全性的問題:

  • 以太坊上全部的交易都是公開可查看的,全部交易歷史能夠經過Etherscan看到。

  • 全部交易執行都是要用發起者的私鑰簽名的,所以只要私鑰能獲得妥善保存,就不會有什麼大問題。在上面的步驟中沒有出現用私鑰簽名,這是由於帳戶自己是由控制檯建立的,在建立的同時也建立了相應的公鑰和私鑰。

5

Truffle框架

能夠看得出上面的整個過程至關繁瑣,Truffle則正是爲解決這些問題而生的。

安裝

npm install -g truffle

開發部署

  • mkdir dapp

  • cd dapp

  • truffle init

  • 進入contracts目錄,建立下面的文件

pragma solidity ^0.4.23;

contract Storage {

    uint256 storageData;

    function set(uint256 data) public {

        storageData = data;

    } 

   function get() view public returns (uint256) {

        return storageData;

    }

}
  • truffle compile

  • 合約的部署經過migration完成,假如用過諸如liquidbase之類的dbmigration工具,對此應該不陌生。進入migrations目錄,建立相應的文件,以「數字_」開頭,如「2_deploy_storage.js」。內容以下:

var Storage = artifacts.require("Storage");

module.exports = function(deployer) {

   deployer.deploy(Storage);
}
  • 搭建開發用的測試鏈,ganache,由於它的速度比前面自行搭建的私鏈更快。

npm install -g ganache-cli  // 安裝

ganache-cli //運行

  • 在部署以前,修改truffle.js內容(其中networks可定義各類網絡,其客觀上起到了相似「環境」的做用):
module.exports = {

  networks: {

    development: {

      host: "127.0.0.1",

      port: 8545,

      network_id: "*" // Match any network id

    }

  }

};
  • truffle migrate

至此,部署完畢,讓咱們手動測試一下。

6

利用JSON-RPC手工調用合約

JSON-RPC接口能夠用curl完成,其特色在於:合約的方法是rpc請求的數據。若是以爲這有點拗口,不妨將這種方式與利用Java Reflection來調用某個類的方法作類比。

要調用上面的合約,首先須要得到合約方法(get和set)的簽名:

get方法

curl -X POST -i http://localhost:8545 --data '{

 "jsonrpc":"2.0",

  "method":"web3_sha3",

  "params":["get()"], 

 "id":1

}'

**set方法**

curl -X POST -i http://localhost:8545 --data '{

 "jsonrpc":"2.0",

  "method":"web3_sha3",

  "params":["set(uint256)"],

  "id":1

}'

方法簽名利用「web3_sha3」獲得,其簽名爲返回值的0x後的8位。上面兩個調用對應的結果以下:

  • get:6d4ce63c

  • set:60fe47b1

調用合約須要合約的地址,這個值能夠從ganache終端中得到。在其終端輸出中查找相似下面的語句,其中created以後的即爲地址。

Contract created: 0x59322f0c1235719b4c0044b0c67f2437674b8c69

剩下的就是合約調用了(其中from帳戶直接使用ganache啓動時初始化的帳戶,to爲合約地址):

get方法

curl -X POST -i http://localhost:8545 --data '{

  "jsonrpc":"2.0", 

 "method":"eth_call", 

 "params":[ 

    {       "from":"0x2fe84a7fb107ade77adfeb351b92615597b68f52",     "to":"0x59322f0c1235719b4c0044b0c67f2437674b8c69",      

"data":"0x6d4ce63c0000000000000000000000000000000000000000000000000000000000000000"

     }, 

    "latest"

  ],

  "id":1

}'

set方法

curl -X POST -i http://localhost:8545 --data '{ 

 "jsonrpc":"2.0", 

 "method":"eth_sendTransaction",

  "params":[ 

    {       "from":"0x2fe84a7fb107ade77adfeb351b92615597b68f52",       "to":"0x59322f0c1235719b4c0044b0c67f2437674b8c69",       "gas":"0xc350", 

      "gaslimit":"0xc350",       "data":"0x60fe47b10000000000000000000000000000000000000000000000000000000000000005" 

    }

  ],

  "id":1

}'

注意兩次調用的「method」的不一樣。同時,「data」參數中的0x後的前8位爲對應的方法簽名,後面則爲實際傳入到對應方法的數據。

7

編程接口

若是要在js文件中與智能合約交互,則須要相應的包:

  • web3.js,其封裝了json-rpc接口

  • truffle-contract模塊,truffle的合約抽象

8

自動化測試

truffle支持兩類自動化測試:使用javascript和使用solidity,都至關簡單,這裏再也不贅述。測試文件統一放在test目錄下,測試命令:

truffle test  // 所有測試
truffle test 文件  // 單個測試

9

包管理

js包用普通的npm,略

智能合約的包用ethpm

truffle install 包名 truffle publish 包名

10

參考

Trufflehttps://truffleframework.com/)

solidityhttps://solidity.readthedocs.io/en/v0.4.24/)

《區塊鏈開發實戰:以太坊關鍵技術與案例分析》,部份內容過期,好比TestRPC目前已經被Ganache替代。

本文做者:HiBlock區塊鏈技術佈道羣-胡鍵

原文發佈於簡書

原文連接:https://www.jianshu.com/p/bec173e6cf73

加微信baobaotalk_com,加入技術佈道羣

線下活動推薦

技術工坊|如何利用ERC875協議開發世界盃區塊鏈門票?(北京)

相關文章
相關標籤/搜索