1. 程式人生 > >以太坊智慧合約學習筆記:網頁互動

以太坊智慧合約學習筆記:網頁互動

沒搞過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中。