2
Help us understand the problem. What are the problem?

More than 1 year has passed since last update.

posted at

updated at

Symbol SDKを利用したトランザクションの発行プログラム

この記事では、Symbol SDKを使ってトランザクションの発行するプログラムについて解説します。トランザクションを発行することで、XYMやモザイクを送金することができます。

ここでは、Node.jsをインストールし、またWebページ制作に使うHTMLファイルとブラウザに利用できるようにカスタマイズしたSymbol SDKが同じフォルダにあるものとして説明します。

なので、Symbol SDKを用意していない方は、以下の記事を参照してください。

ブラウザ環境でのSymbolの実行環境の構築について

 

トランザクションの発行プログラムについて

以下のプログラムについて説明します。

<!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;">
      Receiver Address:<input type="text" id="receiver_address" class="uk-input">
    </div>
    <div style="margin-top:10px;">
      Sender Private Key:<input type="text" id="pk" class="uk-input">
    </div>
    <div id="issue_tx" class="uk-button uk-button-primary" style="margin-top:10px;">1xym送金</div>

    <script>
      const symbol=require("/node_modules/symbol-sdk");
      let privateKey;
      const nodeAddress='http://api-01.ap-northeast-1.0.10.0.x.symboldev.network:3000';
      const networkGenerationHash="6C1B92391CCB41C96478471C2634C111D9E989DECD66130C0430B5B8D20117CD";
      const repositoryFactory=new symbol.RepositoryFactoryHttp(nodeAddress);
      const accountHttp=repositoryFactory.createAccountRepository();

      $('#issue_tx').click(function(){
        privateKey=$('#pk').val();
        let tx = symbol.TransferTransaction.create(
          symbol.Deadline.create(),
          symbol.Address.createFromRawAddress($('#receiver_address').val()), 
          [new symbol.Mosaic (new symbol.MosaicId('5E62990DCAC5BE8A'),symbol.UInt64.fromUint(100))],
          symbol.PlainMessage.create('Send Symbol'),
          symbol.NetworkType.TEST_NET,
          symbol.UInt64.fromUint(100000)
        );
        const account = symbol.Account.createFromPrivateKey(privateKey,symbol.NetworkType.TEST_NET);
        let signedTx = account.sign(tx,networkGenerationHash);
        console.log(signedTx);
        new symbol.TransactionHttp(nodeAddress).announce(signedTx)
        .subscribe(function(x){
          alert("Txが発行されました!");
          console.log(x);
        },function(x){
          alert("エラーが発生しました!");
          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要素について

ここで、このプログラムでは2つの入力枠を用意しています。

 

以下のコードがRecever Addressの入力枠となるコードです。

 <div style="margin-top:10px;">
Receiver Address:<input type="text" id="receiver_address" class="uk-input">
</div>

次に、以下のコードでSender Private Keyの入力枠となるコードです。

<div style="margin-top:10px;">
Sender Private Key:<input type="text" id="pk" class="uk-input">
</div>

そして、以下のコードがボタンとなるものになります。このボタンをクリックすると、実行となります。

<div id="issue_tx" class="uk-button uk-button-primary" style="margin-top:10px;">1xym送金</div>

script要素について

以下の1行で、Symbol SDKに入っている情報を変数symbolに代入します。

const symbol=require("/node_modules/symbol-sdk");

つまり、Symbol SDKを呼び出す宣言になります。

また、プライベートキーを入れておく事を確保するために、変数をここで用意しておきます。

let privateKey

以下のコードでどこのノードアドレスに情報を問い合わせるのかを定数nodeAddressにて設定します。

const nodeAddress='http://api-01.eu-central-1.096x.symboldev.network:3000';

ノードアドレスを調べたい場合は、赤い四角で囲んだところをクリックしてノードのアドレスを確認できます。

 

ここから、ノードを選んでください。

ノードを選んだら、それに対応するネットワークジェネレーションハッシュが必要になります。

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で、変えるべきなのは、ノードアドレスと、そのジェネレーションハッシュということになります。

以下のコードについて、IDをissue_txで定義したボタン(「1XYM送金」と書かれたボタン)をクリックすると、

$('#issue_tx').click(function(){

の文以降の処理が発生します。

 privateKey=$('#pk').val();
        let tx = symbol.TransferTransaction.create(
          symbol.Deadline.create(),
          symbol.Address.createFromRawAddress($('#receiver_address').val()), 
          [new symbol.Mosaic (new symbol.MosaicId('5E62990DCAC5BE8A'),symbol.UInt64.fromUint(100))],
          symbol.PlainMessage.create('Send Symbol'),
          symbol.NetworkType.TEST_NET,
          symbol.UInt64.fromUint(100000)
        );
        const account = symbol.Account.createFromPrivateKey(privateKey,symbol.NetworkType.TEST_NET);
        let signedTx = account.sign(tx,networkGenerationHash);
        console.log(signedTx);
        new symbol.TransactionHttp(nodeAddress).announce(signedTx)
        .subscribe(function(x){
          alert("Txが発行されました!");
          console.log(x);
        },function(x){
          alert("エラーが発生しました!");
          console.error(err)
        }); 

このコードについて見ていきます。

以下のコードで、入力枠に入力したプライベートキーと.val()を変数PrivateKeyに代入したものになります。

privateKey=$('#pk').val();

以下のコードで、トランザクションを発行するコードになり、基本的にコピペでOKです。

let tx = symbol.TransferTransaction.create(
          symbol.Deadline.create(),
          symbol.Address.createFromRawAddress($('#receiver_address').val()), 
          [new symbol.Mosaic (new symbol.MosaicId('5E62990DCAC5BE8A'),symbol.UInt64.fromUint(100))],
          symbol.PlainMessage.create('Send Symbol'),
          symbol.NetworkType.TEST_NET,
          symbol.UInt64.fromUint(100000)
        );

以下のコードは、トランザクションの有効期間になります。

symbol.Deadline.create(),

この書き方で、デフォルトで設定された期間になります。


以下のコードで入力したアドレスを取得しています。

symbol.Address.createFromRawAddress($('#receiver_address').val()),

次に、以下のコードで、送るモザイクの種類とその量を決めます。

[new symbol.Mosaic (new symbol.MosaicId('5E62990DCAC5BE8A'),symbol.UInt64.fromUint(100))],

5E62990DCAC5BE8A:モザイクのID

fromUint(100):送る量。単位はμXYM。この時は100μXYMを送る量としています。

以下のコードで送るメッセージを設定します。

symbol.PlainMessage.create('Send Symbol'),

このコードでは、メッセージを「Send Symbol」としています。

 

以下のコードで、テストネット上で送るように指示したものになります。

symbol.NetworkType.TEST_NET,

 

以下のコードで、送金手数料の最大値を書いています。

symbol.UInt64.fromUint(100000)

次に、以下のコードを見ていきます。

const account = symbol.Account.createFromPrivateKey(privateKey,symbol.NetworkType.TEST_NET);
        let signedTx = account.sign(tx,networkGenerationHash);
        console.log(signedTx);
        new symbol.TransactionHttp(nodeAddress).announce(signedTx)
        .subscribe(function(x){
          alert("Txが発行されました!");
          console.log(x);
        },function(x){
          alert("エラーが発生しました!");
          console.error(err)
        }); 

このコードで、どのアカウントでサインするのかを定義します。

const account = symbol.Account.createFromPrivateKey(privateKey,symbol.NetworkType.TEST_NET);

ここでは、プライベートキーからアカウントを作ります。ここでは、引数privateKyeに入っているプライベートキーと使うSymbolのネットワークタイプ(ここではテストネット)を

引数privateKeyを変える事で、アカウントが変わります。さっき作ったトランザクションを、このアカウントでサインします。

次に、signTxという変数に対して

let signedTx = account.sign(tx,networkGenerationHash);

と書く事で、トランザクションデータとネットワークジェネレーションハッシュを使うことで、サインしたトランザクションができます。

ここで、sighedTxの中身を見てみます。

console.log(signedTx);

すると、Google Chromeのディベロッパーツールのconsoleを見ると、以下のようになっています。

payloadが、サインされたトランザクションを表します。これを作れる仕組みを考えれば、他のプログラミング言語にも移植することができます。(これがややこしいみたいです)
このpayroadは表示されていると、トランザクションを発生させたことに成功したことになります。

そして、次のコードで、ネットワークにXYMやモザイクを送金します。

new symbol.TransactionHttp(nodeAddress).announce(signedTx)
.subscribe(function(x){
alert("Txが発行されました!");
console.log(x);
},function(x){
alert("エラーが発生しました!");
console.error(err)
});

ここで、TransactionHttp(nodeAddress)で使うノードを決め、announce(signedTx)でサインしたトランザクションをネットワークにてアナウンスし、

.subscribe(function(x){
alert("Txが発行されました!");
console.log(x);
},function(x){
alert("エラーが発生しました!");
console.error(err)
});

でアナウンスした結果が画面に表示されるようになります。

※この記事は、nemlogで企画されたイベントであるしゅうさんの勉強会「しゅうさんといっしょ!」の内容の一部をまとめたものです。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Sign upLogin
2
Help us understand the problem. What are the problem?