arrow-left Course Hub
Lesson 4: NFTのミントとバーン
完了目安時間:

25分

難易度:

Intermediate

重要なポイント:

XRP LedgerでNFTをミントおよびバーンする方法を学びます。レッスン内のコードサンドボックスを使用して、XRPL.jsライブラリのコードを試してみましょう。

Lesson 4

NFTのミントとバーン

XRP LedgerでのNFTのミントとバーン

このレッスンでは、以下の方法を説明します。:

  1. 新しい非代替性トークン(NFT)の発行
  2. アカウントに存在するNFTのリストの取得
  3. NFTを削除(バーン)します。

コードを編集してみる:mint-and-burn-nfts.js

以下のインタラクティブなコード例は、Testnet、Devnet、Mainnetなど、あらゆるXRP Ledgerネットワークで使用できます。独自に構築する際は、コードを更新して、異なるまたは追加のXRP Ledgerネットワークを選択できます。

 

アカウントの取得

  1. 上記のcodesandboxを開いてください。新しいウィンドウで「Edit on Codepen」をクリックすることをお勧めします(右上にあるリンク)
  2. テストアカウントの取得
    1. 既存のNFT-Devnetアカウントのシードを持っている場合
      1. アカウントのシードをシードフィールドに貼り付ける
      2. シードからアカウントを取得をクリック
    2. 既存のNFT-Devnetアカウントがない場合
      1. 新規スタンバイアカウントを取得をクリック
      2. 新規運用アカウントを取得をクリック

NFTokenのミント

非代替性トークンオブジェクトのミント

  1. Flagsフィールドを設定します。テスト目的では、値を8に設定することをお勧めします。これによりtfTransferableフラグが設定され、NFTokenオブジェクトを別のアカウントに転送できるようになります。そうでない場合、NFTokenオブジェクトは発行アカウントにのみ転送できます。NFTokenの作成に使用できるすべてのフラグについて
  2. トークンURLを入力してください。これは、NFTokenオブジェクトに関連付けられたデータまたはメタデータを指すURIです。URIがない場合は、提供されているサンプルURIを使用できます。
  3. 譲渡手数料を入力します。これは、NFTokenの将来の販売による収益のうち、元の発行者に還元される割合です。この値は0〜50000(両端を含む)で、0.001%刻みで0.000%〜50.000%の譲渡レートを設定できます。Flagsフィールドを設定してNFTokenの譲渡を許可しない場合は、このフィールドを0に設定してください。
  4. トークンのミントをクリック

トークンの取得

トークンの取得をクリックすると、アカウントが所有するNFTokenのリストが表示されます。

トークンのバーン

NFTokenの現在の所有者は、常にNFTokenオブジェクトを破棄(またはバーン)できます。

NFTokenを完全に破棄するには

  1. トークンIDを入力
  2. トークンをバーンをクリック

JavaScriptコードのウォークスルー:ripplex3-mint-nfts.js

mintToken()

レジャーに接続し、アカウントのウォレットを取得します。
トランザクションを定義します。
convertStringToHex ユーティリティを使って、16 進 URI を文字列に変換します。
NFToken を第三者に譲渡可能にしたい場合は、Flags フィールドを 8 に設定します。
Transfer Fee は 0 から 50000 の値で、ロイヤリティを 0.000% から 50.000% まで 0.001% 単位で設定するために使用されます。
TokenTaxon は必須の値です。発行者が任意に定義する値で、特に用途がなければ 0 に設定できます。
トランザクションを送信し、レスポンスが返るまで待ちます。
アカウントが所有する NFT のリストを取得します。
結果を表示します。
レジャーから切断します。
// *******************************************************
// ********************** Mint Token *********************
// *******************************************************
      
async function mintToken() {
  results = 'Connecting to ' + getNet() + '....'
  standbyResultField.value = results
  let net = getNet()
  const standby_wallet = xrpl.Wallet.fromSeed(standbySeedField.value)
  const client = new xrpl.Client(net)
  await client.connect()
  results += 'nConnected. Minting NFToken.'
  standbyResultField.value = results
      
  // Note that you must convert the token URL to a hexadecimal 
  // value for this transaction.
  // ------------------------------------------------------------------------
  const transactionBlob = {
    "TransactionType": "NFTokenMint",
    "Account": standby_wallet.classicAddress,
    "URI": xrpl.convertStringToHex(standbyTokenUrlField.value),

    "Flags": parseInt(standbyFlagsField.value),

    "TransferFee": parseInt(standbyTransferFeeField.value),

    "NFTokenTaxon": 0 //Required, but if you have no use for it, set to zero.
  }

  // ----------------------------------------------------- Submit signed blob 
  const tx = await client.submitAndWait(transactionBlob, { wallet: standby_wallet} )
  const nfts = await client.request({
    method: "account_nfts",
    account: standby_wallet.classicAddress  
  })
        
  // ------------------------------------------------------- Report results
  results += 'nnTransaction result: '+ tx.result.meta.TransactionResult
  results += 'nnnfts: ' + JSON.stringify(nfts, null, 2)
  standbyBalanceField.value = 
    (await client.getXrpBalance(standby_wallet.address))
  standbyResultField.value = results    
  client.disconnect()
} //End of mintToken()

getTokens()

レジャーに接続し、アカウントのウォレットを取得します。
アカウントが所有する NFT のリストを取得します。
結果を表示します。
レジャーから切断します。
// *******************************************************
// ******************* Get Tokens ************************
// *******************************************************
      
async function getTokens() {
  const standby_wallet = xrpl.Wallet.fromSeed(standbySeedField.value)
  let net = getNet()
  const client = new xrpl.Client(net)
  results = 'Connecting to ' + net + '...'
  standbyResultField.value = results
  await client.connect()
  results += 'nConnected. Getting NFTokens...'
  standbyResultField.value = results
  const nfts = await client.request({
    method: "account_nfts",
    account: standby_wallet.classicAddress  
  })
  results += 'nNFTs:n ' + JSON.stringify(nfts,null,2)
  standbyResultField.value = results
  client.disconnect()
} //End of getTokens()

burnToken()

レジャーに接続し、アカウントのウォレットを取得します。
トランザクションを定義します。
トランザクションを送信し、結果が返るまで待ちます。
クライアントが所有する NFToken のリストを取得します。
結果を表示します。
レジャーから切断します。
// *******************************************************
// ********************* Burn Token **********************
// *******************************************************
      
async function burnToken() {
  const standby_wallet = xrpl.Wallet.fromSeed(standbySeedField.value)
  let net = getNet()
  const client = new xrpl.Client(net)
  results = 'Connecting to ' + net + '...'
  standbyResultField.value = results
  await client.connect()
  results += 'nConnected. Burning NFToken...'
  standbyResultField.value = results

  // ------------------------------------------------------- Prepare transaction
  const transactionBlob = {
    "TransactionType": "NFTokenBurn",
    "Account": standby_wallet.classicAddress,
    "NFTokenID": standbyTokenIdField.value
  }

  //---------------------------------- Submit transaction and wait for the results
  const tx = await client.submitAndWait(transactionBlob,{wallet: standby_wallet})
  const nfts = await client.request({
    method: "account_nfts",
    account: standby_wallet.classicAddress  
  })
  results += 'nTransaction result: '+ tx.result.meta.TransactionResult
  results += 'nBalance changes: ' +
  JSON.stringify(xrpl.getBalanceChanges(tx.result.meta), null, 2)
  standbyResultField.value = results
  standbyBalanceField.value = 
    (await client.getXrpBalance(standby_wallet.address))
  results += 'nNFTs: n' + JSON.stringify(nfts,null,2)
  standbyResultField.value = results
  client.disconnect()
}// End of burnToken()

Reciprocal transactions oPmintToken(), oPgetTokens() and oPburnToken()

// **********************************************************************
// ****** Reciprocal Transactions ***************************************
// **********************************************************************
   
// *******************************************************
// ************** Operational Mint Token *****************
// *******************************************************
      
async function oPmintToken() {
  results = 'Connecting to ' + getNet() + '....'
  operationalResultField.value = results
  let net = getNet()
  const operational_wallet = xrpl.Wallet.fromSeed(operationalSeedField.value)
  const client = new xrpl.Client(net)
  await client.connect()
  results += 'nConnected. Minting NFToken.'
  operationalResultField.value = results

  // Note that you must convert the token URL to a hexadecimal 
  // value for this transaction.
  // ------------------------------------------------------------------------
  const transactionBlob = {
    "TransactionType": 'NFTokenMint',
    "Account": operational_wallet.classicAddress,
    "URI": xrpl.convertStringToHex(operationalTokenUrlField.value),
    "Flags": parseInt(operationalFlagsField.value),
    "TransferFee": parseInt(operationalTransferFeeField.value),
    "NFTokenTaxon": 0 //Required, but if you have no use for it, set to zero.
  }
      
  // ----------------------------------------------------- Submit signed blob 
  const tx = await client.submitAndWait(transactionBlob, { wallet: operational_wallet} )
  const nfts = await client.request({
    method: "account_nfts",
    account: operational_wallet.classicAddress  
  })
        
  // ------------------------------------------------------- Report results
  results += 'nnTransaction result: '+ tx.result.meta.TransactionResult
  results += 'nnnfts: ' + JSON.stringify(nfts, null, 2)
  operationalBalanceField.value = 
    (await client.getXrpBalance(operational_wallet.address))
  operationalResultField.value = results    

  client.disconnect()
} //End of oPmintToken
      
// *******************************************************
// ************** Operational Get Tokens *****************
// *******************************************************

async function oPgetTokens() {
  const operational_wallet = xrpl.Wallet.fromSeed(operationalSeedField.value)
  let net = getNet()
  const client = new xrpl.Client(net)
  results = 'Connecting to ' + getNet() + '...'
 operationalResultField.value = results
 await client.connect()
  results += 'nConnected. Getting NFTokens...'
  operationalResultField.value = results
  const nfts = await client.request({
    method: "account_nfts",
    account: operational_wallet.classicAddress  
  })
  results += 'nNFTs:n ' + JSON.stringify(nfts,null,2)
  operationalResultField.value = results
  client.disconnect()
} //End of oPgetTokens
      
// *******************************************************
// ************* Operational Burn Token ******************
// *******************************************************
      
async function oPburnToken() {
  const operational_wallet = xrpl.Wallet.fromSeed(operationalSeedField.value)
  let net = getNet()
  const client = new xrpl.Client(net)
  results = 'Connecting to ' + getNet() + '...'
  operationalResultField.value = results
  await client.connect()
  results += 'nConnected. Burning NFToken...'
  operationalResultField.value = results
      
  // ------------------------------------------------------- Prepare transaction
  const transactionBlob = {
    "TransactionType": "NFTokenBurn",
    "Account": operational_wallet.classicAddress,
    "NFTokenID": operationalTokenIdField.value
  }
      
  //-------------------------------------------------------- Submit signed blob
  const tx = await client.submitAndWait(transactionBlob,{wallet: operational_wallet})
  const nfts = await client.request({
    method: "account_nfts",
    account: operational_wallet.classicAddress  
  })
  results += 'nTransaction result: '+ tx.result.meta.TransactionResult
  results += 'nBalance changes: ' +
    JSON.stringify(xrpl.getBalanceChanges(tx.result.meta), null, 2)
  operationalResultField.value = results
  operationalBalanceField.value = 
    (await client.getXrpBalance(operational_wallet.address))
  operationalBalanceField.value = 
    (await client.getXrpBalance(operational_wallet.address))
  results += 'nNFTs: n' + JSON.stringify(nfts,null,2)
  operationalResultField.value = results
  client.disconnect()
}
// End of oPburnToken()

HTMLフォームのプレビュー: 3.mint-nfts.html

以下に示すフォームにおいて、**太字**で示された箇所が、新しい機能をサポートするために変更された点です

<html>
  <head>
    <title>Token Test Harness</title>
    <link href='https://fonts.googleapis.com/css?family=Work Sans' rel='stylesheet'>
    <style>
       body{font-family: "Work Sans", sans-serif;padding: 20px;background: #fafafa;}
       h1{font-weight: bold;}
       input, button {padding: 6px;margin-bottom: 8px;}
       button{font-weight: bold;font-family: "Work Sans", sans-serif;}
       td{vertical-align: top;padding-right:10px;}
    </style>
    <script src='https://unpkg.com/xrpl@2.2.3'></script>
    <script>
      if (typeof module !== "undefined") {
        const xrpl = require('xrpl')
      }
    </script>
  </head>
  
<!-- ************************************************************** -->
<!-- ********************** The Form ****************************** -->
<!-- ************************************************************** -->

  <body>
    <h1>Token Test Harness</h1>
    <form id="theForm">
      Choose your ledger instance:  
      <input type="radio" id="tn" name="server" value="wss://s.altnet.rippletest.net:51233" >
      <label for="testnet">Testnet</label>
      
      <input type="radio" id="dn" name="server" value="wss://s.devnet.rippletest.net:51233" checked>
      <label for="devnet">Devnet</label>
      <br/><br/>
      <button type="button" onClick="getAccountsFromSeeds()">Get Accounts From Seeds</button>
      <br/>
      <textarea id="seeds" cols="40" rows= "2"></textarea>
      <br/><br/>
      <table>
        <tr valign="top">
          <td>
            <button type="button" onClick="getAccount('standby')">Get New Standby Account</button>
            <table>
              <tr valign="top">
                <td align="left">
                  Standby Account<br/> <input type="text" id="standbyAccountField" size="30" />
                </td>
                <td></td>
              </tr>
              <tr>
                <td align="left">
                  Public Key<br/>
                  <input type="text" id="standbyPubKeyField" size="30"></input>                                                 </td>
                <td align="left">
                  Private Key<br/>
                  <input type="text" id="standbyPrivKeyField" size="30"></input>
                </td>
              </tr>
              <tr>
                <td align="left">
                  Seed <br/>
                  <input type="text" id="standbySeedField" size="30"></input>
                  <br>
                </td>
                <td align="left">
                  XRP Balance <br/>
                  <input type="text" id="standbyBalanceField" size="30"></input>
                </td>
            </tr>
            <tr>
                <td align="left">
                  Amount<br/>
                  <input type="text" id="standbyAmountField" size="30"></input>
                </td>
                <td align="left">
                  Destination Account <br/>
                <input type="text" id="standbyDestinationField" size="30"></input>
                </td>
              </tr>
              <tr valign="top">
                <td><button type="button" onClick="configureAccount('standby',document.querySelector('#standbyDefault').checked)">Configure Account</button><br/>
                  <input type="checkbox" id="standbyDefault" checked="true"/>
                  <label for="standbyDefault">Allow Rippling</label>
                </td>

                <td>
                  Currency<br/>
                  <input type="text" id="standbyCurrencyField" size="30" value="USD"></input>
                </td>
              </tr>
              <tr>
                <td colspan=2>NFToken URL<br/>
                  <input type="text" id="standbyTokenUrlField"
                  value = "ipfs://bafybeigdyrzt5sfp7udm7hu76uh7y26nf4dfuylqabf3oclgtqy55fbzdi" size="70"/>
                </td>
              </tr>
              <tr>
                <td colspan=2>Flags<br/>
                  <input type="text" id="standbyFlagsField" value="1" size="10"/></td>
              </tr>
              <tr>
                <td colspan=2>NFToken ID<br/>
                  <input type="text" id="standbyTokenIdField" value="" size="70"/></td>
              </tr>
              <tr>
                <td colspan=2>Transfer Fee<br/>
                  <input type="text" id="standbyTransferFeeField" value="" size="70"/></td>
              </tr>
              <tr>
                <td colspan=2>
                  <p align="right">
                    <button type="button" onClick="sendXRP()">Send XRP ↓</button>
                    <button type="button" onClick="createTrustline()">Create TrustLine</button>
                    <button type="button" onClick="sendCurrency()">Send Currency</button>
                    <button type="button" onClick="getBalances()">Get Balances</button>
                    <br/>
                    <button type="button" onClick="mintToken()">Mint NFToken</button>
                    <button type="button" onClick="getTokens()">Get NFTokens</button>
                    <button type="button" onClick="burnToken()">Burn NFToken</button>
                  </p>
                </td>
              </tr>
            </table>
          </td>
          <td valign="top">
            <textarea id="standbyResultField" cols="60" rows="20" ></textarea>
          </td>
        </tr>
      </table>
      <br/><br/>
      <table>
        <tr valign="top">
          <td>
            <button type="button" onClick="getAccount('operational')">Get New Operational Account</button>
            <table>
              <tr valign="top">
                <td align="left">
                  Operational Account<br/> <input type="text" id="operationalAccountField" size="30" />
                </td>
                <td></td>
              </tr>
              <tr>
                <td align="left">Public Key<br/>
                  <input type="text" id="operationalPubKeyField" size="30" />                                                 </td>
                <td align="left">
                  Private Key<br/>
                  <input type="text" id="operationalPrivKeyField" size="30"></input>
                </td>
              </tr>
              <tr>
                <td align="left">
                  Seed <br/>
                  <input type="text" id="operationalSeedField" size="30"></input>
                  <br>
                </td>
                <td align="left">
                  XRP Balance <br/>
                  <input type="text" id="operationalBalanceField" size="30" />
                </td>
            </tr>
            <tr>
                <td align="left">
                  Amount<br/>
                  <input type="text" id="operationalAmountField" size="30" />
                </td>
                <td align="left">
                  Destination Account <br/>
                <input type="text" id="operationalDestinationField" size="30" />
                </td>
              </tr>
              <tr valign="top">
                <td><button type="button" onClick="configureAccount('operational',document.querySelector('#operationalDefault').checked)">Configure Account</button><br/>
                  <input type="checkbox" id="operatoinalDefault" checked="true"/>
                  <label for="operationalDefault">Allow Rippling</label>
                </td>

                <td>
                  Currency<br/>
                  <input type="text" id="operationalCurrencyField" size="30" value="USD"></input>
                </td>
              </tr>
                            <tr>
                <td colspan=2>NFToken URL<br/>
                  <input type="text" id="operationalTokenUrlField"
                  value = "ipfs://bafybeigdyrzt5sfp7udm7hu76uh7y26nf4dfuylqabf3oclgtqy55fbzdi" size="70"/>
                </td>
              </tr>
              <tr>
                <td colspan=2>Flags<br/>
                  <input type="text" id="operationalFlagsField" value="1" size="10"/></td>
              </tr>
              <tr>
                <td colspan=2>NFToken ID<br/>
                  <input type="text" id="operationalTokenIdField" value="" size="70"/></td>
              </tr>
              <tr>
                <td colspan=2>Transfer Fee<br/>
                  <input type="text" id="operationalTransferFeeField" value="" size="70"/></td>
              </tr>
              <tr>
                <td colspan=2>
                  <p align="right">
                    <button type="button" onClick="oPsendXRP()">Send XRP ↑</button>
                    <button type="button" onClick="oPcreateTrustline()">Create TrustLine</button>
                    <button type="button" onClick="oPsendCurrency()">Send Currency</button>
                    <button type="button" onClick="getBalances()">Get Balances</button>
                    <br/>
                    <button type="button" onClick="oPmintToken()">Mint NFToken</button>
                    <button type="button" onClick="oPgetTokens()">Get NFTokens</button>
                    <button type="button" onClick="oPburnToken()">Burn NFToken</button>
                  </p>
                </td>
              </tr>
            </table>
          </td>
          <td>
            <textarea id="operationalResultField" cols="60" rows="20" ></textarea>
          </td>
        </tr>
      </table>
    </form>
  </body>
  <script src='ripplex1-send-xrp.js' async></script>
  <script src='ripplex2-send-currency.js' async></script>
  <script src='ripplex3-mint-nfts.js' async></script>
</html>

追加の資料

レッスン終了

XRP LedgerでのNFTのミントとバーンについて学んだので、クイズで知識を試してみましょう。

Welcome to your Mint and burn NFTs (JP)

NFTokenTaxon IDは何に使用されますか?