建立以太坊私有鏈(三) 執行投票合約

上一篇我們已經將合約部署至區塊鏈上了,在這篇執行合約前

我想要先講一下如果往後把terminal關掉了,要怎麼把合約的實例(instance)從區塊鏈上設回變數

 

取回部署在區塊鏈上的合約實例

如果你是接續上一篇做到這裡的,也就是在geth中輸入vote.address有反應的,可以跳過這部份

 
在取回合約實例之前,我們必須要有ABI及合約地址這兩樣才能把合約實例找回來

ABI類似合約的描述檔,記錄這個合約有哪些function,function有哪些input、回傳、範圍…等

如果缺少這兩個的話…,那就重新部署一次或一個區塊一個區塊慢慢找回來吧…

怎麼找出合約的ABI呢,因為我們是合約的owner,當然程式碼也在我們手中

打開Remix叫回合約程式碼,一樣在Compile分頁的Detail

就會看到ABI了

把它複製起來到記事本中,然後把所有換行拿掉(在geth中遇到換行會error…)

回到geth運行,把它ABI指派給abi這個變數

var abi = [{"constant": false,"inputs": [{"name": "proposal","type": "uint256"}],"name": "vote","outputs": [],"payable": false,"stateMutability": "nonpayable","type": "function"},{"constant": true,"inputs": [],"name": "showWinningProposal","outputs": [{"name": "winningProposal","type": "uint256"}],"payable": false,"stateMutability": "view","type": "function"},{"constant": false,"inputs": [{"name": "voter","type": "address"}],"name": "giveRightToVote","outputs": [],"payable": false,"stateMutability": "nonpayable","type": "function"},{"inputs": [{"name": "proposalNames","type": "bytes32[]"}],"payable": false,"stateMutability": "nonpayable","type": "constructor"}];

也把要找回的合約地址指派給address

var address = "0x33111237ea1c133fb27268700370109d8ec03e87";

然後運行

var vote = eth.contract(abi).at(address);

就可以把之前的合約實例對回給vote這個變數了

 
現在再試一次

terminal1 $> vote.address
"0x33111237ea1c133fb27268700370109d8ec03e87"

就會出現合約的地址,代表有正確assign到

 

再做一遍上面的方法讓terminal2 $取得合約的實例,等等我們要拿他來當投票者

 

執行投票合約

geth閒置一段時間後如果要再使用有關帳戶的指令

geth會要求會重新解鎖帳戶,所以要再調用personal.unlockAccount()一次

terminal1 $> personal.unlockAccount(eth.coinbase)
terminal2 $> personal.unlockAccount(eth.coinbase)

如果調用合約時遇到Invalid Address,有可能是defaultAccount也跑掉了

再指定一次即可解決Invalid Address的問題

terminal1 $> web3.eth.defaultAccount = eth.coinbase
terminal2 $> web3.eth.defaultAccount = eth.coinbase

賦予投票權利

投票前先執行vote.showWinningProposal()看看

還記得上一篇提到我們的合約有一個bug,當出現兩個最高票的提案

showWinningProposal()只會返回index順序比較前面的那個

因為目前沒有任何人投票,所以返回的應該會是0,也就是第一個提案

terminal1 $> vote.showWinningProposal()
0

terminal2 $有權利投票,先記下terminal2 $的帳戶地址

terminal2 $> eth.coinbase

把該地址賦予投票的權利

terminal1 $> vote.giveRightToVote("剛剛記下terminal2的地址")

注意要是挖礦的狀態miner.start()terminal2 $投票的權利才會被打包到區塊上唷

投票與開票

當挖出幾個礦後就可以讓terminal2 $投票看看了

還記得剛剛執行vote.showWinningProposal()的結果是第一個提案

所以這次我們就故意投第二個提案

terminal2 $> vote.vote(1)

可能又會出現需要解鎖的訊息,那就需要再調用personal.unlockAccount()一次

放著讓他挖一會兒後,執行vote.showWinningProposal()就可以看到得票最高的變成第二個提案了

terminal1 $> vote.showWinningProposal()
1

 

結論

做到這邊,我們已經學會如何建立一條自己的區塊鏈

並且成功部署自己的第一個智能智能合約上去了:)))


發佈留言