Edited at

[Ethereum]private_netでトランザクションがある時だけ採掘する(Mac)

More than 1 year has passed since last update.


概要

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>


実行

1.作成したhtmlを開く

スクリーンショット 2018-03-14 18.01.44.png

2.gethのコンソールでもweb3でもjsonRPCでも何でもいいので送金を行う

#geth console

> eth.sendTransaction({from: eth.accounts[0], to: eth.accounts[1], value: web3.toWei(1, "ether")})

3. 1で開いたhtmlでトランザクションが検知され採掘開始。送金が処理されると採掘が終わる

スクリーンショット 2018-03-14 18.06.44.png


解説

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のリアクションをフックして送金するみたいなツール作った時に画面端で開いておくとちょっと便利