上一篇我們已經將合約部署至區塊鏈上了,在這篇執行合約前
我想要先講一下如果往後把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
結論
做到這邊,我們已經學會如何建立一條自己的區塊鏈
並且成功部署自己的第一個智能智能合約上去了:)))