Symbol

Symbol入門 その4

はじめてのアプリケーションを作成

少しずつSymbolの技術について勉強中です。

まずは、入門ということで下記の公式ドキュメントを読んでいくことにしました。

入門 — Symbol Documentation

日本語になっているのは非常にありがたいですね。

Symbol入門 その3にて開発環境を構築したので、今回は実際にサンプルアプリケーションを作ってみたいと思います。

はじめてのアプリケーションを作成

作成したコードは下記のリポジトリにアップしています。

symbol-first-application

typescriptのコーディング環境整備

前回作成したプロジェクトのフォルダにコーディング環境を整備します。

// ソースコード格納用フォルダ、ビルド格納用フォルダを作成
$ mkdir src build
// tsconfigを生成
$ tsc --init

tsconfigを以下のとおり編集し、ビルド用の設定を行います。

"outDir": "./build",
"rootDirs": ["src"],

以上で準備は完了です。

サンプルアプリケーション作成

今回作成するサンプルアプリケーションはチケットの売買を行うようなサンプルのようです。 イメージは以下のような感じです。 アプリケーションイメージ

ユーザアカウントの作成

まずは、販売者用のアカウントは前回作成しているので、ユーザ用のアカウントを追加で作成します。

$ symbol-cli account generate --network TEST_NET --save --url http://api-01.us-east-1.testnet.symboldev.network:3000 --profile customer

ユーザを作成したあと、下記コマンドを実行するとプロファイルが2つになっていることが確認できます。

$ symbol-cli profile list

┌──────────────────┬──────────────────────────────────────────────────────────────────┐
│ Property         │ Value                                                            │
├──────────────────┼──────────────────────────────────────────────────────────────────┤
│ Name             │ testnet                                                          │
├──────────────────┼──────────────────────────────────────────────────────────────────┤
│ Address          │ TBJHBF-KL5NL4-UDGN63-6KG5PD-CKXPCO-YTYYWN-YEA                    │
├──────────────────┼──────────────────────────────────────────────────────────────────┤
│ Network          │ TEST_NET                                                         │
├──────────────────┼──────────────────────────────────────────────────────────────────┤
│ Node URL         │ http://api-01.us-east-1.testnet.symboldev.network:3000           │
├──────────────────┼──────────────────────────────────────────────────────────────────┤
│ Generation Hash  │ 45FBCF2F0EA36EFA7923C9BC923D6503169651F7FA4EFC46A8EAF5AE09057EBD │
├──────────────────┼──────────────────────────────────────────────────────────────────┤
│ Network Currency │ name: symbol.xym, divisibility: 6                                │
├──────────────────┼──────────────────────────────────────────────────────────────────┤
│ Profile type     │ PrivateKey                                                       │
└──────────────────┴──────────────────────────────────────────────────────────────────┘
┌──────────────────┬──────────────────────────────────────────────────────────────────┐
│ Property         │ Value                                                            │
├──────────────────┼──────────────────────────────────────────────────────────────────┤
│ Name             │ customer                                                         │
├──────────────────┼──────────────────────────────────────────────────────────────────┤
│ Address          │ TDDH3J-UCWMFW-2VSKLD-JM7GB3-P7LIDI-L54RBS-2QA                    │
├──────────────────┼──────────────────────────────────────────────────────────────────┤
│ Network          │ TEST_NET                                                         │
├──────────────────┼──────────────────────────────────────────────────────────────────┤
│ Node URL         │ http://api-01.us-east-1.testnet.symboldev.network:3000           │
├──────────────────┼──────────────────────────────────────────────────────────────────┤
│ Generation Hash  │ 45FBCF2F0EA36EFA7923C9BC923D6503169651F7FA4EFC46A8EAF5AE09057EBD │
├──────────────────┼──────────────────────────────────────────────────────────────────┤
│ Network Currency │ name: symbol.xym, divisibility: 6                                │
├──────────────────┼──────────────────────────────────────────────────────────────────┤
│ Profile type     │ PrivateKey                                                       │
└──────────────────┴──────────────────────────────────────────────────────────────────┘

Default profile:testnet

販売者アカウントのモニタリング

トランザクションを監視してみます。

$ symbol-cli monitor all --address TBJHBF-KL5NL4-UDGN63-6KG5PD-CKXPCO-YTYYWN-YEA

以下のような表示になっていればモニタできています。 新しいブロックができたり、トランザクションが発行されたりするとリアルタイムに表示されます。

Monitoring TBJHBF-KL5NL4-UDGN63-6KG5PD-CKXPCO-YTYYWN-YEA using http://api-01.us-east-1.testnet.symboldev.network:3000

チケットの作成

モザイクにてチケットを作成してみます。 下記コマンドで作成します。

$ symbol-cli transaction mosaic --amount 10 --supply-mutable --divisibility 0 --duration 1000 --max-fee 2000000 --sync --profile testnet

いくつか質問されますので、下記のように答えると下記の通り作成されます。

✔ Enter your wallet password: … ********
✔ Do you want a non-expiring mosaic? … yes
✔ Do you want this mosaic to be transferable? … yes
✔ Do you want this mosaic to be restrictable? … yes
✔ Select the transaction announce mode: › normal
┌───────────────────────────────────────────────────────────────────────────────────────────────────────┐
│                                          AGGREGATE_COMPLETE                                           │
├────────────────────────────────────┬──────────────────────────────────────────────────────────────────┤
│ Max fee:                           │ 2,000,000                                                        │
├────────────────────────────────────┼──────────────────────────────────────────────────────────────────┤
│ Network type:                      │ TEST_NET                                                         │
├────────────────────────────────────┼──────────────────────────────────────────────────────────────────┤
│ Deadline:                          │ 2021-03-21 15:52:48.094                                          │
├────────────────────────────────────┴──────────────────────────────────────────────────────────────────┤
│                             Inner transaction 1 of 2 - MOSAIC_DEFINITION                              │
├────────────────────────────────────┬──────────────────────────────────────────────────────────────────┤
│ [Inner tx. 1 of 2] Mosaic Id:      │ 7460F899DF487963                                                 │
├────────────────────────────────────┼──────────────────────────────────────────────────────────────────┤
│ [Inner tx. 1 of 2] Duration:       │ unlimited                                                        │
├────────────────────────────────────┼──────────────────────────────────────────────────────────────────┤
│ [Inner tx. 1 of 2] Divisibility:   │ 0                                                                │
├────────────────────────────────────┼──────────────────────────────────────────────────────────────────┤
│ [Inner tx. 1 of 2] Supply mutable: │ true                                                             │
├────────────────────────────────────┼──────────────────────────────────────────────────────────────────┤
│ [Inner tx. 1 of 2] Transferable:   │ true                                                             │
├────────────────────────────────────┼──────────────────────────────────────────────────────────────────┤
│ [Inner tx. 1 of 2] Restrictable:   │ true                                                             │
├────────────────────────────────────┴──────────────────────────────────────────────────────────────────┤
│                            Inner transaction 2 of 2 - MOSAIC_SUPPLY_CHANGE                            │
├────────────────────────────────────┬──────────────────────────────────────────────────────────────────┤
│ [Inner tx. 2 of 2] Mosaic Id:      │ 7460F899DF487963                                                 │
├────────────────────────────────────┼──────────────────────────────────────────────────────────────────┤
│ [Inner tx. 2 of 2] Direction:      │ Increase supply                                                  │
├────────────────────────────────────┼──────────────────────────────────────────────────────────────────┤
│ [Inner tx. 2 of 2] Delta:          │ 10                                                               │
├────────────────────────────────────┴──────────────────────────────────────────────────────────────────┤
│                                           Signature details                                           │
├────────────────────────────────────┬──────────────────────────────────────────────────────────────────┤
│ Payload:                           │ 38010000000000005595EB3AF43B1EFE84B2FBDF3F0E1DC39774C141469C17E4 │
│                                    │ 233788E0C94308E16C125CC93C83C208AED0B90EEF671C064EF1164489B76EC8 │
│                                    │ 6FD924C2363FCA04347EE9E8B84918559FBA9BEA2538D8AEB1D3FA1583EB75F1 │
│                                    │ 3C0246DB5D4CE181000000000198414180841E00000000005E2ECCFB09000000 │
│                                    │ 04DD29FB90F7CD7F25DF01A2402D7479F7AFF888F840724B2F15156202180F9A │
│                                    │ 90000000000000004600000000000000347EE9E8B84918559FBA9BEA2538D8AE │
│                                    │ B1D3FA1583EB75F13C0246DB5D4CE1810000000001984D41637948DF99F86074 │
│                                    │ 000000000000000039E1BF11070000004100000000000000347EE9E8B8491855 │
│                                    │ 9FBA9BEA2538D8AEB1D3FA1583EB75F13C0246DB5D4CE1810000000001984D42 │
│                                    │ 637948DF99F860740A000000000000000100000000000000                 │
├────────────────────────────────────┼──────────────────────────────────────────────────────────────────┤
│ Hash:                              │ 2565DD6494FD3428E24195553B1A956C8D9501428785149910D4EF9E4A57EC67 │
├────────────────────────────────────┼──────────────────────────────────────────────────────────────────┤
│ Signer:                            │ 347EE9E8B84918559FBA9BEA2538D8AEB1D3FA1583EB75F13C0246DB5D4CE181 │
└────────────────────────────────────┴──────────────────────────────────────────────────────────────────┘
✔ Do you want to announce this transaction? … yes

SUCCESS Transaction announced

SUCCESS Transaction confirmed

作成に成功すると、モニタしていた側にも結果が表示されます。

New transaction confirmed:
┌───────────────────────────────────────────────────────────────────────────────────────────────────────┐
│                                          AGGREGATE_COMPLETE                                           │
├────────────────────────────────────┬──────────────────────────────────────────────────────────────────┤
│ Hash:                              │ 2565DD6494FD3428E24195553B1A956C8D9501428785149910D4EF9E4A57EC67 │
├────────────────────────────────────┼──────────────────────────────────────────────────────────────────┤
│ Max fee:                           │ 2,000,000                                                        │
├────────────────────────────────────┼──────────────────────────────────────────────────────────────────┤
│ Height (Block):                    │ 205,909                                                          │
├────────────────────────────────────┼──────────────────────────────────────────────────────────────────┤
│ Network type:                      │ TEST_NET                                                         │
├────────────────────────────────────┼──────────────────────────────────────────────────────────────────┤
│ Deadline:                          │ 2021-03-21 15:52:48.094                                          │
├────────────────────────────────────┼──────────────────────────────────────────────────────────────────┤
│ Signer:                            │ TBJHBF-KL5NL4-UDGN63-6KG5PD-CKXPCO-YTYYWN-YEA                    │
├────────────────────────────────────┴──────────────────────────────────────────────────────────────────┤
│                             Inner transaction 1 of 2 - MOSAIC_DEFINITION                              │
├────────────────────────────────────┬──────────────────────────────────────────────────────────────────┤
│ [Inner tx. 1 of 2] Mosaic Id:      │ 7460F899DF487963                                                 │
├────────────────────────────────────┼──────────────────────────────────────────────────────────────────┤
│ [Inner tx. 1 of 2] Duration:       │ unlimited                                                        │
├────────────────────────────────────┼──────────────────────────────────────────────────────────────────┤
│ [Inner tx. 1 of 2] Divisibility:   │ 0                                                                │
├────────────────────────────────────┼──────────────────────────────────────────────────────────────────┤
│ [Inner tx. 1 of 2] Supply mutable: │ true                                                             │
├────────────────────────────────────┼──────────────────────────────────────────────────────────────────┤
│ [Inner tx. 1 of 2] Transferable:   │ true                                                             │
├────────────────────────────────────┼──────────────────────────────────────────────────────────────────┤
│ [Inner tx. 1 of 2] Restrictable:   │ true                                                             │
├────────────────────────────────────┴──────────────────────────────────────────────────────────────────┤
│                            Inner transaction 2 of 2 - MOSAIC_SUPPLY_CHANGE                            │
├────────────────────────────────────┬──────────────────────────────────────────────────────────────────┤
│ [Inner tx. 2 of 2] Mosaic Id:      │ 7460F899DF487963                                                 │
├────────────────────────────────────┼──────────────────────────────────────────────────────────────────┤
│ [Inner tx. 2 of 2] Direction:      │ Increase supply                                                  │
├────────────────────────────────────┼──────────────────────────────────────────────────────────────────┤
│ [Inner tx. 2 of 2] Delta:          │ 10                                                               │
└────────────────────────────────────┴──────────────────────────────────────────────────────────────────┘

チケットの送信

コードを作成する前に、networkGenerationHashを取得しておきます。 networkGenerationHashは以下URLにアクセスすることで取得できます。

http://api-01.us-east-1.testnet.symboldev.network:3000/node/info

上記にアクセスすると、以下のようなjsonが取得できるので、その中からnetworkGenerationHashSeedをコピーしておきます。

{"version":655624,"publicKey":"31D7A021B0C8BFBAAA64AD040E332BE24421541004E9F01D0E0F459925342475","networkGenerationHashSeed":"45FBCF2F0EA36EFA7923C9BC923D6503169651F7FA4EFC46A8EAF5AE09057EBD","roles":2,"port":7900,"networkIdentifier":152,"host":"","friendlyName":"api-01-us-east-1","nodePublicKey":"F57FB70C3F51663D0DDF47303C93ADC8FDD266DC61BBA67B983052D075FD900E"}

以下のようにソースコードを書きます。

import { MosaicId, Address, NetworkType, TransferTransaction, Deadline, Mosaic, UInt64, PlainMessage, Account, RepositoryFactoryHttp } from "symbol-sdk";

// replace with mosaic id
const mosaicIdHex = '7460F899DF487963';
const mosaicId = new MosaicId(mosaicIdHex);
// replace with customer address
const rawAddress = 'TDDH3J-UCWMFW-2VSKLD-JM7GB3-P7LIDI-L54RBS-2QA';
const recipientAddress = Address.createFromRawAddress(rawAddress);
// replace with network type
const networkType = NetworkType.TEST_NET;

const transferTransaction = TransferTransaction.create(
  Deadline.create(1573430400),
  recipientAddress,
  [new Mosaic(mosaicId, UInt64.fromUint(1))],
  PlainMessage.create('enjoy your ticket'),
  networkType,
  UInt64.fromUint(2000000),
);

// replace with ticket vendor private key
const privateKey = 'A1C760B38DA4F36A1FE1825C5B355D03223B84163D01ABAEDAF11B119DAB3ACB';
const account = Account.createFromPrivateKey(privateKey, networkType);
// replace with meta.networkGenerationHash (nodeUrl + '/node/info')
const networkGenerationHash =
  '45FBCF2F0EA36EFA7923C9BC923D6503169651F7FA4EFC46A8EAF5AE09057EBD';
const signedTransaction = account.sign(
  transferTransaction,
  networkGenerationHash,
);

// replace with node endpoint
const nodeUrl = 'http://api-01.us-east-1.testnet.symboldev.network:3000';
const repositoryFactory = new RepositoryFactoryHttp(nodeUrl);

const transactionHttp = repositoryFactory.createTransactionRepository();

transactionHttp.announce(signedTransaction).subscribe(
  (x) => console.log(x),
  (err) => console.error(err),
);

実行

ts-nodeにて上記のコードを実行してみます。

$ ts-node src/transfer-ticket.ts

実行してみると、utf8パッケージがないとエラーが発生したため、追加でutf8パッケージをインストールします。

$ npm install utf8

再度実行すると以下のように表示されました。

TransactionAnnounceResponse {
  message: 'packet 9 was pushed to the network via /transactions'
}

ユーザの情報を表示すると、モザイクが付与されていることが確認できます。

$ symbol-cli account info --profile customer

Account Information
┌───────────────────┬──────────────────────────────────────────────────────────────────┐
│ Property          │ Value                                                            │
├───────────────────┼──────────────────────────────────────────────────────────────────┤
│ Address           │ TDDH3J-UCWMFW-2VSKLD-JM7GB3-P7LIDI-L54RBS-2QA                    │
├───────────────────┼──────────────────────────────────────────────────────────────────┤
│ Address Height    │ 205964                                                           │
├───────────────────┼──────────────────────────────────────────────────────────────────┤
│ Public Key        │ 0000000000000000000000000000000000000000000000000000000000000000 │
├───────────────────┼──────────────────────────────────────────────────────────────────┤
│ Public Key Height │ 0                                                                │
├───────────────────┼──────────────────────────────────────────────────────────────────┤
│ Importance        │ 0                                                                │
├───────────────────┼──────────────────────────────────────────────────────────────────┤
│ Importance Height │ 0                                                                │
└───────────────────┴──────────────────────────────────────────────────────────────────┘
Balance Information
┌──────────────────┬─────────────────┬─────────────────┬───────────────────┐
│ Mosaic Id        │ Relative Amount │ Absolute Amount │ Expiration Height │
├──────────────────┼─────────────────┼─────────────────┼───────────────────┤
│ 7460F899DF487963 │ 1               │ 1               │ Never             │
└──────────────────┴─────────────────┴─────────────────┴───────────────────┘

ひとまず、今日はここまでにします。
明日は今回作成したコードについてもう少し深堀りしたいと思います。
その後、もう少し実践的なサンプルシステムを今回のお題をもとに作ってみたいと思います。

こけっこー
仮想通貨について1から勉強中です。 普段はSEをしています。 Symbolの技術に強い興味を持ち、 本ブログをはじめました。
Twitter
Amazon