phpでハッシュレートなどの情報を取得して表示する

イーサ先輩ブログリスペクトです。ethOSの情報を調べたときに真っ先に参考にさせていただいたブログなんですが、サイドバーに「ただいまのハッシュレート」ってのがありました。これは面白い!ってことでパクり参考にさせていただきました。どうやら先輩のブログではjavascriptで取得してるっぽいです。ですが全く同じでは面白くないのでphpでやってみることにしました。

私のRIGは全てethermineのpoolに接続していますので、ethermine.orgが提供するAPIを利用して表示することにします。このあたりは前にethOSのダウン検出でやってるので楽勝な予感。取得する値はハッシュレート、ActiveWorker数、ついでにdifficultyとBTCとUSDのレートも取ってみることにします。

なお、API制限があります。(javascriptなら悩まなくてよかった…)

Access to the API is limited to 100 requests / 15 minutes / ip.

phpでethOSのダウン検出と同じ仕組みにしてしまうと、誰かがアクセスする度にAPI取得しにいってしまって制限突破してしまう恐れがあるので、キャッシュを利用してみます。キャッシュはWordPressのTransientを利用してデータベースに保存、10分間隔でAPIを取得するようにしてみました。

function.phpに下記コードを追加

//ethermine.orgからrig情報を入手してキャッシュする
function get_ethermine_rigStats(){
  //データベースキャシュに値を取得
  $res = get_transient( 'transient_key' );
  if ( $res === false ) {//キャッシュが存在しないとき
    /* JSONデータ取得 */
    $res = "https://api.ethermine.org/miner/ウォレット/currentStats";
    $res = file_get_contents($res);
    //取得した値をデータベースキャッシュに保存
    set_transient( 'transient_key', $res, 10 * MINUTE_IN_SECONDS );
  }
  return $res;
}

//ethermine.orgからnetwork statusを入手してキャッシュする
function get_ethermine_networkStats(){
  //データベースキャシュに値を取得
  $res2 = get_transient( 'transient_key2' );
  if ( $res2 === false ) {//キャッシュが存在しないとき
    /* JSONデータ取得 */
    $res2 = "https://api.ethermine.org/networkStats";
    $res2 = file_get_contents($res2);
    //取得した値をデータベースキャッシュに保存
    set_transient( 'transient_key2', $res2, 10 * MINUTE_IN_SECONDS );
  }
  return $res2;
}

さて、表示部分のテスト用に適当にphpを作ってみます。文字化け防止(UTF8に変換)部分はぶっちゃけ要らないんだけど”おまじない”で入れてます。

<?php
/* キャッシュからロード */
$arr = get_ethermine_rigStats();
$arr2 = get_ethermine_networkStats();

/* 文字化け防止(UTF8に変換) */
$arr = mb_convert_encoding($arr, 'UTF8', 'ASCII,JIS,UTF-8,EUC-JP,SJIS-WIN');
$arr2 = mb_convert_encoding($arr2, 'UTF8', 'ASCII,JIS,UTF-8,EUC-JP,SJIS-WIN');

/* JSONデータを連想配列にする */
$arr = json_decode($arr,true);
$arr2 = json_decode($arr2,true);

$status = $arr['status'];
$activeWorkers = $arr['data']['activeWorkers'];
$averageHashrate = $arr['data']['averageHashrate'];
$currentHashrate = $arr['data']['currentHashrate'];
$reportedHashrate = $arr['data']['reportedHashrate'];
$cacheTime = $arr['data']['time'];
$difficulty = $arr2['data']['difficulty'];
$btc = $arr2['data']['btc'];
$usd = $arr2['data']['usd'];
$cacheTime2 = $arr2['data']['time'];

$cacheTime = date('Y/m/d H:i:s', $cacheTime);
$cacheTime2 = date('Y/m/d H:i:s', $cacheTime2);

$n = 1 ;	// 小数点第n位
$averageHashrate = ($averageHashrate / 1000000);
$averageHashrate = floor($averageHashrate * pow(10 , $n) ) / pow(10 , $n);
$averageHashrate = $averageHashrate . ' MH/s';

$currentHashrate = ($currentHashrate / 1000000);
$currentHashrate = floor($currentHashrate * pow(10 , $n) ) / pow(10 , $n);
$currentHashrate = $currentHashrate . ' MH/s';

$reportedHashrate = ($reportedHashrate / 1000000);
$reportedHashrate = floor($reportedHashrate * pow(10 , $n) ) / pow(10 , $n);
$reportedHashrate = $reportedHashrate . ' MH/s';

$difficulty = $difficulty / (1000 * 1000 * 1000 * 1000);
$difficulty = floor($difficulty); //小数点以下切り捨て

echo 'UTC time&nbsp&nbsp&nbsp: ' . date('Y/m/d H:i:s', time()) . '<br>';
echo 'Cache time1: ' . $cacheTime . '<br>';
echo 'Cache time2: ' . $cacheTime2 . '<br>';
echo 'status: ' . $status . '<br>';
echo '<br>';

echo 'Ethereum difficulty: ' . $difficulty . ' T<br>';
echo '1ETH = ' . $btc . ' BTC<br>';
echo '1ETH =  ' . $usd . ' USD<br>';

echo '<br>';
echo 'activeWorkers: ' . $activeWorkers . '<br>';
echo 'averageHashrate: ' . $averageHashrate . '<br>';
echo 'currentHashrate: ' . $currentHashrate . '<br>';
echo 'reportedHashrate: ' . $reportedHashrate . '<br>';
?>

このphpを実行してみると、このようになりました。

本当にキャッシュできてるのか不安なのでデータベースを覗いてみると、問題無さそうです。

ちゃんとwp_optionsに格納されていました。

では、このphpの余計な部分を取っ払い、ショートコードで出せるように改造します。function.phpに下記コードを追加

/* shortcode 追加 */
function ethStats($atts) {
  /* キャッシュからロード */
  $arr = get_ethermine_rigStats();
  $arr2 = get_ethermine_networkStats();

  /* 文字化け防止(UTF8に変換) */
  $arr = mb_convert_encoding($arr, 'UTF8', 'ASCII,JIS,UTF-8,EUC-JP,SJIS-WIN');
  $arr2 = mb_convert_encoding($arr2, 'UTF8', 'ASCII,JIS,UTF-8,EUC-JP,SJIS-WIN');

  /* JSONデータを連想配列にする */
  $arr = json_decode($arr,true);
  $arr2 = json_decode($arr2,true);

  $activeWorkers = $arr['data']['activeWorkers'];
  $reportedHashrate = $arr['data']['reportedHashrate'];
  $difficulty = $arr2['data']['difficulty'];
  $btc = $arr2['data']['btc'];
  $usd = $arr2['data']['usd'];


  $n = 1 ;    // 小数点第n位
  $reportedHashrate = ($reportedHashrate / 1000000);
  $reportedHashrate = floor($reportedHashrate * pow(10 , $n) ) / pow(10 , $n);
  $reportedHashrate = $reportedHashrate . ' MH/s';

  $difficulty = $difficulty / (1000 * 1000 * 1000 * 1000);
  $difficulty = floor($difficulty); //小数点以下切り捨て

/*
  echo 'Ethereum difficulty: ' . $difficulty . ' T<br>';
  echo '1ETH = ' . $btc . ' BTC<br>';
  echo '1ETH =  ' . $usd . ' USD<br>';
  echo 'activeWorkers: ' . $activeWorkers . '<br>';
  echo 'Hashrate: ' . $reportedHashrate . '<br>';
*/
  if($atts[0] == 'hash'){
    return $reportedHashrate;
  } elseif($atts[0] == 'worker'){
    return $activeWorkers;
  } elseif($atts[0] == 'diff'){
    return $difficulty;
  } elseif($atts[0] == 'btc'){
    return $btc;
  } elseif($atts[0] == 'usd'){
    return $usd;
  } else {
    return $reportedHashrate;
  }
}
add_shortcode('eth', 'ethStats');

これでショートコード[eth]ができたはず。
引数なしの[eth]および[eth hash]だとハッシュレート、
[eth worker]でActiveWorker数、
[eth diff]でdifficulty、
[eth btc]でBTCのレート、
[eth usd]でUSDのレートが出るようになっているはずです。

実際にショートコードを入力すると、、、

Hashrate: 685.7 MH/s
Worker: 6
difficulty: 1466 T
1 ETH = 0.04984 BTC
1 ETH = 295.39 USD

ちゃんと動きました。やったね。

しかしながら、このままだとサイドバーウィジェットにてショートコードが動きません。
function.phpにもう1行追加します。

/* ウィジェットでショートコードを使う */
add_filter('widget_text', 'do_shortcode' );

最後にサイドバーに適当に追加して完了です。

なお、この情報は10分毎の更新なので、参考程度にお願いします。