6.2 以太坊應用

xiaohuanglv發表於2018-08-24

6.2.1 測試鏈與私鏈

以太坊屬於公有鏈,官方不但提供了主鏈,也提供了測試鏈,然而對於想要更進一步理解以太坊結構的讀者,就有些不方便了,如果是在主鏈上進行操作使用,則有如下一些問題:

1)以太坊上的轉賬交易或者智慧合約部署等都需要消耗以太幣,顯然不適合開發測試的需求;

2)以太坊公鏈的執行節點遍佈全球,即便是使用測試鏈,執行速度也是無法達到實驗級的要求的,而且不方便去控制網路中的每一個節點;

3)對於公鏈的使用,只是通過客戶端直接去連線使用,但看不到網路具體是怎麼搭建起來的,很多細節看不到;

4)若在某些場合下只是希望使用以太坊來搭建一個區域性的網路,類似於區域網,那肯定不能直接使用公鏈。

基於以上原因,我們有必要自己搭建一個測試鏈,由於這個測試鏈通常執行在使用者自己的區域網路中,一般情況下並不會 開放到公網中,因此這種測試鏈也稱為私有鏈,在本節,我們就來演示一下如何使用以太坊客戶端搭建私有鏈,下面的過程是在Mac OS上完成的,若在Linux或者Windows上操作,過程都是一樣的。

工欲善其事,必先利其器,要搭建私有鏈,自然先要準備好工具,準備材料如下:

1)以太坊核心客戶端可以到官網下載,我們使用官方推薦的Go語言版本geth,下載版本為1.6.5,為了操作方便,可以將geth放到系統的環境變數目錄下。注意,由於是Go語言版本,因此務必保證本機已經安裝了Go的執行環境;

2)建立一個配置私有鏈的資料目錄,我們命名為ethprivate;

3)準備一份創世區塊的初始化檔案,我們命名為genesis.json,放到ethprivate目錄中,其內容如下:


{
"config": {
       "chainId": 15,
       "homesteadBlock": 0,
       "eip155Block": 0,
       "eip158Block": 0
   },
   "difficulty": "200000000",
   "gasLimit": "2100000",
   "alloc": {
       "7df9a875a174b3bc565e6424a0050ebc1b2d1d82": { "balance": "300000" },
       "f41c74c9ae680c1aa78f42e5647a62f353b7bdde": { "balance": "400000" }
   }
}


可以看到,主要配置了初始的難度值以及兩個初始的錢包地址及其餘額,這些值大家可以根據自己的需要自行設定。這裡需要注意,如果使用的geth客戶端版本不是1.6.x而是1.5.x(如1.5.9),則配置檔案中不能有config段,否則會出錯。

接下來建立私有鏈了,建立的過程相當簡單,進入到ethprivate目錄中,執行如下命令:


geth --datadir "./" init genesis.json


命令中,通過datadir引數指定了資料目錄,這裡指定的是當前所在的目錄也就是ethprivate目錄,執 行完命令後,可以在ethprivate目錄下看到生成了兩個子目錄:一個是geth;一個是keystore。建立完畢後,我們就可以啟動這個私有鏈 了,命令如下:


geth --datadir "./" --networkid 989898 --rpc console --port 0


可以看到這裡指定了networkid,並且開啟了rpc服務,當然引數還不止這些,更多的引數應用可以檢視geth命令的使用幫助。如果要指定埠,可以如下執行啟動命令:


geth --datadir "./" --networkid 989898 --rpc console --port 30304 --rpcport 8546


啟動成功後預設會進入到命令控制檯,可以通過命令與私有鏈節點進行訪問,我們可以通過 admin.nodeInfo命令檢視節點摘要資訊。注意,我們現在只是啟動了一個節點,如果還需要啟動第二個節點,步驟跟上述一樣,另外建立一個新檔案 夾,將genesis.json複製到目錄中,然後同樣執行初始化,以及啟動節點命令即可,需要注意的是,要指定不同的埠,否則可能會導致埠占用衝 突。若建立多個節點,則節點之間可以通過admin.addPeer連線,在本機啟動多個節點或者在不同的計算機上執行多個節點都可以,這樣可以模擬出一 個私有鏈網路。

在節點啟動後的控制檯中,可以進行各種操作,實際上就是呼叫以太坊節點的RPC服務,比如新建一個賬戶地址,可以使用如下命令:


personal.newAccount


建立賬號後,就可以啟動挖礦了,挖礦命令如下:


//啟動挖礦
miner.start()

//停止挖礦
miner.stop()


一定要注意,如果希望某個節點上的運算元據要寫入到區塊,並且同步到網路中的其他節點,必須要啟動挖礦,挖礦就是一個區塊打包和傳播同步的過程,同時也只有啟動挖礦,才能讓私有鏈中的主賬號獲得以太幣,進而可以用來繼續測試轉賬交易、合約部署、合約呼叫等功能。

有讀者可能會覺得這種配置私有鏈的方式還是有些麻煩。對於想快速方便進行測試使用以及智慧合約開發的讀者,還有一 種配置私有鏈的方式,那就是使用TestRPC與Truffle組合。TestRPC是在本地使用記憶體模擬的一個以太坊環境,可以用於搭建測試環境,基於 Node.js開發,因此使用TestRPC首先要安裝Node.js環境並且版本要大於6.9.1。Truffle是針對以太坊智慧合約應用的一套開發 框架。我們來看下具體如何搭建。

1)使用npm安裝TestRPC,命令如下:


sudo npm install -g ethereumjs-testrpc


2)安裝完畢後,可以輸入如下命令檢視版本資訊:


testrpc –version


3)執行後輸出如下資訊:


EthereumJS TestRPC v3.0.5

Available Accounts
==================
(0) 0xb43333d44136f351fd30d20215490432e0f3968d
(1) 0x34f73354540fa4b653bf33568c7ba9f69ad6c84d
(2) 0x047bf66a5be28bb84502f3baaa40b10cb04d44e8
(3) 0x1dc4d3ce33b05e24219f93f28612b9a80e2724de
(4) 0xaa82bb04532d560139eeae495fc6d00706dbc7f7
(5) 0xe2ee5d9e955277b6f5e13d10beb686e069859731
(6) 0xfe023592bc7bbb7dac6051950a0b8774206c1f5b
(7) 0x34b1b1b6a36348912be0b943e3f34db38339a192
(8) 0x860638afa0bbecf8ea5c5808e95108710ec92acc
(9) 0xd7a701bd9cffbf887b1e3f03ac91c68ead3032ec

Private Keys
==================
(0) 6e94ed2e32818d2bb1d58bd0119407096691ec683ed8a43a2975ff6003bb1924
(1) ccc8fca886b7666c0e2707cc9a429d4a1c941dd170b8c0f5f55c71ce966fa835
(2) d0ba307ed8ff2ec12deeb59d0c85884d74735b8ab26329e74cb37966f656634b
(3) c057235669dd341ebb4ce1185b469eeac3d1cd2f763e95aa36e0e22adaa9ce84
(4) 7c6d6a7268fd9f76d2868f650168ba67a2901d427de85357b6a453dfad784db4
(5) 2baaacc4818dfc605b0c91ba5418826a86c09b375861123aa393d7411cce6595
(6) 147d63765df501f94179514459660502b00692b4aab0dfcc2316aea9fc0877dd
(7) bbded13290bcefc551d1cc9bf36921a2e65024b03401014388a6ce52c2159494
(8) 53df9b7d172746d9a0a548f62bc1d21ca78bd6202456221241b36a7fa1cf3b91
(9) 03691c7d31ce9b041d2a66bdc48397b13660f097164d443e3f8ba3f09ae9272e

HD Wallet
==================
Mnemonic:      trade target identify fun bleak wish sphere emotion journey rose decide above
Base HD Path:  m/44’/60’/0’/0/{account_index}

Listening on localhost:8545


可以看到,預設就自動配置了10個賬戶地址。注意,以上資訊是動態的,每次啟動時隨機生成,不是固定的。通過最後一行資料的提示,表明TestRPC啟動後使用8545埠監聽。

4)同樣使用npm安裝Truffle,命令如下:


sudo npm install –g truffle


5)安裝成功後,輸入truffle--version,輸出如下:

image.png

可以看到,輸出了版本資訊v3.2.5,並且在下面列出了各種可以使用的命令。

6)安裝solc:


sudo npm install -g solc


注意,安裝後的命令是solcjs,這是用來編譯智慧合約程式碼的。

7)執行測試

首先執行TestRPC,在命令列中直接通過testrpc命令可以啟動,接著開始初始化Truffle目錄,命令如下:


mkdir mytruffle && cd mytruffle
truffle init webpack


這個命令其實就是下載一個專案框架,也可以直接通過網址https://github.com/trufflesuite/truffle-init-webpack下載壓縮包後解壓縮,複製到相應目錄,效果是一樣的。初始化命令執行後,輸出如下資訊:

image.png

提示資訊很簡單,就是下載專案框架後進行初始化,初始化完成後,在目錄中生成了如下檔案:

image.png

其中,contracts中存放的是合約,truffle compile進行編譯的時候就會在這裡面尋找合約檔案,migrations目錄裡面存放的是JavaScript檔案,它幫助部署合約到以太坊網路 中,它們表示了進行部署任務的步驟,truffle.js檔案內容如下:


module.exports = {
 networks: {
   development: {
     host: "localhost", //節點地址,如果是私有鏈,一般是本機
     port: 8545,  //節點RPC埠
     network_id: "*" //自定義網路號
   }
 }
};


預設的配置與testrpc的引數是一致的,也可以根據需要修改。

8)啟動了testrpc,也初始化了truffle,現在開始試著編寫合約。可以看到在contracts中已經有幾個示例合約了,不用管,建立一個MyCalc.sol,原始碼如下:


pragma solidity ^0.4.11;
contract MyCalc {
 function SumAdd(uint a) returns(uint d) {
   return a + 100;
 }
}


這是一段非常簡單的程式碼,合約名為MyCalc,其中包含了一個方法SumAdd,通過傳入一個整數引數,返回一 個加上100的值,這就是一份智慧合約,智慧合約並沒有我們想象得那麼複雜,與傳統應用軟體開發最大的區別就是,編寫的合約一旦部署到以太坊上,就會被同 步到每一個節點中,由整個以太坊網路的基礎設施來確保合約的剛性執行以及不可篡改性。我們先來看下這份編寫的合約如何部署執行,程式碼編寫完畢後就可以進行 編譯了,以太坊中的智慧合約都執行在EVM(Ethereum Virtual Machine,以太坊虛擬機器)上,必須首先被編譯為EVM能識別的位元組碼。

9)回到mytruffle的目錄中,進行編譯,執行如下命令:


sudo truffle compile


10)編譯若沒有問題,則會有如下提示:


Compiling ./contracts/MyCalc.sol...
Writing artifacts to ./build/contracts


11)可以看到生成了一個build目錄,編譯沒有問題就可以部署了,進入到migrations目錄,編輯“2_deploy_contracts”檔案,在最後一行插入“deployer.deploy”(合約名),編輯內容如下:


var ConvertLib = artifacts.require("./ConvertLib.sol");
var MetaCoin = artifacts.require("./MetaCoin.sol");
var MyCalc=artifacts.require("./MyCalc.sol"); //新增

    module.exports = function(deployer) {
     deployer.deploy(ConvertLib);
     deployer.link(ConvertLib, MetaCoin);
     deployer.deploy(MetaCoin);
     deployer.deploy(MyCalc); //新增
   };


12)編輯儲存後,執行部署命令:


sudo truffle migrate


13)注意,在操作過程中一定要保證TestRPC是開啟的,命令執行成功後,在TestRPC中可以看到響應,接下來呼叫一下合約中的方法,要呼叫合約的功能,得與TestRPC模擬節點互動,首先進入到控制檯,命令如下:


sudo truffle console


14)進入到控制檯後,我們進入到MyTruffle目錄下的build子目錄中,找到MyCalc.json,開啟它找到abi的內容段,複製出來,然後回到控制檯,執行如下命令:


abi=複製出來的abi內容


15)同時在MyCalc.json中找到合約的地址,並且在控制檯中執行命令:


myContract=web3.eth.contract(abi).at("0xc7b8a297b99e473feeaf447993600336482c8a8a")


16)接下來就可以執行合約中的函式了,執行如下命令:


myContract.SumAdd.call(10)


最後就能看到結果了。

至此,我們對以太坊的私有鏈配置以及開發測試環境的搭建介紹就結束了,大家可以根據自己的具體需求進行各項引數的 配置,另外也要注意版本變更帶來的一些問題,比如geth的不同版本之間會有些差異,例如1.6版本去除了內建的JavaScript環境編譯功能,而 1.5版本中是有的,因此在1.5版本中可以直接使用相關的合約程式設計和編譯功能。以太坊是一個開源系統,功能開發也一直處於不斷的進化中,隨著發展,也會 出現更方便的功能,大家在具體使用過程中可以多關注一下。

6.2.2 編寫一個代幣合約

在上面幾節中,我們演示了一段合約程式碼的編寫,不過只是一個簡單的加法運算,實在讓人感覺不到智慧合約的特色。在本小節中,我們來演示一下如何通過以太坊智慧合約來建立一個數字代幣,我們參照以太坊官網的示例,提供一段最簡單的代幣合約示例,程式碼如下:


pragma solidity ^0.4.11;
contract MyToken {
    //宣告陣列,用以儲存代幣所有人的地址列表
    mapping (address => uint256) public balanceOf;

    // 初始化代幣總額,賦值給合約建立者的賬戶地址中
    // 這是一個建構函式,只會被執行一次
    function MyToken(
        uint256 initialSupply
        ) {
        balanceOf[msg.sender] = initialSupply; 
    }

    /* 代幣傳送 */
    function transfer(address _to, uint256 _value) {
        require(balanceOf[msg.sender] >= _value);            // 檢查餘額是否足夠
        // 檢查是否會溢位,主要防止迴圈傳送給自己
        require(balanceOf[_to] + _value >= balanceOf[_to]);  
        balanceOf[msg.sender] -= _value;     // 從傳送者賬戶中減掉髮送的金額
        balanceOf[_to] += _value;            // 在接收者賬戶中增加傳送的金額
    }
}

通過上述程式碼的註釋說明,我們大致瞭解了本合約程式碼中定義了一個名字叫MyToken的代幣,提供了一個建構函式 初始化代幣數量,建構函式中的msg.sender是指當前呼叫者的以太坊賬戶地址,由於合約一般都是由建立者部署的,因此初始化的代幣會通過執行構造函 數一次性全部記錄在建立者的賬戶地址中。除了建構函式,本合約還提供了一個傳送的方法,用來進行代幣轉賬,邏輯很簡單,引數中包含了一個轉賬目標賬戶地址 的引數_to和一個轉賬金額引數_value,過程就是做一些基本校驗以及更改轉出和轉入賬戶的金額,我們通過以太坊官方錢包來部署,為了方便操作,我們 使用較新的0.9.0版,其自帶的geth是1.6.5版,並且支援直接配置為本機單節點私有鏈,我們來看一下操作步驟。

(1)配置為單節點私有鏈

image.png

可以看到,配置相當簡單,選擇“Solo network”即可,選擇後可以建立一個賬戶,然後點選“開啟挖礦(僅限Testnet)網路”,可以看到建立的賬戶中很快就能獲得以太幣,如下所示:

image.png

由於部署合約以及呼叫合約方法要消耗以太幣,因此讀者可以根據自己的需要確保賬戶中具備足夠的餘額。

(2)代幣合約部署

通過下面第一個介面,可以部署合約以及檢視合約。

我們看到在介面底部,有一個WATCH TOKEN按鈕,這是專門用來檢視代幣合約的,大家注意,代幣合約和基於以太坊的其他合約(如眾籌合約等)性質都是一樣的,只是程式碼邏輯不同,官方錢包在 這裡專門為代幣合約設定了一個檢視的操作,是由於代幣合約的特殊性,方便操作而已。

現在我們來部署代幣合約,在合約介面點選DEPLOY NEW CONTRACT,進入到部署介面,如下面第二個介面。

在這個介面中,我們把編寫的代幣合約程式碼複製到SOLIDITY CONTRACT SOURCE CODE中,程式碼貼上進去後,會自動進行編譯,並將編譯後的位元組碼顯示在CONTRACT BYTE CODE中,接下來我們在右側SELECT CONTRACT TO DEPLOY中選擇待部署的合約名稱,我們的代幣合約名稱是MyToken,選擇好後在下方輸入初始代幣數量,這個數量會提供給建構函式執行,我們輸入了 10000。一切準備妥當後,點選介面下部的DEPLOY按鈕執行部署,彈出介面如下面第三個介面。

image.png

image.png

image.png

上圖顯示了合約建立的一些摘要資訊,部署的賬戶地址以及需要耗費的Gas,在主鏈上部署時會根據Gas以及Gas Price計算出需要花費的以太幣金額,我們現在是在單機私鏈上操作,因此沒有這些限制,可以直接進行部署,點選SEND TRANSACTION即可發起一個部署交易,執行後回到合約主介面,可以看到底部顯示部署狀態,如下所示:

image.png

讀者可能發現一直顯示著這個狀態,似乎部署不上去,原因可能是沒有開啟挖礦,部署的時候必須處於挖礦狀態才能成功,開啟挖礦後就部署成功了,部署後可以檢視這條部署交易資訊:

image.png

可以看到這條部署交易的賬戶地址、已確認的區塊數、合約部署的區塊高度等資訊,也可以看到部署的合約地址。在以太坊 中,部署合約也屬於一種交易事務。部署完成後,我們可以在合約操作的主介面上點開WATCH TOKEN,讓以太坊錢包以數字貨幣的視角來識別這份智慧合約,開啟後介面如下面第一個介面圖。

在TOKEN CONTRACT ADDRESS中輸入合約地址即可,下面是名稱、符合等資訊,可填可不填,完成後點選OK按鈕就引入了這個合約,可以看到主介面已經識別到了這個合約。如下面第二個介面圖。這裡顯示了初始數量為10000,至此部署就全部完成了。

有讀者會覺得奇怪,這麼部署一下就創造了一種數字代幣?這也太簡單了吧。準確地說,基於以太坊開發數字代幣很容 易。如果沒有一個這樣的基礎平臺,從零開發還是有些複雜的,實際上,以太幣本身也是一種合約,只不過合約規則是固化在以太坊程式碼中的。部署完成後,就可以 傳送給賬戶地址了,我們建立另外一個以太坊賬戶地址,然後做一次轉賬操作,進入到SEND介面,選擇主賬戶並選擇MyToken代幣,如下面第三個介面圖 所示。

image.png

image.png

image.png

在轉賬金額一欄填入一個金額(如2000),填寫完畢後點選“傳送”即可,我們分別來看一下主賬戶和接收賬戶的MyToken餘額。

1)主賬戶:

image.png

2)接收賬戶:

image.png

通過上述介紹,我們瞭解了在以太坊中通過智慧合約建立數字代幣的過程,當然我們只是演示了一個最簡單的程式碼版本。通常對於一個代幣來說,還會有其他多項功 能,比如獲得賬戶餘額,獲得代幣總量,設定凍結週期和數量等。以太坊上的智慧合約代幣有一個標準,也就是ERC20令牌標準,標準中約定了一系列的事件行 為和規則,應用開發者、交易平臺、錢包客戶端等多方如果都遵循標準來開發和識別代幣,就可以做到事先的介面對應,類似於一個協議,方便代幣在業務生態中平 滑流轉。

來源:我是碼農,轉載請保留出處和連結!

本文連結:http://www.54manong.com/?id=81

'); (window.slotbydup = window.slotbydup || []).push({ id: "u3646208", container: s }); })();
'); (window.slotbydup = window.slotbydup || []).push({ id: "u3646147", container: s }); })();

相關文章