概要
private_netで遊んでいると、送金の度にminer.start打ってminer.stopかけるのが面倒になってくる。
ので、『トランザクションが発生したら採掘して、終わったら採掘辞める』を自動化する。
前準備
#Geth
brew tap ethereum/ethereum
brew install ethereum
mkdir eth_private
vim eth_private/genesis.json
======
{
"nonce": "0x0000000000000042",
"mixhash": "0x0000000000000000000000000000000000000000000000000000000000000000",
"difficulty": "0x400",
"alloc": {},
"coinbase": "0x3333333333333333333333333333333333333333",
"timestamp": "0x0",
"parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
"extraData": "0x",
"gasLimit": "0x8000000",
"config": {}
}
======
geth --datadir /Users/hoge/eth_private/ init /Users/hoge/eth_private/genesis.json
geth --networkid "10" --nodiscover --datadir "/Users/hoge/eth_private" console 2>> /Users/hoge/eth_private/geth_err.log
personal.newAccount()
miner.start()
miner.stop()
exit
gethの起動
#--rpcapiにminerを追加して起動
geth --networkid "19" --nodiscover --datadir "/Users/hoge/eth_private/" --rpc --rpcaddr "localhost" --rpcport "8545" --rpcapi "eth,net,web3,personal,accounts,miner" --rpccorsdomain "*" console 2>> /Users/hoge/eth_private/geth_err.log
実装
<html>
<body>
<script src="http://code.jquery.com/jquery-1.11.1.min.js"></script>
<script src="https://cdn.rawgit.com/ethereum/web3.js/develop/dist/web3.min.js"></script>
<script type="text/javascript">
var mining_threads = 1
const web3 = new Web3();
web3.setProvider(new web3.providers.HttpProvider('http://localhost:8545'));
function checkWork() {
if (web3.eth.getBlock("pending").transactions.length > 0) {
if (web3.eth.mining) return;
console.log("== Pending transactions! Mining...");
jsonrpc_api('miner_start', 1);
} else {
if (!web3.eth.mining) return;
console.log("== No transactions! Mining stopped.");
jsonrpc_api('miner_stop', 0);
}
}
web3.eth.filter("latest", function(err, block) { checkWork(); });
web3.eth.filter("pending", function(err, block) { checkWork(); });
function jsonrpc_api(method, param) {
//'{"jsonrpc":"2.0","method":"miner_stop","params":[0],"id":1}
$.ajax({
url : 'http://localhost:8545/',
type : 'POST',
dataType: 'json',
timeout : 30000,
headers : {
'Accept' : 'application/json',
'Content-type' : 'application/json'
},
data : JSON.stringify({
'jsonrpc' : "2.0",
'method' : method,
'params' : [param],
'id' : 1})
}).done(function(data, status, jqXHR) {
// 成功時
console.log(data);
}).fail(function(error, status, errorThrown) {
// 失敗時
console.log(error);
});
}
</script>
</body>
</html>
実行
2.gethのコンソールでもweb3でもjsonRPCでも何でもいいので送金を行う
#geth console
> eth.sendTransaction({from: eth.accounts[0], to: eth.accounts[1], value: web3.toWei(1, "ether")})
3. 1で開いたhtmlでトランザクションが検知され採掘開始。送金が処理されると採掘が終わる
解説
private_netにトランザクションが発生した時、最後のトランザクションを処理した時にイベント発生。
checkWorkを呼ぶ。
web3.eth.filter("latest", function(err, block) { checkWork(); });
web3.eth.filter("pending", function(err, block) { checkWork(); });
checkWork
- トランザクションが有れば採掘→採掘中ならreturn
- トランザクションが無ければ採掘終了→採掘してなければreturn
if (web3.eth.getBlock("pending").transactions.length > 0) {
if (web3.eth.mining) return;
console.log("== Pending transactions! Mining...");
jsonrpc_api('miner_start', 1);
} else {
if (!web3.eth.mining) return;
console.log("== No transactions! Mining stopped.");
jsonrpc_api('miner_stop', 0);
}
jsonrpc_api
miner.start()とminer.stop()を行う。
web3でやりたかったけどうまく動作しなかったため、jsonRPCで代用
これ単体では何の役にも立たないが、slackのリアクションをフックして送金するみたいなツール作った時に画面端で開いておくとちょっと便利