ASICマイニングの基礎知識 ~ 電力 ~

### ワット(W)とは
どれだけの電圧(V)で、どれだけの電流(A)を流せたかという仕事量を表す単位
ワットすうが高いほど、大きな電気エネルギーを使っている

Aアンペア x Vボルト = Wワット

### アンペア(A)
電流、電気の流れる量

### 電圧(V)
電気の強さ
※一般家庭では、100Vが一般的、国別に見ると、Europeは220Vが多い。高電圧に変更する場合は数万円程度かかる
※マイニングには100Vと200Vではパフォーマンスに差が出ると言われている

### ワットアワー(Wh)
1時間に使用するワットアワー
1000(W) x 1(h) = 1000Wh = 1kWh

### アンペア
一般家庭では20、30アンペア
東京電力では、アンペアブレーカーの色でアンペアがわかる
赤10、桃15, 黄20、緑30、グレー40、茶色50、紫60

### コンセント
一般家庭のコンセントでは1500Wまで使えるというのが多い

### 電気料金の決まり方
基本料金(アンペア)と従量課金

### 電力目安
新電力料金目安単価(1時間に1000W使用)31円/kWh(税込)〈

### 東京電力の単価表
最初の120kWhまで(第1段階料金) 1kWh 30円00銭
120kWhをこえ300kWhまで(第2段階料金) 〃 36円60銭
上記超過(第3段階料金) 〃 40円69銭
https://www.tepco.co.jp/ep/private/plan/old01.html
リミックスポイントは1kWhが東電より8円くらい安い

### 新電力
発電と送配電は大手が担っているが、小売を新電力が参入していることが多いらしい

なるほど、マイニングには電気の知識も必要やな

[LINE] Messaging APIで、テキスト以外のレスポンスを送る

modelをTextMessageではなく、TemplateMessageに変更する
公式ドキュメントを参考にする
https://developers.line.biz/en/reference/messaging-api/#imagemap-message
SDKのモデル一覧はこちら
https://github.com/line/line-bot-sdk-php/blob/master/examples/KitchenSink/src/LINEBot/KitchenSink/EventHandler/MessageHandler/TextMessageHandler.php

  $template = array('type'    => 'confirm',
                  'text'    => 'テキストメッセージ。最大240文字',
                  'actions' => array(
                                 array('type'=>'message', 'label'=>'yes', 'text'=>'yesを押しました' ),
                                 array('type'=>'message', 'label'=>'no',  'text'=>'noを押しました' )
                                )
                );
  $message = new \LINE\Clients\MessagingApi\Model\TemplateMessage(['type' => 'template','altText'  => '代替テキスト','template' => $template]);
  $request = new \LINE\Clients\MessagingApi\Model\ReplyMessageRequest([
    'replyToken' => $replyToken,
    'messages' => [$message],
  ]);
  $response = $messagingApi->replyMessage($request);

LINE側の挙動は確認できたので、あとはMySQLのCRUDとChatGPTのレスポンスの確認

LINE Messaging APIで複数レスポンスする

複数のメッセージを送信したい場合は、messagesを配列にする。

$message = new \LINE\Clients\MessagingApi\Model\TextMessage(['type' => 'text','text' => $message->{"text"}]);
$userId = new \LINE\Clients\MessagingApi\Model\TextMessage(['type' => 'text','text' => $userId]);
$request = new \LINE\Clients\MessagingApi\Model\ReplyMessageRequest([
    'replyToken' => $replyToken,
    'messages' => [$message, $userId],
]);
$response = $messagingApi->replyMessage($request);

1つのリクエストでreplyTokenを複数作ることはできないので、以下のようにレスポンスを複数は書けない。この場合、最初のレスポンスしか表示されない。

$message = new \LINE\Clients\MessagingApi\Model\TextMessage(['type' => 'text','text' => $message->{"text"}]);
$request = new \LINE\Clients\MessagingApi\Model\ReplyMessageRequest([
    'replyToken' => $replyToken,
    'messages' => [$message],
]);
$response = $messagingApi->replyMessage($request);

$userId = new \LINE\Clients\MessagingApi\Model\TextMessage(['type' => 'text','text' => $userId]);
$request = new \LINE\Clients\MessagingApi\Model\ReplyMessageRequest([
    'replyToken' => $replyToken,
    'messages' => [$userId],
]);
$response = $messagingApi->replyMessage($request);

LINE Messaging APIでUserIDを取得する

webhookイベントオブジェクトの構造を参考にUserIDを取得する

### webhookイベントオブジェクト
https://developers.line.biz/ja/reference/messaging-api/#webhook-event-objects
これを見ると、sourceのuserIdがあるので、これをキーに出来そう

{
  "destination": "xxxxxxxxxx",
  "events": [
    {
      "type": "message",
      "message": {
        "type": "text",
        "id": "14353798921116",
        "text": "Hello, world"
      },
      "timestamp": 1625665242211,
      "source": {
        "type": "user",
        "userId": "U80696558e1aa831..."
      },
      "replyToken": "757913772c4646b784d4b7ce46d12671",
      "mode": "active",
      "webhookEventId": "01FZ74A0TDDPYRVKNK77XKC3ZR",
      "deliveryContext": {
        "isRedelivery": false
      }
    },
    {
      "type": "follow",
      "timestamp": 1625665242214,
      "source": {
        "type": "user",
        "userId": "Ufc729a925b3abef..."
      },
      "replyToken": "bb173f4d9cf64aed9d408ab4e36339ad",
      "mode": "active",
      "webhookEventId": "01FZ74ASS536FW97EX38NKCZQK",
      "deliveryContext": {
        "isRedelivery": false
      }
    },
    {
      "type": "unfollow",
      "timestamp": 1625665242215,
      "source": {
        "type": "user",
        "userId": "Ubbd4f124aee5113..."
      },
      "mode": "active",
      "webhookEventId": "01FZ74B5Y0F4TNKA5SCAVKPEDM",
      "deliveryContext": {
        "isRedelivery": false
      }
    }
  ]
}

ソースコード上ではこのように取得する

$message = $jsonObj->{"events"}[0]->{"message"}; 
$userID = $jsonObj->{"events"}[0]->{"source"}->{"userId"}; 

さあ、mysqlの構造をどうするかですね。
その前にレスポンスのバリエーションを確認したい。

line-bot-sdk-phpとreplyToken

LINE Messaging APIを使用した開発をやります。
$ php composer.phar require linecorp/line-bot-sdk
$ php composer.phar require guzzlehttp/guzzle

こちらでは上手くいかない

require("vendor/autoload.php");

use LINE\LINEBot\Constant\HTTPHeader;
use LINE\LINEBot\HTTPClient\CurlHTTPClient;
use LINE\LINEBot;

$channel_access_token = 'xxxx';
$channel_secret = 'xxxx';

$http_client = new CurlHTTPClient($channel_access_token);
$bot = new LINEBot($http_client, ['channelSecret' => $channel_secret]);
$signature = $_SERVER['HTTP_' . HTTPHeader::LINE_SIGNATURE];
$http_request_body = file_get_contents('php://input');
$events = $bot->parseEventRequest($http_request_body, $signature);
$event = $events[0];

$reply_token = $event->getReplyToken();
$reply_text = $event->getText();
$bot->replyText($reply_token, $reply_text);

Githubを見ながら少し内容を変更します。SDKのバージョンによってライブラリのclass構成が変わっているようです。
https://github.com/line/line-bot-sdk-php
replyTokenは、{“events”}[0]に入っている。line-bot-sdk-phpのsampleを見ても全然わからなかったので、凄い時間がかったw

ini_set("display_errors", 1);
error_reporting(E_ALL);
require("vendor/autoload.php");

$jsonString = file_get_contents('php://input'); error_log($jsonString); 
$jsonObj = json_decode($jsonString); $message = $jsonObj->{"events"}[0]->{"message"}; 
$replyToken = $jsonObj->{"events"}[0]->{"replyToken"};

$client = new \GuzzleHttp\Client();
$config = new \LINE\Clients\MessagingApi\Configuration();
$config->setAccessToken('');
$messagingApi = new \LINE\Clients\MessagingApi\Api\MessagingApiApi(
  client: $client,
  config: $config,
);

$message = new \LINE\Clients\MessagingApi\Model\TextMessage(['type' => 'text','text' => $message->{"text"}]);
$request = new \LINE\Clients\MessagingApi\Model\ReplyMessageRequest([
    'replyToken' => $replyToken,
    'messages' => [$message],
]);
$response = $messagingApi->replyMessage($request);

Ubuntu22.04にPHPとMySQLをインストールする

$ sudo apt update

### PHP
$ sudo apt install php libapache2-mod-php php-mysql
$ php -v
PHP 8.1.2-1ubuntu2.14 (cli) (built: Aug 18 2023 11:41:11) (NTS)
Copyright (c) The PHP Group
Zend Engine v4.1.2, Copyright (c) Zend Technologies
with Zend OPcache v8.1.2-1ubuntu2.14, Copyright (c), by Zend Technologies

### MySQL
$ sudo apt install mysql-server

### composer.phar
$ curl -sS https://getcomposer.org/installer | php

[bitcoin] bitcoincoreのファイル構造 [その1]

まずGithubから bitcoincore のソースコードを clone してきます。
github上で見てもいいんですが、なんとなくローカルに落としたいですよね。。

$ git clone https://github.com/bitcoin/bitcoin.git
$ $ tree -L 3 -d
.
└── bitcoin
├── build-aux
│ └── m4
├── build_msvc
│ ├── bench_bitcoin
│ ├── bitcoin-cli
│ ├── bitcoind
│ ├── bitcoin-qt
│ ├── bitcoin-tx
│ ├── bitcoin-util
│ ├── bitcoin-wallet
│ ├── libbitcoin_cli
│ ├── libbitcoin_common
│ ├── libbitcoin_consensus
│ ├── libbitcoin_crypto
│ ├── libbitcoin_node
│ ├── libbitcoin_qt
│ ├── libbitcoin_util
│ ├── libbitcoin_wallet
│ ├── libbitcoin_wallet_tool
│ ├── libbitcoin_zmq
│ ├── libleveldb
│ ├── libminisketch
│ ├── libsecp256k1
│ ├── libtest_util
│ ├── libunivalue
│ ├── msbuild
│ ├── test_bitcoin
│ └── test_bitcoin-qt
├── ci
│ ├── lint
│ ├── retry
│ └── test
├── contrib
│ ├── completions
│ ├── debian
│ ├── devtools
│ ├── guix
│ ├── init
│ ├── linearize
│ ├── macdeploy
│ ├── message-capture
│ ├── qos
│ ├── seeds
│ ├── shell
│ ├── signet
│ ├── testgen
│ ├── tracing
│ ├── verify-binaries
│ ├── verify-commits
│ ├── windeploy
│ └── zmq
├── depends
│ ├── builders
│ ├── hosts
│ ├── packages
│ └── patches
├── doc
│ ├── design
│ ├── man
│ ├── policy
│ └── release-notes
├── share
│ ├── examples
│ ├── pixmaps
│ ├── qt
│ └── rpcauth
├── src
│ ├── bench
│ ├── common
│ ├── compat
│ ├── config
│ ├── consensus
│ ├── crc32c
│ ├── crypto
│ ├── index
│ ├── init
│ ├── interfaces
│ ├── ipc
│ ├── kernel
│ ├── leveldb
│ ├── logging
│ ├── minisketch
│ ├── node
│ ├── policy
│ ├── primitives
│ ├── qt
│ ├── rpc
│ ├── script
│ ├── secp256k1
│ ├── support
│ ├── test
│ ├── univalue
│ ├── util
│ ├── wallet
│ └── zmq
└── test
├── functional
├── fuzz
├── lint
├── sanitizer_suppressions
└── util

各ディレクトリ、各機能ごとの役割を細く見て行くことが必要ですね。

[C言語] 疑似乱数

rand()は 0 から RAND_MAXまでの疑似乱数を返す。stdlib.hに定義されている。
多くのプログラムはエポックからの経過秒数を種にして使用している。

#include <stdio.h>
#include <stdlib.h>

int main() {
    int i;
    printf("RAND_MAX: %u\n", RAND_MAX);
    srand(time(0));

    printf("0からRAND_MAXまでの乱数値\n");
    for(i=0; i< 8; i++)
        printf("%d\n", rand());
    printf("0から20までの乱数値\n");
    for(i=0; i< 8; i++)
        printf("%d\n", (rand()%20)+1);
    return 0;
}

$ ./a.out
RAND_MAX: 2147483647
0からRAND_MAXまでの乱数値
1059493860
583633074
1632571078
678819775
1658879329
1703267400
1565774963
996314262
0から20までの乱数値
13
4
2
13
13
7
11
18

[C言語] 関数のポインタ

#include <stdio.h>

int func_one() {
    printf("これは1つ目の関数です。\n");
    return 1;
}

int func_two() {
    printf("これは2つ目の関数です。\n");
    return 2;
}

int main() {
    int value;
    int (*function_ptr)();

    function_ptr = func_one;
    printf("function_ptr: 0x%08x\n", function_ptr);
    value = function_ptr();
    printf("戻り値: %d\n", value);

    function_ptr = func_two;
    printf("function_ptr: 0x%08x\n", function_ptr);
    value = function_ptr();
    printf("戻り値: %d\n", value);

    return 0;
}

$ ./a.out
function_ptr: 0xcdc907d4
これは1つ目の関数です。
戻り値: 1
function_ptr: 0xcdc907f4
これは2つ目の関数です。
戻り値: 2

[C言語] 構造体

time.hのtm構造体を使用する

#include <stdio.h>
#include <time.h>

int main() {
    long int seconds_since_epoch;
    struct tm current_time, *time_ptr;
    int hour, minute, second, day, month, year;

    seconds_since_epoch = time(0);
    printf("time() - エポックからの通算秒数: %ld\n", seconds_since_epoch);

    time_ptr = &current_time;

    localtime_r(&seconds_since_epoch, time_ptr);

    hour = current_time.tm_hour;
    minute = time_ptr->tm_min;
    second = *((int *) time_ptr);

    printf("現在の時間は: %02d:%02d:%02d\n", hour, minute, second);

    return 0;
}

$ ./a.out
time() – エポックからの通算秒数: 1707729486
現在の時間は: 03:18:06
$ ./a.out
time() – エポックからの通算秒数: 1707729492
現在の時間は: 03:18:12

#include <stdio.h>
#include <time.h>

void dump_time_struct_bytes(struct tm *time_ptr, int size){
    int i;
    unsigned char *raw_ptr;

    printf("0x%08x にある構造体の内容\n", time_ptr);
    raw_ptr = (unsigned char *) time_ptr;
    for(i=0; i<size; i++){
        printf("%02x ", raw_ptr[i]);
        if(i%16 == 15)
            printf("\n");
    }
    printf("\n");
}

int main() {
    long int seconds_since_epoch;
    struct tm current_time, *time_ptr;
    int hour, minute, second, i, *int_ptr;

    seconds_since_epoch = time(0);
    printf("time() - エポックからの通算秒数: %ld\n", seconds_since_epoch);

    time_ptr = &current_time;

    localtime_r(&seconds_since_epoch, time_ptr);

    hour = current_time.tm_hour;
    minute = time_ptr->tm_min;
    second = *((int *) time_ptr);

    printf("現在の時間は: %02d:%02d:%02d\n", hour, minute, second);

    dump_time_struct_bytes(time_ptr, sizeof(struct tm));

    minute = hour = 0;
    int_ptr = (int *) time_ptr;

    for(i=0; i < 3; i++) {
        printf("int ptr @ 0x08x : %d\n", int_ptr, *int_ptr);
        int_ptr++;
    }

    return 0;
}

$ ./a.out
time() – エポックからの通算秒数: 1707730079
現在の時間は: 03:27:59
0xf089a030 にある構造体の内容
3b 00 00 00 1b 00 00 00 03 00 00 00 0c 00 00 00
01 00 00 00 7c 00 00 00 01 00 00 00 2a 00 00 00
00 00 00 00 ff ff 00 00 a0 ab ff ff ff ff ff ff
00 a9 5d d4 aa aa 00 00
int ptr @ 0x08x : -259416016
int ptr @ 0x08x : -259416012
int ptr @ 0x08x : -259416008