DMMエンジニアによるブロックチェーン講座

Stellarでおれおれトークンを作る!![第3回]

トークンの応用、マルチシグ

 本稿では、ブロックチェーン、暗号資産の概念を理解されている方を対象に進めていきます。Stellarのトークンでどのような事が実現可能なのか理解を深めていっていただければと思います。

はじめに

 第2回ではJSを使いおれおれトークンの発行を行いました。今回はそのトークンでどのようなことがStellarでは可能なのか、2つ機能をピックアップし説明していきたいと思います。

注意点

2019年1月よりStellarのtestnetでの仕様が変更になりました。2月末、4月末、7月末、10月末のタイミングでデーターがリセットされます。過去に作成したアカウント情報が消えてしまっている可能性がありますので、その場合は新規に作成し直してください。

メモ機能

 Stellarでは、トランザクションに対してメモを添付することができます。メモを添付することで、トークンを受け取る相手に対してメッセージ代わりにメモを渡すことができます。テキストメモ以外にも、以下のような種類が用意されております。

MEMO_TEXTテキストメモ28byte以内のプレーンテキストを添付可能
MEMO_ID数値型のID64bit以内の数値型の値を添付可能
MEMO_HASHハッシュ32byteのハッシュデーターを添付可能
MEMO_RETURN返金用送金者が返金する際に、返金の対象となったトランザクションハッシュを、添付可能

 Stellarではこのように用途ごとに、メモを添付できる4つの種類が用意されています。テキストメモは28バイトと小さなサイズしか許容されていないため、コミュニケーションの手段としては限定的な用途になるかと思います。それ以外の種類も28バイトから64バイトとそこまで大きなサイズではありません。これらの仕様はStellarノードのディスク容量、パフォーマンスへの影響を懸念したトレードオフになります。

 それでは第2回に作成した、MyTokenクラスを拡張して、メモ機能を追加したtoken.jsを作成します。まず最初に、送付先アドレス、トランザクションの作成などクラス内部に包含されていた機能を外に切り出すことで、クラスを呼ぶ側でコントロールできるようにします。実際に修正したTokenクラスが下の内容になります。

[lib/token.js]

 次にTokenクラスを呼び出す側のプログラムとしてmy_token_memo.jsを作成します。このプログラムではメモを作成し、生成されたトランザクションに添付する処理を実装します。メモを作成するにはStellarSdk.Memoクラスを使用します。テキスト、ID、ハッシュ、返金と用途毎に4つのメソッドが用意されていますので、それらを使って実装します。

 Switch Case文で4種類のメモを切り替えるようにし、Memoオブジェクトを生成する必要性がない場合は、Memo.none()というメソッドを使います。

[my_token_memo.js]

 処理の順番を書き出すと、

  1. createTransactionメソッドで、トークンの生成、送付先アドレスの指定
  2. TransactionBulidオブジェクトが生成される
  3. TransactionBuildオブジェクトにメモを添付
  4. buildメソッドで、Transactionオブジェクトを生成
  5. sendメソッドで、Stellar Networkに送信

 下が4種類のメモを送付したStellar Explorerの画像です。

テキストタイプ
ハッシュタイプ
ID(数値)タイプ
返金用ハッシュタイプ

 トークン単体では使用用途に限界がありますが、このようにメモ機能を応用することで、トークンをメッセージとして利用したり、ユーティリティトークン、アクセストークンなど、トークンに幅をもたせることがで可能になります。

マルチシグ機能

 StellarのNative通貨であるXLMだけでなく、おれおれトークンでもマルチシグ機能を使用することができます。マルチシグを使うことで盗難防止、複数人による公平性の担保が可能になります。第2回ではconfig.jsを作成し、1つのアカウントのsecretKeyで署名を行い送付を行いました。これをマルチシグの反対の言葉でシングルシグと呼びます。

 Stellarのマルチシグは、Bitcoinのマルチシグとは異なり、マルチシグ用のアドレスというものは存在していません。Stellarではアカウントに対して、マルチシグの制約を追加するイメージになるため、マルチシグの設定を行ってからマルチシグ署名が利用できるようになります。

 ここでは「マルチシグの設定」と「マルチシグの署名」をわけて説明したいと思います。

マルチシグの設定

 実装する前に、マルチシグで使用されるアカウントの用語の定義を書きました。

  • マスターアカウント……送付元アドレス、オペレーションの主体となるアドレス
  • シグネチャアカウント…マスターアカウントがオペレーションする際に署名するためのアドレス

 これ以降、マスターアカウントとシグネチャアカウントという呼び方で説明します。

 第2回「テストネット用のアドレス作成」で説明した方法でtestnet用のアカウントをあらかじめ作成しておいてください。作成したアカウントをシグネチャアカウントとしてconfig.jsのconfigSecパラメータを作成してpublickey、secretKeyをセットします。

[config.js]

 次にマルチシグを行うMultisigクラスを作成します。Multisigクラスの役割は、マスターアカウントに対して、シグネチャアカウントを使用してマルチシグの制約を設定します。constructorでは、マスターアカウントのkeypair、シグネチャアカウントのkeypairSecにsecret keyをセットしています。

[lib/multisig.js]

 マルチシグを行う上で重要なメソッドがcreateSignatureになります。このメソッドでは、まずシグネチャアカウントを登録します。コードの例では1つのアカウントしか追加していませんが、複数でも問題ありません。weightはそのアカウントの重み付けになります。重み付けはマスターアカウントがデフォルトで1ですので、マスターアカウントと比較して重みをどちらに置くかによって値を変更してください。

 configThresholdでは、マスターアカウントの重みと、オペレーションに対する必要な重みを定義しています。3つのThresholdの内容については、下の表で確認ください。

lowTreshold
(Low)
トラストラインの設定、トランザクションの生成時に必要となる、シーケンス番号の採番
medThreshold
(Medium)
アカウントの作成、送金、トラストラインの許可設定など、low、high以外のオペレーションが対象
heighThreshold
(Heigh)
マルチシグの設定、アカウントの統合統合

 上のmultisig.jsでは、「medThreshold: 2」と定義しました、これはアカウントの作成、送金などを行うには、2のweightが必要という意味になります。

 masterアカウントの重みが1で、追加したシグネチャアカウントの重みも1なので、合計するとmedThresholdの制約をみたしているので、Mediumオペレーションの実行が可能になります。

マスターアカウントの重み1 + シグネチャアカウントの重み1 = 合計2のThresholdを実行可能

 それ以外のオペレーション(lowTreshold、 heighTreshold)は重みが1ですので、マスターアカウントのシングルシグで操作するこができます。

 ユースケースとして2of3のマルチシグにする場合は、

  • マスターアカウント   重み: 1
  • シグネチャアカウント1  重み: 1
  • シグネチャアカウント2  重み: 1
マスターアカウントの重み1 + シグネチャアカウント1 or 2 の重み1 = 合計2のThresholdを実行可能

 という設定で可能です。

 マスターアカウント以外は、部外者の人のアカウントで、非常時にはマスターアカウントだけで、オペレーションの操作を行わなければならないユースケースの場合、

  • マスターアカウント   重み: 2
  • シグネチャアカウント1  重み: 1
  • シグネチャアカウント2  重み: 1
マスターアカウントの重み2 or (シグネチャアカウント1の重み1 + シグネチャアカウント2の重み1) = 合計2のThresholdを実行可能

 という設定で可能です。

 Multisigクラスが作成できましたので、次は呼び出すプログラムをmy_token_multisig.jsを作成します。

[my_token_multisig.js]

 my_token_multisig.jsを実行することで、マスターアカウントに対してマルチシグ設定がされます。Stellar Network内のトランザクションに設定した内容が書き込まれますので、Stellar explorerで確認することができます。下の画像が、設定した、Stellar explorerのキャプチャ画像です。

 マスターアカウント、シグネチャアカウントが同じweight=1で登録されており、その下にLow、Medium、HighのThreshholdが設定されれていることが確認できます。

 実際にシングルシグの実装である、my_token_send.jsをコマンドラインから実行してみますと。以下のようなマルチシグエラー(op_bad_auth)が発生することが確認できます。

マルチシグ署名

 マルチシグの設定ができたので、マルチシグ署名を行いトークンの送付を行うmy_token_multisig_send.jsを作成します。トークンの送付機能自体は、メモ機能で作成したTokenクラスをそのまま利用します。

[my_token_multisig_send.js]

 createTransacitonメソッドを作成し、sendコマンドで送付するところまでは、シングルシグネチャのケースと同じです。違う点は、シグネチャアカウントを使ってsignメソッドで署名を行い、マルチシグ署名を行っていることです。

 処理の順番を書き出しますと、

  1. createTransactionメソッドで、トークンの生成、送付先アドレスの指定
  2. TransactionBuildオブジェクトが生成される
  3. buildメソッドでTransactionオブジェクトを生成
  4. シグネチャアカウントでマルチシグ署名
  5. sendメソッドの中でマスターアカウントのマルチシグ署名
  6. Stellar Networkに送信

 という流れになります。同一トランザクションへの署名であれば、マスタ、シグネチャアカウントの署名の順番は関係ありません。

 my_token_multisig_send.jsを実行してみたいと思います。

 問題なく送信できました。

まとめ

 第1回から第3回までStellarを用いた、おれおれトークン発行について解説させ頂きました。誌面の都合上紹介できなかった「ロック機能」、「パススルー」、「オーダーブック」など、まだまだたStellarにはデフォルトで多彩なトークン機能が用意されています。StellarのスマートコントラクトはEthereumやEOSなどのDAppsブロックチェーンのような自由度はありませんが、その分セキュリティを意識した設計になっており、他のブロックチェーンより安心して簡単にスマートコントラクトを作成できます。

 本稿をきっかけに読者の皆様がStellarに興味を持って頂けますと、幸いです。

高地 明

合同会社DMM.com CTO室 エンジニア。R&D、他事業部の支援活動を通して、暗号通貨のプロダクト開発プロジェクトに参加。好きな暗号通貨ブロックチェーンはStellar、好きなプログラミング言語はCrystal。