この記事では、Symbol SDKを使ってXYMとモザイクの残高表示プログラムを作ります。
ここでは、Webページ制作に使うHTMLファイルとブラウザに利用できるようにカスタマイズしたSymbol SDKが同じフォルダにあるものとして説明します。
なので、Symbol SDKを用意していない方は、以下の記事を参照してください。
残高表示プログラムについて
以下のコードについて説明します。
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/uikit@3.5.8/dist/css/uikit.min.css" />
<script src="https://cdn.jsdelivr.net/npm/uikit@3.5.8/dist/js/uikit.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/uikit@3.5.8/dist/js/uikit-icons.min.js"></script>
<script src="symbol-sdk-0.21.0.js"></script>
<title>Symbol残高照会</title>
</head>
<body style="margin:30px;">
<h1>Symbolを触ってみる</h1>
<h2>残高の確認</h2>
<div style="margin-top:10px;">
Address:<input type="text" id="address" class="uk-input">
</div>
<div style="margin-top:10px;">
Balance:<span id="balance">0</span> xym
</div>
<div id="balance_get" class="uk-button uk-button-primary" style="margin-top:10px;">残高取得</div>
<script>
const symbol=require("/node_modules/symbol-sdk");
let address;
const nodeAddress='http://api-01.ap-northeast-1.0.10.0.x.symboldev.network:3000';
const networkGenerationHash="1DFB2FAA9E7F054168B0C5FCB84F4DEB62CC2B4D317D861F3168D161F54EA78B";
const repositoryFactory=new symbol.RepositoryFactoryHttp(nodeAddress);
const accountHttp=repositoryFactory.createAccountRepository();
$('#balance_get').click(function(){
address=symbol.Address.createFromRawAddress($('#address').val());
accountHttp.getAccountInfo(address)
.subscribe(function(accountInfo){
$('#balance').text(accountInfo.mosaics[0].amount.compact()/1000000);
console.log(accountInfo.mosaics[0].id.toHex())
}, err => console.error(err));
});
</script>
</body>
</html>
このプログラムの完成版は以下になります。
これについて説明します。
head要素について
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js">
</script>
この要素で、jQueryを読み込みます。
以下の3行でCSSのフレームワークであるUIKitを読み込んでいます。
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/uikit@3.5.8/dist/css/uikit.min.css" />
<script src="https://cdn.jsdelivr.net/npm/uikit@3.5.8/dist/js/uikit.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/uikit@3.5.8/dist/js/uikit-icons.min.js"></script>
Symbol SDKをHTMLファイルと同じフォルダ内に置いている上で、このようにして書きます。
<script src="symbol-sdk-0.21.0.min.js"></script>
このように書くことで、Symbol SDKをHTMLファイルに読むこむことができるようになります。
また、以下のようにして書くと、Symbol SDKをネットワークからダウンロードして読む込みこともできます。
<script src=“https://xembook.github.io/nem2-browserify/symbol-sdk-0.21.0.js”></script>
body要素について
input要素を使う事で、アドレスの入力フォームをつくることができます。
<div style="margin-top:10px;">
Address:<input type="text" id="address" class="uk-input">
</div>
ここでは、UIKITを使っているので入力枠を見やすくしていますが、最低限、これだけでもOKです。
<input type="text">
また、以下のコードで残高(Balance)を表示させます。ここでは初期値として0としています。
Balance:<span id="balance">0</span> xym
以下のコードで、「残高取得」と書かれたボタンを実装しています。このボタンをクリックすることで実行できます。
<div id="balance_get" class="uk-button uk-button-primary" style="margin-top:10px;">残高取得</div>
script要素について
以下の1行で、Symbol SDKを呼び出す宣言になります。
const symbol=require("/node_modules/symbol-sdk");
このように書く事で、symbolという定数にSymbol SDK内の情報を代入することになります。ここで、requireはnode.jsで定義されるコマンドです。
それ以降、symbolという定数を使う事で、Symbol SDKの中身を使えるようになります。この1行は基本的にコピペでOKです。また、ここではsymbolを定数としましたが、定数名はお好みでOKです。
また、アドレスを入れておく事を確保するための変数をここで用意しておきます。
let address
以下のコードでどこのノードアドレスに情報を問い合わせるのかを定数nodeAddressにて設定します。
const nodeAddress='http://api-01.eu-central-1.096x.symboldev.network:3000';
ノードアドレスを調べたい場合は、Symbol Walletにて、赤い四角で囲んだところをクリックして
ノードのアドレスを確認できます。ここから、ノードを選んでください。
ノードを選んだら、それに対応するネットワークジェネレーションハッシュが必要になります。
const networkGenerationHash="1DFB2FAA9E7F054168B0C5FCB84F4DEB62CC2B4D317D861F3168D161F54EA78B";
このジェネレーションハッシュは以下のページにて見つけ方が書かれています。
https://docs.symbolplatform.com/ja/getting-started/first-application.html
つまり、ノードアドレスが、
http://api-01.ap-northeast-1.0.10.0.x.symboldev.network:3000
の場合は
http://api-01.ap-northeast-1.0.10.0.x.symboldev.network:3000/node/info
ということになります。このURLで開いてみると・・・
networkGenerationHashSeedに、ネットワークジェネレーションハッシュが書かれています。これをコードに書きます。
ノードのURLとネットワークジェネレーションハッシュは一対一に結びついているので、ノードURLを決めたら、必ずネットワークジェネレーションハッシュを見つけてください。
次に、このコードを見ます。
const repositoryFactory=new symbol.RepositoryFactoryHttp(nodeAddress);
これは、Symbolの中身の仕組みを使うのに、nodeAddressを引数としたrepositoryFactoryを定数としておいたものです。
次に、このコードを見ます。
const accountHttp=repositoryFactory.createAccountRepository();
定数 accountHttpは、先ほど書いたrepositoryFactoryをcreateAccountRepositoryで読んで来いというものです。
ここまで読んだ以下のコード
const symbol=require("/node_modules/symbol-sdk");
let address;
const nodeAddress='http://api-01.eu-central-1.096x.symboldev.network:3000';;
const networkGenerationHash="1DFB2FAA9E7F054168B0C5FCB84F4DEB62CC2B4D317D861F3168D161F54EA78B";
const repositoryFactory=new symbol.RepositoryFactoryHttp(nodeAddress);
const accountHttp=repositoryFactory.createAccountRepository();
は、基本的にコピペでOKで、変えるべきなのは、ノードアドレスと、そのジェネレーションハッシュということになります。
次に、このコードについて
$('#balance_get').click(function(){
これはIDがbalance_getの要素(「残高取得」と書かれたボタン)をクリックしたら、以下の処理を実行するというものです。
address=symbol.Address.createFromRawAddress($('#address').val());
accountHttp.getAccountInfo(address)
.subscribe(function(accountInfo){
$('#balance').text(accountInfo.mosaics[0].amount.compact()/1000000);
console.log(accountInfo.mosaics[0].id.toHex())
}, err => console.error(err));
以上のコードについて、それぞれ説明します。
まず、以下のコードについて説明します。
address=symbol.Address.createFromRawAddress($('#address').val());
これは、input要素のIDを「address」と指定することで、そのinput要素から取得したデータと.valを読んでくる事ができます。それをcreateFromRawAddressで、Symbol SDKの中で使うアドレスに変換されたものを、変数addressに代入するという意味です。
この変数addressの中身は、アドレスとネットワークのタイプ(152番)がオブジェクトデータとして入っているようです。実際にそうなっている事を調べるには、このコードのあとに、
alert(JSON.stringify(address));
として、input要素をクリック(残高収得をクリック)するとわかります。
調べてみると、確かにそうなっています!!
このコードは基本的にコピペでOKで、もしアドレスを固定で指定したい場合はaddress=symbol.Address.createFromRawAddress($('TADAFIKEA2DCTO6CJPNQHT3W543W2RBMJ6QITPI').val());
として、直接アドレスを書いてもOKです。
今度は、このコードを見てみます。
accountHttp.getAccountInfo(address)
.subscribe(function(accountInfo){
$('#balance').text(accountInfo.mosaics[0].amount.compact()/1000000);
console.log(accountInfo.mosaics[0].id.toHex())
getAccountInfo(address)でaddressの情報を取ってきて、それを非同期処理(sunscribe)(結果が返ってきた処理から順番に処理すること)により、addressに入っている情報が入ってきたら、入ってきた順番に処理をしていくことになります。その結果がaccountInfoに返ってきます。返ってきたら、IDを「balance」とした要素にテキストとして、モザイクの0番目の量をコンパクト化したものを100万で割ったものを表示することになります。
Balance:<span id="balance">0</span> xym
すると、0として最初は表示していたのが、実際の残高として表示されます。
ここで、このコードをaccountInfoを見てみます。そのためには、(accountinfo)の後にconsole.log(accountInfo)を書きます。つまり、コードを以下のようにするということです。accountHttp.getAccountInfo(address).subscribe(function(accountInfo)
console.log(accountInfo);
実行してみて、Google Chromeのデベロッパーツールのconsoleを見てみると・・・
この中身を見てみます。
ここで、mosaicsの中身をみると・・・
0番目のモザイクを見てみると・・・
赤い四角で囲んだものをcompactという関数で組み合わせると、残高が表示されるようになります。
けど、表示されるときは、μXYMで表示されているので、XYMで表示するために、100万で割っています。
ここで、0番目のモザイクはXYMの事を指していますが、1番目と2番目はXYM以外のモザイクを表します。
実際にウォレットを見てみます。
SymbolではXYMとモザイクの送信方法は、IDを指定するだけで同じようにできます。
つまり、XYMの場合のIDは「5B66E76BECAD0860」であり、自作のモザイクのID「7DC393D57931CA69」や「519F7A167869851C」を送信するとしてやると、XYMもモザイクも同じように送信することができます。
accountHttp.getAccountInfo(address).subscribe(function(accountInfo){$('#balance').text(accountInfo.mosaics[1].amount.compact()/1000000);}, err => console.error(err));
とすると、モザイクの残高が表示されるようになります。
つまり、
accountHttp.getAccountInfo(address).subscribe(function(accountInfo){ }, err => console.error(err));
は、コピペでOKで、{ }の中に残高を表示するプログラムを書くとなると、accountHttp.getAccountInfo(address).subscribe(function(accountInfo){
$('#balance').text(accountInfo.mosaics[0].amount.compact()/1000000);
}, err => console.error(err));
となるわけです。基本的に、この一文はコピペでOKであり、XYM以外のモザイクを表示したいときに、accountinfo.mosaics[1]とかにします。
最後に、このコードについて見てみます。
console.log(accountInfo.mosaics[0].id.toHex())
これは、モザイクのIDを見る事ができます。
ここで、lower、higherが分かれているので、結合するために、toHEX()とすることで、16進数にして合体させる処理をしています。
ここで、実行させてみると・・・
このように、IDが表示されています。ここでは0番目のモザイクのIDを指定しているので、XYMのIDが表示されています。
ここで、
console.log(accountInfo.mosaics[1].id.toHex()
として、1番目のモザイクのIDを調べてみると、以下のようになります。
先ほどのウォレットと比較してみると・・・
これで、1番目のモザイクは何なのかがわかりました。
このようにして、何番目のモザイクなのかを確認することができます。
これは、モザイクのIDを調べたいとき、必要に応じて書いてください。
最後に・・・
では、XYMとモザイクを一気に残高照会をしたときは、このように書きます。
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/uikit@3.5.8/dist/css/uikit.min.css" />
<script src="https://cdn.jsdelivr.net/npm/uikit@3.5.8/dist/js/uikit.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/uikit@3.5.8/dist/js/uikit-icons.min.js"></script>
<script src="symbol-sdk-0.21.0.min.js"></script>
<title>Symbol残高照会</title>
</head>
<body style="margin:30px;">
<h1>Symbolを触ってみる</h1>
<h2>残高の確認</h2>
<div style="margin-top:10px;">
Address:<input type="text" id="address" class="uk-input">
</div>
<div style="margin-top:10px;">
Balance:<span id="balance0">0</span> xym
Balance:<span id="balance1">0</span> xym
</div>
<div id="balance_get" class="uk-button uk-button-primary" style="margin-top:10px;">残高取得</div>
<script>
const symbol=require("/node_modules/symbol-sdk");
let address;
const nodeAddress='http://api-01.ap-northeast-1.0.10.0.x.symboldev.network:3000';
const repositoryFactory=new symbol.RepositoryFactoryHttp(nodeAddress);
const accountHttp=repositoryFactory.createAccountRepository();
$('#balance_get').click(function(){
address=symbol.Address.createFromRawAddress($('#address').val());
accountHttp.getAccountInfo(address)
.subscribe(function(accountInfo){
for(i=0;i<accountInfo.mosaics.length;i++){
$('#balance'+i).text(accountInfo.mosaics[i].amount.compact()/1000000);
}
console.log(accountInfo.mosaics[0].id.toHex())
}, err => console.error(err));
});
</script>
</body>
</html>
つまり、
$('#balance').text(accountInfo.mosaics[0].amount.compact()/1000000)
に関して、accountInfo.mosaicsに入っている配列の長さ分を繰り返せばよいので、accountInfo.mosaics.lengthと書くことになるので、for文は
for(i=0;i<accountInfo.mosaics.length;i++){
$('#balance'+i).text(accountInfo.mosaics[i].amount.compact()/1000000);
}
となります。
また、それを画面に表示させたいので、
<div style="margin-top:10px;">
Balance:<span id="balance0">0</span> xym
Balance:<span id="balance1">0</span> mosaic </div>
と書く事になります。
※この記事は、nemlogで企画されたイベントであるしゅうさんの勉強会「しゅうさんといっしょ!」の内容の一部をまとめたものです。