以太坊智慧合約學習筆記:網頁互動
阿新 • • 發佈:2018-11-03
沒搞過web程式,花了幾天研究一下,總算是搞懂了網頁與以太坊節點的互動流程。
網頁與智慧合約互動,需要使用web3.js,它實現了通用JSON PRC規範,通過JSON RPC協議與以太坊節點進行互動。除了js以外,以太坊還提供了Java、Python等語言的API,對於沒有提供API的語言,只能自己直接使用JSON RPC來與以太坊進行互動了,關於以太坊的JSON RPC協議,請戳這裡。
我們還是以之前的投票合約為例,來介紹一下網頁互動。
首先,我們需要建立一個以太坊節點
geth --datadir testNet --dev --rpc --rpcaddr 0.0.0.0 --rpccorsdomain "*" console --dev.period 1 2>>test.log
和之前的命令相比,多了幾項
- –rpcaddr 0.0.0.0 該選項是指定監聽IP
- –rpccorsdomain “*” 這是瀏覽器強制要求選項,用來指定可以訪問的IP和埠,“*”代表無訪問限制
- –dev.period 1 自動挖礦間隔,這裡是間隔一秒
然後回到合約工程目錄進行編譯和部署
truffle compile && truffle deplo
接下來我們要準備一個html,簡單一點,兩個文字框用來輸入人名和顯示結果,兩個按鈕用來投票和查詢,佈局就不加了。
<!DOCTYPE html> <html> <head> <title>MetaCoin - Truffle Webpack Demo w/ Frontend</title> <link rel="shortcut icon" href="#" /> <script type="text/javascript" src="https://cdn.jsdelivr.net/gh/ethereum/web3.js/dist/web3.min.js"></script> </head> <body> <br><label for="candidate">Candidate:</label><input type="text" id="candidate" placeholder="Rama"></input> <br><label for="votes">Votes:</label><input type="text" id="votes"></input> <input type="button" value="query" onclick="totalVotesFor()"></input> <input type="button" value="votes" onclick="voteForCandidate()"></input> <script type="text/javascript"> if (typeof web3 !== 'undefined') { web3 = new Web3(web3.currentProvider); } else { // set the provider you want from Web3.providers web3 = new Web3(new Web3.providers.HttpProvider("http://192.168.180.130:8545")); } web3.eth.defaultAccount = web3.eth.accounts[0]; var abi = [{"constant":true,"inputs":[{"name":"candidate","type":"bytes32"}],"name":"totalVotesFor","outputs":[{"name":"","type":"uint8"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"candidate","type":"bytes32"}],"name":"validCandidate","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"","type":"bytes32"}],"name":"votesReceived","outputs":[{"name":"","type":"uint8"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"","type":"uint256"}],"name":"candidateList","outputs":[{"name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"candidate","type":"bytes32"}],"name":"voteForCandidate","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"inputs":[{"name":"candidateNames","type":"bytes32[]"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"}]; var votingContract = web3.eth.contract(abi); var voting = votingContract.at('0x4121629c08fd86b7133761baa2e047ec23a17661'); function totalVotesFor() { // document.getElementById("votes").value = "abc"; document.getElementById("votes").value = voting.totalVotesFor(document.getElementById("candidate").value); } function voteForCandidate() { voting.voteForCandidate(document.getElementById("candidate").value); } </script> </body> </html>
HttpProvider的IP不能是127.0.0.1,這裡被坑慘了。
變數abi的值是合約編譯的結果,變數voting後面的大長串十六進位制數是合約的地址,這裡可以看之前的文章。
然後搭建個簡易的web伺服器,我們這裡用Python
python -m SimpleHTTPServer
最後用瀏覽器訪問“http://192.168.180.130:8000/”看結果。
在Candidate中輸入人名,點選votes進行投票,點選query查詢結果,結果顯示在Votes中。