第二課 如何實(shí)現(xiàn)以太坊最簡(jiǎn)智能合約“Hello World”的運(yùn)行

【本文目標(biāo)】
完成以太坊最簡(jiǎn)智能合約“Hello World”的編寫和運(yùn)行

【技術(shù)收獲】
跟隨本文實(shí)踐,你將可以有以下收獲:

  1. 啟動(dòng)GETH以太坊錢包環(huán)境
  2. 準(zhǔn)備賬戶
  3. 創(chuàng)建賬戶
  4. 給新賬戶轉(zhuǎn)賬
  5. 解鎖賬戶
  6. 編寫合約代碼
  7. 部署合約
  8. 運(yùn)行合約

【實(shí)操課程列表】
第一課 如何在WINDOWS環(huán)境下搭建以太坊開發(fā)環(huán)境
第二課 如何實(shí)現(xiàn)以太坊最簡(jiǎn)智能合約“Hello World”的運(yùn)行
第四課 以太坊開發(fā)框架Truffle從入門到實(shí)戰(zhàn)
第六課 技術(shù)小白如何開發(fā)一個(gè)DAPP區(qū)塊鏈應(yīng)用(以寵物商店為例)
第七課 技術(shù)小白如何在45分鐘內(nèi)發(fā)行通證(TOKEN)并上線交易
第八課 如何調(diào)試以太坊官網(wǎng)的智能合約眾籌案例
【說明】未列出的課程為知識(shí)普及的非實(shí)操類課程,所有區(qū)塊鏈文章參考“區(qū)塊鏈入口”專欄。

1. 啟動(dòng)GETH以太坊錢包環(huán)境

如果你對(duì)于以太坊智能合約開發(fā)還沒有概念(本文會(huì)假設(shè)你已經(jīng)知道這些概念),建議先閱讀入門篇。 就先學(xué)習(xí)任何編程語言一樣,入門的第一個(gè)程序都是Hello World。今天我們來一步一步從搭建以太坊智能合約開發(fā)環(huán)境開始,講解智能合約的Hello World如何編寫。

【說明】強(qiáng)烈建議新手使用Browser-Solidity來進(jìn)行開發(fā)。

Browser-Solidity是一個(gè)基于瀏覽器的Solidity,就可以不用安裝Solidity,本文的Hello World教程也將基于Browser-Solidity來進(jìn)行。如果你想自己安裝請(qǐng)參考Solidity安裝指引

geth是一個(gè)以太坊客戶端,現(xiàn)在利用geth啟動(dòng)一個(gè)以太坊(開發(fā)者)網(wǎng)絡(luò)節(jié)點(diǎn)。

geth --datadir testNet --dev console 2>> test.log

執(zhí)行命名后,會(huì)進(jìn)入geth控制臺(tái),這時(shí)光標(biāo)停在一個(gè)向右的箭頭處,像這樣:


命令參數(shù)說明:
–dev 啟用開發(fā)者網(wǎng)絡(luò)(模式),開發(fā)者網(wǎng)絡(luò)會(huì)使用POA共識(shí),默認(rèn)預(yù)分配一個(gè)開發(fā)者賬戶并且會(huì)自動(dòng)開啟挖礦。
–datadir 后面的參數(shù)是區(qū)塊數(shù)據(jù)及秘鑰存放目錄。
第一次輸入命令后,它會(huì)放在當(dāng)前目錄下新建一個(gè)testNet目錄來存放數(shù)據(jù)。
console 進(jìn)入控制臺(tái)
2>> test.log 表示把控制臺(tái)日志輸出到test.log文件

為了更好的理解,建議新開一個(gè)命令行終端,實(shí)時(shí)顯示日志:

tail -f test.log

輸出截圖:
Xshell建立一個(gè)新的窗口用于輸出LOG結(jié)果

2. 準(zhǔn)備賬戶

部署智能合約需要一個(gè)外部賬戶,我們先來看看分配的開發(fā)者賬戶,在控制臺(tái)使用以下命令查看賬戶:

eth.accounts

回車后,返回一個(gè)賬戶數(shù)組,里面有一個(gè)默認(rèn)賬戶,
也可以使用personal.listAccounts查看賬戶。

personal.listAccounts

本文作者已創(chuàng)建了一個(gè)賬號(hào),共有2個(gè)賬號(hào)了:

eth.getBalance(eth.accounts[0])表示賬戶列表第一個(gè)賬戶
回車后,可以看到大量的余額,如:

1.15792089237316195423570985008687907853269… e+77

開發(fā)者賬戶因余額太多,如果用這個(gè)賬戶來部署合約時(shí)會(huì)無法看到余額變化,為了更好的體驗(yàn)完整的過程,這里選擇創(chuàng)建一個(gè)新的賬戶。

3. 創(chuàng)建賬戶

使用以下命令創(chuàng)建賬戶:

personal.newAccount("duncanwang")

duncanwang為新賬戶的密碼,回車后,返回一個(gè)新賬戶。
可以看到賬戶數(shù)組包含了3個(gè)賬戶,新賬戶在第三個(gè)(索引為2)位置。
現(xiàn)在看看賬戶的新余額,可以發(fā)現(xiàn)是0.

eth.accounts
eth.getBalance(eth.accounts[2])

截圖如下:

4. 給新賬戶轉(zhuǎn)賬

我們知道沒有余額的賬戶是沒法部署合約的,那我們就從默認(rèn)賬戶轉(zhuǎn)1以太幣給新賬戶,使用以下命令(請(qǐng)使用你自己eth.accounts對(duì)應(yīng)輸出的賬戶):

eth.sendTransaction({from: '0x8cfa24a398efd88de3843d7834cb07fce41e6f46', to: '0x0f1b9da153d910f6ae150145924615c23bbf5176', value: web3.toWei(99, "ether")})

eth.getBalance(eth.accounts[2])

在打開的tail -f test.log日志終端里,可以同時(shí)看到挖礦記錄

再次查看新賬戶余額,可以新賬戶有99個(gè)以太幣(顯示的單位是wei,所以有18個(gè)0) 。

5. 解鎖賬戶

在部署合約前需要先解鎖賬戶(就像銀行轉(zhuǎn)賬要輸入密碼一樣),使用以下命令:

personal.unlockAccount(eth.accounts[2],"duncanwang");

“duncanwang” 是之前創(chuàng)建賬戶時(shí)的密碼

解鎖成功后,賬戶就準(zhǔn)備完畢啦,接下來就是編寫合約代碼。

【說明】
geth的這些函數(shù)的接口文檔是哪個(gè)呢?需要學(xué)習(xí)GETH所有的庫函數(shù),可參考官網(wǎng)文檔
1,admin,debug,miner,personal,txpool實(shí)例的接口函數(shù)[Console的描述]
https://github.com/ethereum/go-ethereum/wiki/Management-APIs
2,eth實(shí)例的接口函數(shù)[例如eth_protocolVersion去除下劃線為eth.protocolVersion]
https://github.com/ethereum/wiki/wiki/JSON-RPC

6. 編寫合約代碼

現(xiàn)在我們來開始編寫第一個(gè)智能合約代碼,solidity代碼如下:

pragma solidity ^0.4.21;
contract hello {
    string greeting;

    function hello(string _greeting) public {
        greeting = _greeting;
    }

    function say() constant public returns (string) {
        return greeting;
    }
}

簡(jiǎn)單解釋下,我們定義了一個(gè)名為hello的合約,在合約初始化時(shí)保存了一個(gè)字符串(我們會(huì)傳入hello world),每次調(diào)用say返回字符串。
把這段代碼寫(拷貝)到Browser-Solidity,如果沒有錯(cuò)誤,點(diǎn)擊Details獲取部署代碼,如:


在彈出的對(duì)話框中找到WEB3DEPLOY部分,點(diǎn)拷貝,粘貼到編輯器后,修改初始化字符串為hello world。

solidity在博文寫作時(shí)(2018/3/30),版本為0.4.21,solidity發(fā)展非常快,solidity版本之間有可能不能兼容,這是你可以在Browser-Solidity的Settings里選擇對(duì)應(yīng)的編譯器版本。 Browser-Solidity也不停的更新中,截圖可能和你看到的界面不一樣。

7. 部署合約

Browser-Solidity生成的代碼,拷貝到編輯器里修改后的代碼如下:

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

【注意】
第1行:修改變量名為_geeting5, 修改字符串為Hello World
第2行:合約變量名為helloContract5,里面引用改為_greeting5
第3行:修改合約實(shí)例變量名為helloContract5,之后可以直接用實(shí)例調(diào)用函數(shù)。
第6行:修改部署賬戶為新賬戶索引,此處改為[2],即使用新賬戶來部署合約。
第8行:準(zhǔn)備付的gas費(fèi)用,IDE已經(jīng)幫我們預(yù)估好了。
第9行:設(shè)置部署回調(diào)函數(shù)。
其中變量名為全局的,_geeting5僅為舉例表示新定義的變量。

拷貝會(huì)geth控制臺(tái)里,回車后,看到輸出,說明合約已經(jīng)部署成功。

在打開的tail -f test.log日志終端里,可以同時(shí)看到挖礦記錄
現(xiàn)在我們查看下新賬戶的余額:

eth.getBalance(eth.accounts[2])

輸出結(jié)果不再是99個(gè)以太幣,比以前少了。

8. 運(yùn)行合約

執(zhí)行一下合約函數(shù):

hello.say()

輸出Hello World,我們第一個(gè)合約Hello World,成功運(yùn)行了。

一個(gè)合約的意義更重要的是體驗(yàn)智能合約開發(fā)流程,對(duì)于初學(xué)者一些可以選擇先放棄一些細(xì)節(jié),開發(fā)流程打通之后,可以增強(qiáng)信心進(jìn)行下一步的學(xué)習(xí)。


參考文檔

1,智能合約開發(fā)環(huán)境搭建及Hello World合約
2,GETH賬戶管理接口文檔
3,GETH JSON-RPC 接口調(diào)用函數(shù)
4, GETH API接口管理

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容