🎛

XRPLでSoulBound Tokenを作成しよう!

2023/02/27に公開

XRP LedgerのNFTについて

XRP Ledgerは2012年に誕生したパブリックブロックチェーンです。XRP Ledgerにスマートトランザクタ(ネイティブな機能)として搭載されているNFT(XLS-20)は2022年にメインネットで有効化されました。
このNFT機能では、次のような一般的なユースケースをカバーしており、ロイヤリティの強制力も存在します。

  • ミント
  • 売買
  • Burn
  • 代理Mint
  • 発行者によるBurn(フラグ)
  • SBT(フラグ)
  • 二次販売でのロイヤリティの強制

またスマートトランザクタとして実装されているため、データ量によってトランザクション手数料が変化することはなく、XRPLの他のトランザクション同様非常に低いトランザクション手数料で、Mintや売買が可能となっています。
一般的には0.000020XRP(≒$0.000008)程度でトランザクションを送信可能です。

SoulBound Tokenとは

SoulBound TokenとはSBTとも呼ばれており、譲渡不可であるNFTのことを指します。
SBTの譲渡不可という性質を生かして、個人の証明書などへ活用されています。

XRPLのNFTでは、転送可能フラグ(tfTransferable)がオフの場合、NFTは発行者を通じてのみ取引が可能になり、第三者同士での取引が不可能となります。

https://xrpl.org/ja/nftokenmint.html#nftokenmintフラグ

つまり、SBTでないNFTとSBTの違いはtfTransferableフラグの有無のみになります。

準備

今回はXummを使ってSBTをMintしてみましょう。
Xummをインストールされていない方はインストールしましょう。XRPLウォレットのデファクトスタンダードです。

https://xumm.app/

以下の記事を参考にアカウントの作成を行なってください。
今回はテストネットを使用するため、アカウントの有効化は不要です。

https://coinkissa.com/how-to-activate-and-use-xumm-wallet

今後メインネットでXRPLを使用する場合はアカウント有効化のため10XRPの入金が必要です。
これはXRPLにおいてアカウントがスパム的に作成されるのを防ぐための仕組みです。

テストネットアカウントを取得

以下のサイトからテストネット(Testnet)のアドレスとシークレットを取得してください。

https://xrpl.org/ja/xrp-testnet-faucet.html

次にXummにアカウントを追加します。

Xummアプリ内下部の設定→アカウント→アカウントを追加する→既存のアカウントをインポートと選択します。

image

さらに全権アクセス→シークレットキーと選択していき、先ほど取得したシークレットを入力します。

image

パブリックアドレスが取得したアドレスと一致していることを確認し、以降の処理を完了させてください。

完了後は設定したアカウントへ切り替わっています。

ネットワークをテストネットへ切り替える

次に接続先ノードをテストネットのノードに切り替えます。

Xummアプリ内下部の設定→詳細設定→ノードからテストネット欄に表示されているノードいずれかを選択します。
image

その後ホームに戻るとテストネットでのXRPの残高が表示されていることを確認してください。

これでアカウントの準備は完了です。

XummのAPIキーを取得

次のページにアクセスし、お好きな方法でアカウントを登録してください。
登録の過程でGoogle Authenticatorなどを使ったワンタイムパスワードの登録が必要です。

https://apps.xumm.dev/

アカウント登録後、Create New Applicationからテスト用のアプリケーションを登録します。

image

必要な項目を入力し、次へ進みます。
image
image

アプリが作成されました!
API KeyとAPI Secretを別の場所へ保存しておきましょう。
image

これで準備は完了です。

手順

SBTの発行

JavascriptでXummのペイロードを作成するコードを書いていきます。

以下のライブラリを使用します。

https://github.com/XRPL-Labs/XUMM-SDK

https://www.npmjs.com/package/xumm-sdk

npm i xumm-sdk

XummSdk.payload.create メソッドでXumm向けのペイロードを作成します。

APIKeyとAPISecretには先ほど取得したものを設定してください。

sbt sample
import { XummSdk } from 'xumm-sdk'

const APIKey = '********-****-****-****-************'
const APISecret = '********-****-****-****-************'

const main = async () => {
  const sdk = new XummSdk(APIKey, APISecret)
  const payload = await sdk.payload.create({
    TransactionType: 'NFTokenMint',
    NFTokenTaxon: 1,
    // Flags: 8, // 8: tfTransferableは設定しません。8を設定したら転送可能なNFTとなります。
    // 画像はサンプルです
    URI: Buffer.from('https://user-images.githubusercontent.com/69445828/220017141-5855f188-85a9-4b59-8ce5-102ead4e0cf1.png', 'utf8').toString('hex').toUpperCase()
  })
  
  console.log(payload)
}

main()

payloadの中身は以下のようになっています。

payload
{
  uuid: '5270dab3-f3f9-44fb-9f3e-1392f3c17225',
  next: {
    always: 'https://xumm.app/sign/5270dab3-f3f9-44fb-9f3e-1392f3c17225'
  },
  refs: {
    qr_png: 'https://xumm.app/sign/5270dab3-f3f9-44fb-9f3e-1392f3c17225_q.png',
    qr_matrix: 'https://xumm.app/sign/5270dab3-f3f9-44fb-9f3e-1392f3c17225_q.json',
    qr_uri_quality_opts: [ 'm', 'q', 'h' ],
    websocket_status: 'wss://xumm.app/sign/5270dab3-f3f9-44fb-9f3e-1392f3c17225'
  },
  pushed: false
}

Xummでの署名

next.alwaysのURLを開いたり、Xummアプリでqr_pngのQRコードを開いたりすることでトランザクションへの署名が行えます。
URLを一度Xummで開いたらそのURL利用できなくなります。

image

スライドして承認することでトランザクションへの署名が行えます。

image

SBTの確認

署名後、SBTを確認してみましょう。
署名したアカウントアドレスで検索してアカウントが保有するNFTを確認できます。

https://test.bithomp.com/nft-explorer

こちらが今回テストでミントしたSBTです。
https://test.bithomp.com/nft/00000000A74B88525756FBD02364E757BAD8FFCE10868C370000099A00000000

この時点ではSBTは発行者自身が保有しているため、発行者以外のアカウントへ転送ができます。

NFTの転送/売買についてはこちらの記事をどうぞ!

https://zenn.dev/tequ/articles/try-xrpl-nft

SBTかどうかの確認

NFTのIDの上位16ビットからNFTが転送不可なSBTであるかどうかを確認できます。

https://xrpl.org/ja/nftoken.html#nftoken-フラグ

上記の例の場合 00000000A74B88525756FBD02364E757BAD8FFCE10868C370000099A00000000 の上位16ビットは 0000 です。
これより、lsfBurnable, lsfOnlyXRP, lsfTransferable のいずれも設定されていないことがわかります。

xrpl.jsのparseNFTokenIDメソッドを使うことで、Flagsを含め、手数料や発行者の情報も展開可能です。

https://www.npmjs.com/package/xrpl

parseNFTokenID
const info = parseNFTokenID('00000000A74B88525756FBD02364E757BAD8FFCE10868C370000099A00000000')
console.log(info)
result
{
  NFTokenID: '00000000A74B88525756FBD02364E757BAD8FFCE10868C370000099A00000000',
  Flags: 0,
  TransferFee: 0,
  Issuer: 'rGE2L3KeL5hwfyNRB6jaHHGdKCZ8cZqMVV',
  Taxon: 1,
  Sequence: 0
}

まとめ

XRP LedgerのNFT機能ではフラグのみの変更でSBTをミントでき、コントラクトを触る必要もないため非常に簡単だといえます。
譲渡不可とする処理もプロトコル内に実装されており、セキュリティリスクも非常に低くなっています。

今回使用したコードは以下のリポジトリからも参照できます。
https://github.com/develoQ/xrpl-sample/tree/main/samples/mint-xrpl-sbt

興味を持たれた方はXRP Ledger開発者のDiscordチャンネルへ是非お越しください!
日本語チャンネルもありますので、英語ができなくても大丈夫です!
https://xrpldevs.org

Discussion