레슨1
NFT를 발행하고 소각하기
XRP Ledger에서 NFT를 발행하고 소각하세요.
이 강의에서는 다음을 배웁니다.
- 대체 불가능한 토큰 (NFT)를 발행합니다 .
- 계정에 있는 기존 NFT 목록을 가져옵니다.
- NFT를 삭제(burn) 합니다.
코드를 편집해 보세요: mint-and-burn-nfts.js
아래의 대화형 코드 예제는 모든 XRP Ledger 네트워크( 테스트넷 , 개발넷 또는 메인넷) 와 함께 사용할 수 있습니다. 빌드할 때, 다른 XRP Ledger 네트워크나 추가 XRP Ledger 네트워크를 선택할 수 있도록 코드를 수정할 수 있습니다.
계정 받기
- 코드 샌드박스를 엽니다. 새 창에서 “Edit on Codepen”을 클릭하는 것을 권장합니다.
- 테스트 계정을 받습니다.
- 기존 NFT-Devnet 계정 시드가 있는 경우:
- Seed 필드에 계정 시드를 붙여 넣습니다.
- “Get Accounts from Seeds”를 클릭합니다.
- 기존 NFT-Devnet 계정이 없는 경우:
- “Get New Standby Account”를 클릭합니다.
- “Get New Operational Account”를 클릭합니다.
- 기존 NFT-Devnet 계정 시드가 있는 경우:
NFToken 발행
대체 불가능 토큰을 발행하기 위해:
- “Flag” 필드를 설정합니다. 테스트 목적으로 값을 8로 설정하는 것을 추천합니다. 이렇게 하면 tsTransferable 플래그가 설정되어 NFToken 객체를 다른 계정으로 전송할 수 있습니다. 그렇지 않으면 NFToken 객체를 발급 계정으로만 다시 전송할 수 있습니다. NFToken을 발행하는 데 사용할 수 있는 모든 플래그에 대한 정보는 NFToken Mint를 참조하세요.
- “Token URL”을 입력합니다. 이는 NFToken 개체와 관련된 데이터 또는 메타데이터를 가리키는 URI입니다. 고유한 샘플 URI가 없는 경우 제공된 샘플 URI를 사용할 수 있습니다.
- “Transfer Fee” 입력합니다. 이는 NFToken의 미래 판매 수익의 백분율로, 원래 제작자에게 반환됩니다. 이는 0-50000을 포함하는 값으로, 0.001% 단위로 0.000%에서 50.000% 사이의 전송률을 허용합니다. NFToken을 전송할 수 있도록 “Flags” 필드를 설정하지 않은 경우 이 필드를 0으로 설정합니다.
- “Mint Token”을 클릭합니다.
토큰 얻기
“Get Tokens”를 클릭하면 해당 계정이 소유한 NFT 토큰 목록을 가져옵니다.
토큰 소각
NFToken의 현재 소유자는 언제든지 NFToken 객체를 파기(burn) 할 수 있습니다.
NFToken을 영구적으로 파기하기 위해:
- “Token ID” 를 입력합니다.
- “Burn Token” 을 클릭합니다.
JavaScript 코드 연습: ripplex3-mint-nfts.js
mintToken()
XRPL에 연결하고 계정 지갑을 가져옵니다.
트랜잭션을 정의합니다.
hex URI를 convertStringToHex 유틸리티를 사용하여 문자열로 변환합니다.
NFToken을 제3자에게 양도 가능하게 하려면 Flags 필드를 8로 설정합니다.
Transfer Fee는 0에서 50000까지의 값으로, 0.000%에서 50.000%까지의 로열티를 0.001 단위로 설정하는 데 사용됩니다.
TokenTaxon은 필수 값입니다. 발행자가 정의한 임의의 값입니다. 필드에 사용할 용도가 없으면 0으로 설정할 수 있습니다.
트랜잭션을 전송하고 응답을 기다립니다.
계정이 소유한 NFT 목록을 요청합니다.
결과를 보고합니다.
XRPL과 연결을 끊습니다.
// *******************************************************
// ********************** 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()
XRPL에 연결하고 계정 지갑을 가져옵니다.
계정이 소유한 NFT 목록을 요청합니다.
결과를 보고합니다.
XRPL과 연결을 끊습니다.
// *******************************************************
// ******************* 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()
XRPL에 연결하고 계정 지갑을 가져옵니다.
트랜잭션을 정의합니다.
트랜잭션을 제출하고 결과를 기다립니다.
클라이언트가 소유한 NFTokens 목록을 요청합니다.
결과를 보고합니다.
XRPL과 연결을 끊습니다.
// *******************************************************
// ********************* 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()
상호 트랜잭션 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>