Windows下以太坊Geth客戶端安裝使用以及簡單合約的部署

操作系統:Windows 10
參考資料:如何搭建以太坊私有鏈智能合約開發環境搭建及Hello World合約

以太坊安裝

以太坊客戶端與Java虛擬機和.NET運行環境類似,能夠讓你在電腦上運行"以太坊程序"。

以太坊的客戶端有很多版本,在這裏選擇Geth(Go-ethereum)。只需要直接到官網下載Windows對應.exe可執行文件,並安裝即可。

安裝完成後,打開cmd命令提示符,輸入命令geth --help顯示以下信息,表明安裝成功。
在這裏插入圖片描述
PS:如果不加任何參數,只使用geth命令執行,或雙擊安裝目錄下的geth.exe,會自動連接到以太坊公網,並開始同步區塊(你會發現一直卡着不動),此時區塊數據存儲的路徑可以在geth --help中查看到。

私有鏈創世區塊搭建

以太坊支持自定義創世區塊,要運行私有鏈,我們就需要定義自己的創世區塊,創世區塊信息寫在一個 json 格式的配置文件中。

在磁盤的某個地方創建一個新文件夾,在該文件夾中新建創世區塊配置文件genesis.json,內容如下:

{
  "config": {
        "chainId": 15,
        "homesteadBlock": 0,
        "eip155Block": 0,
        "eip158Block": 0
    },
    "coinbase" : "0x0000000000000000000000000000000000000000",
    "difficulty" : "0x07000",
    "extraData" : "",
    "gasLimit" : "0xffffffff",
    "nonce" : "0x0000000000000042",
    "mixhash" : "0x0000000000000000000000000000000000000000000000000000000000000000",
    "parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000",
    "timestamp" : "0x00",
    "alloc": { }
}

字段的具體含義在這裏就不展開敘述了。之後在cmd窗口進入該文件夾,執行如下命令:

geth --datadir data init genesis.json

上面命令的主體是 geth init,表示初始化區塊鏈,命令可以帶有選項和參數,其中 --datadir 選項後面跟一個目錄名,這裏爲 data,表示指定數據存放目錄爲 datagenesis.jsoninit 命令的參數。執行後結果如下,可以看到,私有鏈搭建成功。
在這裏插入圖片描述
PS:在data目錄下,會有兩個文件:gethkeystore,前者保存區塊數據,後者存放賬戶信息。

私有鏈節點的加入

在完成上述步驟後,就已經有了一條自己的私有鏈了,可以加入自己的私有鏈節點,使用以下命令啓動節點:

geth --datadir data --networkid 2629 console

命令的主體是 geth console,表示啓動節點並進入交互式控制檯,--datadir 選項指定使用 data 作爲數據目錄,--networkid 選項後面跟一個數字,這裏是 2629,表示指定這個私有鏈的網絡 id 爲 2629。網絡 id 在連接到其他節點的時候會用到,以太坊公網的網絡 id 是 1,爲了不與公有鏈網絡衝突,運行私有鏈節點的時候要指定自己的網絡 id 。執行後,結果如下:

如圖,會進入到一個交互式的 Javascript 執行環境,裏面可以執行 Javascript 的代碼,如輸入1+1會輸出2。 在這個環境中,可以進行很多操作,例如:查看區塊和交易、創建賬戶、挖礦、發送交易、部署智能合約等。

然後執行如下一系列的操作,進行創建用戶,挖礦,就不展開敘述了:

personal.newAccount("123") //創建用戶,引號中的是賬戶密碼

eth.accounts //可查看賬戶信息

miner.start(2) 	//啓動挖礦,參數表示使用的線程數。啓動後就會被挖礦信息刷屏
				//挖礦所得以太幣默認存入第一個賬戶
miner.start();admin.sleepBlocks(1);miner.stop()//使用這個命令會在挖到一次礦後自動停止

miner.stop() //停止挖礦

eth.getBalance(eth.accounts[0]) //可以查看賬戶餘額,單位是wei
web3.fromWei(eth.getBalance(eth.accounts[0]),'ether') //將餘額單位換算成以太幣

交易

PS:下文的操作我換用了Windows PowerShell

按照相同方式再創建一個賬戶,此時先前的賬戶有餘額,而新創建的賬戶餘額爲0,可以通過以下命令將10個以太幣從賬戶0轉移到賬戶1:

amount = web3.toWei(10,'ether')
eth.sendTransaction({from:eth.accounts[0],to:eth.accounts[1],value:amount})

此時會報錯如下:

原因是賬戶每隔一段時間就會被鎖住,要發送交易,必須先解鎖賬戶,由於我們要從賬戶 0 發送交易,所以要解鎖賬戶 0,執行圖中所示命令(需要輸入密碼):
在這裏插入圖片描述
解鎖後,重新執行之前的命令。

交易後,查看賬戶1餘額,會發現還是0,這是因爲交易已經提交到區塊鏈,但還未被處理。正如之前所學到的,需要礦工進行挖礦,處理並記錄這個交易。所以我們進行挖礦後,得到如下結果:

可以看到,賬戶1的餘額已經變成10了,說明交易已被處理。

查看區塊

使用命令eth.blockNumber查看當前的區塊總數,eth.getBlock(10)查看具體的區塊,執行結果如下:
在這裏插入圖片描述
區塊的各字段含義如下:

  • difficulty:表示當前區塊的難度
  • extraData:與此區塊相關的附加數據
  • gasLimit:當前區塊允許使用的最大gas
  • gasUsed:當前區塊累計使用的gas
  • hash:區塊的哈希值。如果區塊沒有被確認,字段值爲null
  • logsBloom:區塊日誌的布隆過濾器,區塊沒被確認時值爲null
  • miner:取得該區塊記賬權的礦工
  • mixHash:一個Hash值,當與nonce組合時,證明此區塊已經執行了足夠的計算
  • nonce:PoW生成的哈希值
  • number:區塊號(創世紀塊的區塊序號爲0,對於每個後續區塊,區塊序號都增加1)
  • parentHash:前一個區塊的哈希值
  • receiptsRoot:收據樹的根哈希值
  • sha3Uncles:數據塊的哈希值
  • size:該區塊的字節大小
  • stateRoot:狀態樹的根哈希值
  • timestamp:區塊打包時的unix時間戳
  • totalDifficulty:區塊鏈到當前區塊的總難度
  • transactions:交易的對象
  • transactionsRoot:交易樹的根哈希值
  • uncles:叔哈希的數組

查看交易

使用命令eth.getTransaction(" ")查看交易,其中引號需加上交易的hash值,在交易執行後會有顯示。執行結果如下,該交易是上文所述交易:
在這裏插入圖片描述
交易的各字段含義如下:

  • blockHash:這個交易所在的區塊的哈希值
  • blockNumber:這個交易所在的區塊的編號
  • from:發起交易的賬戶
  • gas:執行這個交易所需要的gas
  • gasPrice:當前gas與以太幣換算的匯率
  • hash:這個交易的哈希值
  • input:合約的16進制代碼
  • nonce:交易下的nonce值,是賬戶發起交易所維護的nonce,一個交易對應一個nonce值
  • r,s,v:交易簽名後的值,它們可以被用來生成簽名者的公鑰;r,s是ECDSA橢圓加密算法的輸出值,v是用於恢復結果的ID
  • to:交易接收賬戶。如果是一個創建智能合約的交易,to爲空
  • transactionIndex:這個交易在其對應區塊的序號
  • value:交易的以太幣數量。如圖所示,正是10個以太幣

查看日誌

進行到這裏才發現有日誌功能…

日誌功能開啓方法:在上文啓動以太坊節點時在後面加上2>> test.log,日誌的名稱可以自己隨意設置。

簡單來說,日誌的作用就是將我之前在執行命令時會輸出的各種提示信息,例如INFOWARN,不直接輸出到屏幕上,而是重定向寫入到我們指定的日誌文件中。日誌文件部分內容如下:

上圖顯示的內容就是啓動節點後,geth初始化的一些信息。

對於選擇將這些提示信息輸入到日誌中,我認爲有好處也有壞處:好處就是沒有這些提示信息後,geth命令行界面和之前相比顯得更加簡介了,同時有了日誌的記錄,方便日後的查看;壞處就是似乎少了一些什麼的感覺,比如挖礦時刷屏的快感。

編寫簡單的智能合約

使用Remix - Ethereum IDE直接在瀏覽器中編寫和編譯Solidity代碼

參考網上博客(見本文開頭部分的參考資料),創建helloworld.sol,並編寫代碼如下:

pragma solidity ^0.4.22;
contract hello {
    
    string greeting;
    
    function hello(string _greeting) public {
        greeting = _greeting;
    }
    
    function say() constant public returns (string) {
        return greeting;
    }
    
}

上述代碼創建了一個hello合約。點擊頁面中的Compile進行編譯。對於博客提供的代碼似乎給了警告,意思好像是要求寫構造函數,不過既然不是報錯,暫時先不管。

編譯通過後,點擊下方的 Compilation Details,找到 WEB3DEPLOY 選項旁的複製按鈕進行復制,得到如下結果:

var _greeting = /* var of type string here */ ;
var helloContract = web3.eth.contract([{"constant":true,"inputs":[],"name":"say","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"inputs":[{"name":"_greeting","type":"string"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"}]);
var hello = helloContract.new(
   _greeting,
   {
     from: web3.eth.accounts[0], 
     data: '0x608060405234801561001057600080fd5b506040516102a83803806102a8833981018060405281019080805182019291905050508060009080519060200190610049929190610050565b50506100f5565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061009157805160ff19168380011785556100bf565b828001600101855582156100bf579182015b828111156100be5782518255916020019190600101906100a3565b5b5090506100cc91906100d0565b5090565b6100f291905b808211156100ee5760008160009055506001016100d6565b5090565b90565b6101a4806101046000396000f300608060405260043610610041576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063954ab4b214610046575b600080fd5b34801561005257600080fd5b5061005b6100d6565b6040518080602001828103825283818151815260200191508051906020019080838360005b8381101561009b578082015181840152602081019050610080565b50505050905090810190601f1680156100c85780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b606060008054600181600116156101000203166002900480601f01602080910402602001604051908101604052809291908181526020018280546001816001161561010002031660029004801561016e5780601f106101435761010080835404028352916020019161016e565b820191906000526020600020905b81548152906001019060200180831161015157829003601f168201915b50505050509050905600a165627a7a72305820bd9c8f1aad9fb4da7211d57eeaea5ede4555a3d028220142c0fa5bfe05d3874d0029', 
     gas: '4700000'
   }, function (e, contract){
    console.log(e, contract);
    if (typeof contract.address !== 'undefined') {
         console.log('Contract mined! address: ' + contract.address + ' transactionHash: ' + contract.transactionHash);
    }
 })

繼續按照博客要求,將第一行的註釋部分改爲“Hello World”(可以先複製到文本中進行修改)。修改完成後,拷貝到geth控制檯中。注意先要解鎖合約中from字段對應的賬戶!

**然後需要進行挖礦!**我起初沒有進行挖礦,所以一直以爲哪裏出錯了。查看Log日誌可以看到,當我們將上述內容拷貝到控制檯後,日誌中提示以下信息:

INFO [10-09|21:44:27.864] Submitted contract creation

在開始挖礦一段時間後,可以看到如下所示的提示信息,表示合約已經部署成功了。

在這裏插入圖片描述
此時查看對應賬戶餘額,可以看到,餘額變少了。

運行hello合約,得到如下結果:
在這裏插入圖片描述
結果符合預期,即輸出了Hello World,合約成功運行!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章