LoginSignup
14
5

More than 1 year has passed since last update.

PHPを使ってSymbolブロックチェーンのトランザクションを送信する

Last updated at Posted at 2022-05-20

この記事は「自分の得意なプログラミング言語でSymbolブロックチェーンを動かす方法」をPHPで実践したものです。

PHPで様々なトランザクションを作成する方法はこちらをご参考ください。

アカウント作成

$sign_pair = sodium_crypto_sign_keypair();
$sign_secret = sodium_crypto_sign_secretkey($sign_pair);
$sign_public = sodium_crypto_sign_publickey($sign_pair);

echo 'Secretkey: ' . substr(sodium_bin2hex($sign_secret), 0, 64) . PHP_EOL;
echo 'PublicKey: ' . sodium_bin2hex($sign_public) . PHP_EOL;

アカウント復元

//Secretkey: 94ee0f4d7fe388ac4b04a6a6ae2ba969617879b83616e4d25710d688a89d80c7
//PublicKey: 5f594dfc018578662e0b5a2f5f83ecfb1cda2b32e29ff1d9b2c5e7325c4cf7cb

$sign_secret = sodium_hex2bin("94ee0f4d7fe388ac4b04a6a6ae2ba969617879b83616e4d25710d688a89d80c75f594dfc018578662e0b5a2f5f83ecfb1cda2b32e29ff1d9b2c5e7325c4cf7cb");
$sign_public = sodium_crypto_sign_publickey_from_secretkey($sign_secret);

echo 'Secretkey: ' . substr(sodium_bin2hex($sign_secret), 0, 64) . PHP_EOL;
echo 'PublicKey: ' . sodium_bin2hex($sign_public) . PHP_EOL;

php sodiumの仕様なのかSecretkeyが sign_secret + sign_public という構成をとっています。
つまり、sign_publicも控えておかないとアカウントが復元できません。
この点、何か知っている人がいればご助言ください。

トランザクション構築

use Base32\Base32;

$deadline_time = ((time()  + 7200) - 1637848847) * 1000;

$reserved1 = "00000000";
$signature = "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000";
$signer = sodium_bin2hex($sign_public);
$reserved2 = "00000000";
$version = bin2hex(pack('C', 1));
$networkType = bin2hex(pack('C', 152));
$txType = bin2hex(pack('v', 16724));
$fee = bin2hex(pack('P', 190000000));
$deadline = bin2hex(pack('P', $deadline_time));
$recipientAddress  = bin2hex(Base32::decode("TBUXMJAYYW3EH3XHBZXSBVGVKXKZS4EH26TINKI"));
$mosaicCount = bin2hex(pack('C', 1));
$txReserved = "00" . "00000000";
$mosaicId = bin2hex(pack('P', hexdec("3A8416DB2D53B6C8")));
$mosaicAmount = bin2hex(pack('P', 100));
$message = "00" . bin2hex('Hello PHP! Welcome to Symbol world!');
$messageSize = bin2hex(pack('v', strlen($message) / 2));

$verifiableData = 
	$version
	.$networkType
	.$txType
	.$fee
	.$deadline
	.$recipientAddress
	.$messageSize
	.$mosaicCount
	.$txReserved
	.$mosaicId
	.$mosaicAmount
	.$message;

トランザクション署名

$payload = "7fccd304802016bebbcd342a332f91ff1f3bb5e902988b352697be245f48e836" . $verifiableData;

$signature = sodium_bin2hex(sodium_crypto_sign_detached(sodium_hex2bin($payload), $sign_secret));
echo 'Signature: ' . $signature . PHP_EOL;

トランザクションの通知

ノードにトランザクションを通知します。

$txSize = bin2hex(pack('V', strlen($verifiableData) / 2 + 108));
$txBuffer = 
	$txSize
	.$reserved1
	.$signature
	.$signer
	.$reserved2
	.$verifiableData;

echo $txBuffer . PHP_EOL;

$node = "https://sym-test-01.opening-line.jp:3001";
$params = array(
    "payload" => $txBuffer
);
$params = json_encode($params); // json化
$header = array(
    "Content-Type: application/json",
);

$context = array(
    "http" => array(
        "method"  => 'PUT',
        "header"  => implode("\r\n", $header),
        "content" => $params
    )
);

$json_response = file_get_contents($node . "/transactions" ,false,stream_context_create($context));
echo $json_response . PHP_EOL;
echo $http_response_header . PHP_EOL;

確認

トランザクションのハッシュ値を出力してノードに照会します。

$digest = hash('sha3-256',
	sodium_hex2bin(
		$signature . $signer . "7fccd304802016bebbcd342a332f91ff1f3bb5e902988b352697be245f48e836" . $verifiableData
	)
);

echo "txhash: " . $digest. PHP_EOL;
echo $node . "/transactionStatus/" . $digest . PHP_EOL;
echo $node . "/transactions/confirmed/" . $digest . PHP_EOL;
echo "https://testnet.symbol.fyi/transactions/" . $digest . PHP_EOL;

複雑なトランザクション送信についてはまた後日に。

14
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
14
5