30
33

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

はじめてのブロックチェーン実践講座その2

Last updated at Posted at 2023-08-29

はじめに

本講座では、金融庁認定の暗号資産:Symbol ブロックチェーンを利用し、
プログラム知識ゼロでブロックチェーンを自由に利用、体験していただきます。

また、本講座はTaka Nobu(@nem_takanobu)様の「速習Symbolブロックチェーン」を元に作成しております。

本講座では、「はじめてのブロックチェーン実践講座その1」を実施した方向けに書かれております。まだ実施していない方は、そちらから実施してください。また、本講座では、複数トランザクションの同時送信。あなたのオリジナルトークン作成が出来るようになります。

準備するもの

・インターネット接続環境
・Google Chromeブラウザ
・PC環境
・「はじめてのブロックチェーン実践講座その1」の知識

1.複数トランザクションの同時送信

1-1.アグリゲートトランザクションとは?

はじめてのブロックチェーン実践講座その1」では、aliceからbobへの送金トランザクションを作成し、署名⇒アナウンスしました。今の皆さんの知識で、aliceからcarolへの送金も可能だと思います。ですが、100人に送信する場合に、1つ1つトランザクションを送信するのは大変ですよね。そこで活躍するのが、アグリゲートトランザクションとなります。簡単に説明すると、1つのトランザクション内に複数の送信データを格納して一括で送るトランザクションになります。

◆前回のトランザクションの流れ
1.bobへ1XYMをメッセージ付きで送るトランザクション作成
2.aliceの秘密鍵で署名
3.ノードへアナウンス⇒送金

◆今回のアグリゲートトランザクションの流れ
1.bobとcarolへ1XYMをメッセージ付きで送るトランザクション作成
2.aliceの秘密鍵で署名
3.ノードへアナウンス⇒送金

このようになります。

1-2.事前準備

Symbol利用環境の構築
alice、bob、carolのアカウントの呼び出し
※方法を忘れた際は、上記のリンク先にて実施してください。
・Symbolデスクトップウォレットの起動

1-3.アグリゲートトランザクション作成

ここでは、アグリゲートトランザクションを作成します。ここで用意するトランザクションとは、
1.送信先(bob,carol)
2.トークンとその枚数の指定(XYM1枚)
3.メッセージの有無(hello bob,hello carol)
4.ネットワークタイプ(Testnet)
こちらをbob,carolでそれぞれ先に作成し、アグリゲートトランザクションとしてまとめたものとなります。

では早速、アグリゲートトランザクション生成のコマンドを観ていきましょう。

//bobへの送金トランザクション 
innerTx1 = sym.TransferTransaction.create(
    undefined,
    bob.address, 
    [new sym.Mosaic(new sym.NamespaceId("symbol.xym"),sym.UInt64.fromUint(1000000))],
    sym.PlainMessage.create('hello bob'),
    networkType,
);
//carolへの送金トランザクション
innerTx2 = sym.TransferTransaction.create(
    undefined,
    carol.address, 
    [new sym.Mosaic(new sym.NamespaceId("symbol.xym"),sym.UInt64.fromUint(1000000))],
    sym.PlainMessage.create('hello carol'),
    networkType,
);
//上記をまとめたアグリゲートトランザクション宣言
aggregateTx = sym.AggregateTransaction.createComplete(
    sym.Deadline.create(epochAdjustment,6),
    [
//bobとcarolへの上記の送金トランザクションをそれぞれ呼び出し1つにまとめる
      innerTx1.toAggregate(alice.publicAccount), //aliceアカウントの公開鍵
      innerTx2.toAggregate(alice.publicAccount)  //aliceアカウントの公開鍵
    ],
    networkType,
    [],
    sym.UInt64.fromUint(1000000)//手数料
);

では、早速アグリゲートトランザクションをコンソール画面にコピーして貼り付けてみましょう。
Capt_51.jpg

エンターキーを押下し、以下の状態になればOKです。

Capt_52.jpg

1-4.署名

トランザクションは「誰に何をどう送るか?のセット」だとお伝えしたと思います。ですがそれだけでは、「誰が送るのか?」が足りていません。そこで、送信元のサインを秘密鍵を利用して実施いたします。以下のコマンドをご覧ください。

signedTx = alice.sign(aggregateTx,generationHash);
console.log(signedTx);

ここでは、aliceの秘密鍵を利用して、サインを行っています。前項目ではbob,carolへの送信アグリゲートトランザクションを作成したため、aliceからbob,carolへ同時送信を行うことになります。早速、コマンドをconsole画面に入力→エンターキーを押下してください。
Capt_53.jpg

1-5.アナウンス

ここまで、アグリゲートトランザクション(bobとcarolに何を何枚送るか)を作成し、そこに署名(aliceから送信)をいたしました。では、いよいよこれを Symbolブロックチェーンノードにアナウンス(送信)しましょう。以下のコマンドを入力してください。
※エンターキーは押下しないこと

await txRepo.announce(signedTx).toPromise();

Capt_60.jpg
上記の状態になればOKです。それではアナウンスをする前に、Symbolウォレットでaliceのホーム画面を表示させてください。
では、Symbolウォレットを起動したまま、console画面にてエンターキーを押下しノードへアナウンスをしてください。
Capt_60.jpg
上記と同時に、Symbolウォレットから「チャリン」と音が鳴ると思います。Symbolウォレットを確認してください。あなたのコマンド入力で、Symbolウォレットに反映されました。名称が前回と異なり、アグリゲートコンプリートと表示されています。
Capt_56.jpg
続いて、Symbolウォレットのアグリゲートコンプリートをクリックして、詳細を観てみましょう。
Capt_57.jpg
前回の講座での通常トランザクションとは異なり、アグリゲートコンプリートと表示されています。更に、トランザクション詳細として、alice⇒bob、alice⇒carolへ同時に送金されていることが分かります。

bobとcarolのアカウントを確認してみましょう。指定した「1XYM、メッセージ:hallo bob/hallo carol」がそれぞれ入金されていることが確認できます。
◆bob詳細
Capt_58.jpg
◆carol詳細
Capt_59.jpg

おめでとうございます。これであなたはブロックチェーンでのアグリゲートトランザクション送金を自身で可能となりました。複数のトランザクションを一括して送るときにとても便利な機能です。ユースケースとしては、オリジナルトークンをチケットとして作成し、購入者に一括して送信する等、様々な利用方法が考えられます。

次の章からは、あなたのオリジナルトークンを作成していきましょう。

2.オリジナルトークン作成

2-1.オリジナルトークンとは?

Symbolでは、簡単にあなただけのユニークなトークン(SymbolではMosaicと呼びます)を作成することが出来ます。例えば、いままで送金していたXYMをトークンとして分解すると以下の通りとなります。

◆XYMの詳細
・ネームスペース:Symbol
・サブネームスペース:XYM
・モザイクID:72C0212E67A08BCE(ユニークなIDとなります。)
・表示:Symbol.XYM(実際にウォレットでは以下のように表示されています)
Capt_61.jpg
本章では「Symbol.XYM」のように、あなただけのトークンを作成しましょう。今回、私は「nembear.coin」というオリジナルトークンを作成していきます。

2-2.モザイクID作成

前章で説明した、モザイクIDの部分から作成いたします。まずは、carolアカウントに300XYMを送金しましょう。(やり方を忘れた方はこちらラストから)

では早速、モザイクから作成しましょう。

//モザイクトランザクション定義1
supplyMutable = true; //供給量変更の可否(初期設定から枚数の変更が可能)
transferable = true; //第三者への譲渡可否(carol⇒alice⇒bobへの譲渡可能)
restrictable = true; //制限設定の可否(モザイク制限可能)
revokable = false; //発行者からの還収可否(carolからの還収不可)

nonce = sym.MosaicNonce.createRandom();
mosaicDefTx = sym.MosaicDefinitionTransaction.create(
    undefined, 
    nonce,
    sym.MosaicId.createFromNonce(nonce, carol.address), //モザイクID生成
    sym.MosaicFlags.create(supplyMutable, transferable, restrictable, revokable),
    0,//divisibility:可分性(1)
    sym.UInt64.fromUint(0), //duration:有効期限(0=無制限) 
    networkType
);

これで、carolのアカウントで作成されるモザイク定義1が登録されます。
console画面にて、コマンド全文をコピーして入力してください。その後、エンターキーを押下してください。
Capt_62.jpg
続いて、モザイクの枚数を定義します。100枚のモザイクを作成します。

//モザイクトランザクション定義2
mosaicChangeTx = sym.MosaicSupplyChangeTransaction.create(
    undefined,
    mosaicDefTx.mosaicId,
    sym.MosaicSupplyChangeAction.Increase,
    sym.UInt64.fromUint(100), //モザイク枚数100枚
    networkType
);

console画面にて、コマンド全文をコピーして入力してください。その後、エンターキーを押下してください。
Capt_63.jpg
これで、あなたのオリジナルトークン(モザイク)がすべてトランザクションとして定義されました。2つのトランザクションですので、第1章で実施したアグリゲートトランザクションで、署名⇒アナウンスしましょう。

//アグリゲートトランザクションを使用
aggregateTx = sym.AggregateTransaction.createComplete(
    sym.Deadline.create(epochAdjustment),
    [
      mosaicDefTx.toAggregate(carol.publicAccount),//carolの公開鍵を使用
      mosaicChangeTx.toAggregate(carol.publicAccount),//carolの公開鍵を使用
    ],
    networkType,[],
).setMaxFeeForAggregate(100, 0);

signedTx = carol.sign(aggregateTx,generationHash);//carolの秘密鍵で署名
await txRepo.announce(signedTx).toPromise();//ノードへアナウンス

console画面にて、コマンド全文をコピーして入力してください。その後、エンターキーを押下してください。
Capt_64.jpg
それでは早速、carolのアカウントをSymboウォレットで確認しましょう。以下の通り、新規のオリジナルトークン(モザイク)がアグリゲートトランザクションで作成されました。
Capt_65.jpg
続いて、アグリゲートトランザクションの中身を確認しましょう。ユニークなモザイクIDが発行されています(ここでは「0B84D717C9DA3F82」)更に設定が、指定した通りになっていることを確認してください。さらに、100枚発行されていることが確認できます。また、トークン発行には手数料として50XYMがかかることをご承知おきください。
Capt_66.jpg
おめでとうございます!これで、あなたのオリジナルトークンが作成されました。早速このトークン(モザイク)をAliceに送信してみましょう。console画面にて、コマンド全文をコピーして入力してください。その後、エンターキーを押下してください。

//モザイクIDを指定しトランザクションを作成
 tx = sym.TransferTransaction.create(
                sym.Deadline.create(epochAdjustment, 6),
                sym.Address.createFromRawAddress("あなたのaliceのアドレスを入力してください。"),
                [new sym.Mosaic(new sym.MosaicId('あなたのモザイクIDを入力してください'), sym.UInt64.fromUint(1))],//モザイクIDと枚数を指定(1枚)
                sym.PlainMessage.create('オリジナルモザイク'),
                sym.NetworkType.TEST_NET,
            ).setMaxFee(100);

signedTx = carol.sign(tx,generationHash);//carolの秘密鍵で署名
console.log(signedTx);
res = await txRepo.announce(signedTx).toPromise();//ノードへアナウンス
console.log(res);

下記のように表示されればOKです。続いてSymbolウォレットのaliceアカウントを開いてみましょう。
Capt_67.jpg
このように、あなたのオリジナルトークンの送金が完了しました。送信トランザクション内の【MosaicId】を変更すると自由に送金が出来ます。XYMも皆さんが作ったオリジナルトークンの1つということですね。
Capt_68.jpg

2-3.ネームスペース、サブネームスペース作成

前章で、オリジナルトークン(モザイクIDの発行)作成を行いました。ですが、見た目が文字列になっております。これだと、受け取った方も誰のトークンか認識するのが難しいと思います。そこで、ここでは、モザイクIDにネームスペースを紐づけたいと思います。意味合いとしては以下の通りです。
◆ネームスペース例(XYMの場合)
・ネームスペース「Symbol」を取得
 ⇒サブネームスペース「XYM」を取得
  ⇒モザイクID「72C0212E67A08BCE」をサブネームスペースに紐づける

その結果、モザイクID「72C0212E67A08BCE」を「Symbol.XYM」と認識させることが出来ます。今回の講座では、私は作成したモザイクIDを「nembear.coin」として認識させたいと思います。皆さんもオリジナルの名称を考えてください

では早速、carolのアカウントで、ネームスペース、サブネームスペースを取得しましょう。まずは、ネームスペースをレンタルします。console画面にて、コマンド全文をコピーして入力後に指定通り編集してください。その後、エンターキーを押下してください。
※注意:ネームスペースはユニークな文字列(英数字)のみ有効となります。既に誰かが取得しているネームスペースはレンタルすることが出来ません。

tx = sym.NamespaceRegistrationTransaction.createRootNamespace(
    sym.Deadline.create(epochAdjustment),
    "あなたがレンタルしたいネームスペース名を入力してください。",
    sym.UInt64.fromUint(86400),
    networkType
).setMaxFee(100);
signedTx = carol.sign(tx,generationHash);//carolの秘密鍵で署名
await txRepo.announce(signedTx).toPromise();

下記の通り、表示されればOKです。(私は「nembear」という名前のネームスペースを入力しています。)
Capt_71.jpg
早速、carolのアカウントをSymbolウォレットで確認してみましょう。予定通り、ネームスペースの登録がトランザクションとして表示されています。
Capt_72.jpg
さらに詳細を観てみましょう。スペース名としてあなたが指定したネームスペース名、レンタル期間が30日(延長可能です)、そしてレンタル料(レンタル期間によって金額が変更されます)が表示されています。
Capt_73.jpg
続いて、carolのアカウントで、サブネームスペースをレンタルします。console画面にて、コマンド全文をコピーして入力してください。その後、エンターキーを押下してください。

subNamespaceTx = sym.NamespaceRegistrationTransaction.createSubNamespace(
    sym.Deadline.create(epochAdjustment),
    "coin",  //あなたが作成したいサブネームスペースを入力してください。
    "nembear", //先ほど作成したネームスペースを入力してください。
    networkType,
).setMaxFee(100);
signedTx = carol.sign(subNamespaceTx,generationHash);
await txRepo.announce(signedTx).toPromise();

下記の通り、表示されればOKです。
Capt_74.jpg
早速、carolのアカウントをSymbolウォレットで確認してみましょう。予定通り、ネームスペースの登録がトランザクションとして表示されています。
Capt_75.jpg
さらに詳細を観てみましょう。サブスペース名としてあなたが指定したサブネームスペース名、紐づけたネームスペース名、そしてレンタル料が表示されています。
Capt_76.jpg
これで、ネームスペース、サブネームスペースを取得することが出来ました。次章では、このネームスペースをアカウントに紐づけましょう。

2-4.オリジナルトークン作成

前章で、ネームスペースの作成を行いました。ここでは、それをアカウント、モザイクIDと紐づけて、オリジナルのトークンを作成しましょう。まずはアカウントへのリンクを実施いたします。
console画面にて、コマンド全文をコピーして入力してください。その後、エンターキーを押下してください。

namespaceId = new sym.NamespaceId("あなたのネームスペース入力してください");
address = sym.Address.createFromRawAddress("carolのアドレスを入力してください");
tx = sym.AliasTransaction.createForAddress(
    sym.Deadline.create(epochAdjustment),
    sym.AliasAction.Link,
    namespaceId,
    address,
    networkType
).setMaxFee(100);
signedTx = carol.sign(tx,generationHash);
await txRepo.announce(signedTx).toPromise();

下記の通り、表示されればOKです。
Capt_77.jpg
早速、carolのアカウントをSymbolウォレットで確認してみましょう。予定通り、アドレスエイリヤスの登録がトランザクションとして表示されています。
Capt_78.jpg
さらに詳細を観てみましょう。ネームスペースID、LINK、carolアドレスが設定されているのが確認できます。
Capt_79.jpg
さらに、ネームスペースを確認すると、ネームスペースがcarolのアドレスに紐づいていることが確認できます。
Capt_80.jpg
それではいよいよ、モザイクIDと紐づけて、オリジナルトークンを作成しましょう。
console画面にて、コマンド全文をコピーして入力してください。その後、エンターキーを押下してください。

namespaceId = new sym.NamespaceId("あなたのネームスペース、サブネームスペースを入力してください");//例:nembear.coin
mosaicId = new sym.MosaicId("あなたのモザイクIDを入力してください");
tx = sym.AliasTransaction.createForMosaic(
    sym.Deadline.create(epochAdjustment),
    sym.AliasAction.Link,
    namespaceId,
    mosaicId,
    networkType
).setMaxFee(100);
signedTx = carol.sign(tx,generationHash);
await txRepo.announce(signedTx).toPromise();

下記の通り、表示されればOKです。
Capt_81.jpg
早速、carolのアカウントをSymbolウォレットで確認してみましょう。予定通り、モザイクエイリヤスの登録がトランザクションとして表示されています。更に、アセット欄のモザイク名称が、ネームスペース.サブネームスペースとして表示されています。
Capt_82.jpg
さらに詳細を観てみましょう。ネームスペースID、LINK、モザイクIDが設定されているのが確認できます。
Capt_83.jpg
さらに、ネームスペースを確認すると、ネームスペースがモザイクIDに紐づいていることが確認できます。
Capt_84.jpg
続いて、モザイクを見てみましょう。モザイクIDに指定した名前(ネームスペース、サブネームスペース)が付きました。これで、あなたのオリジナルトークンの完成です。
Capt_85.jpg
aliceのアカウントにも、モザイクIDだったトークンが、名前入り変更されています。
Capt_87.jpg

3.回収可能トークンの発行と回収

3-1.回収可能トークンとは??

前章までで作成したトークンは、1度送ってしまうと送信先アカウントが送り返さない限り元に戻すことは出来ません。ですが、回収可能トークンは、自身で送ったトークンを回収することが可能です
ユースケース
・サブスク:あなたの作ったトークンの所持者のみ閲覧出来るサイトや記事を作成し、月々の支払いがない場合、トークンを回収することでサブスクリプションが成立。
・チケット:あなたの作ったトークンの所持者のみ参加できるイベントを開催し、イベント終了後回収することで、チケットとして成立。
特記事項
・手数料が作成者払い:Symbolブロックチェーンでは送信時に手数料がかかります。その結果、XYMを持っていない方は受信は出来ますが、送信が出来ません。ですが、回収可能トークンは回収手数料がトークン作成者が持つので、どんなユーザーにも送ることが出来ます。

3-2.回収トークンの作成

早速作成していきましょう。前章とやり方は同じです。モザイクトランザクション定義1のrevokableのみtrueに設定してください。そこからは、前章と同様の操作となります。(便宜上、carolのアカウントで作成してください)

//モザイクトランザクション定義1
supplyMutable = true; //供給量変更の可否(初期設定から枚数の変更が可能)
transferable = false; //第三者への譲渡可否(carol⇒alice⇒bobへの譲渡可能)
restrictable = true; //制限設定の可否(モザイク制限不可)
revokable = true; //発行者からの還収可否(carolからの還収不可)

nonce = sym.MosaicNonce.createRandom();
mosaicDefTx = sym.MosaicDefinitionTransaction.create(
    undefined, 
    nonce,
    sym.MosaicId.createFromNonce(nonce, carol.address), //モザイクID生成
    sym.MosaicFlags.create(supplyMutable, transferable, restrictable, revokable),
    0,//divisibility:可分性(1)
    sym.UInt64.fromUint(0), //duration:有効期限(0=無制限) 
    networkType
);

3-3.回収トークンの回収方法

回収可能トークンを回収するトランザクションを説明いたします。準備として、回収可能トークンをbobに送信してください。
Capt_88.jpg
回収トランザクションは以下の通りとなります。入力後にエンターキーを押下してください。(エンターキーを押下後に自動回収される為、bobのアカウントを開いておきましょう)

 revTx = sym.MosaicSupplyRevocationTransaction.create(
                sym.Deadline.create(epochAdjustment),
                sym.Address.createFromRawAddress("bobのアドレスを入力"),
                new sym.Mosaic(new sym.MosaicId("回収可能トークンのモザイクIDを入力"), sym.UInt64.fromUint(1)),
                sym.NetworkType.TEST_NET,
                sym.UInt64.fromUint(100000)
            );
            
            signedTx = carol.sign(revTx, generationHash);
            new sym.TransactionHttp(NODE)
                .announce(signedTx)
                .subscribe((x) => console.log(x), (err) => console.error(err));

未承認の場合はまだ、回収可能トークンが存在しています。
Capt_89.jpg
承認済みになると、回収可能トークンが消え、carolのアカウントへ戻ります。
Capt_90.jpg

おめでとうございます。これで回収可能トークンまで作成することが出来るようになりました。「はじめてのブロックチェーン実践講座その1」に比べ、Symbolブロックチェーンの見識がさらに高まったことと思います。Symbolブロックチェーンを利用してのアイデアや想像も広がったのではないでしょうか?そこで、皆さんに是非実施して欲しいことがあります。「速習Symbolブロックチェーン」を是非実施してください。今のあなたの知識ではすんなり、そして深くSymbolブロックチェーンを学ぶことが出来ます。ここまでお付き合いいただきありがとうございました。感謝申し上げます。

30
33
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
30
33

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?