JavaScript를 이용한 NFTs 발행 및 소각(Mint and Burn NFTs Using JavaScript)
Last updated
Last updated
이 예제는 다음을 보여줍니다:
새로운 Non-fungible Tokens (NFTs) 발행하기.
기존 NFTs의 목록을 얻는 방법.
NFT를 삭제(소각)하는 방법.
Quickstart Samples 아카이브를 다운로드하여 각 샘플을 브라우저에서 시도해볼 수 있습니다.
브라우저에서 3.mint-nfts.html
을 엽니다.
테스트 계정을 가져옵니다.
계정 seed가 있는 경우
Seeds 필드에 계정 seed를 붙여넣습니다.
Get Accounts from Seeds를 클릭합니다
계정 seed가 없는 경우
Get New Standby Account를 클릭합니다.
Get New Operational Account를 클릭합니다.
non-fungible token 객체를 발행하려면:
Flags 필드를 설정합니다. 테스트 목적으로는 이 값을 8로 설정하는 것을 권장합니다. 이는 tsTransferable 플래그를 설정하며, 이는 NFT 객체를 다른 계정으로 전송할 수 있음을 의미합니다. 그렇지 않으면, NFT 객체는 발행 계정으로만 전송할 수 있습니다. NFT 발행에 사용할 수 있는 모든 플래그에 대한 정보는 NFToken Mint를 참조하십시오.
Token URL을 입력합니다. 이는 NFT 객체와 연결된 데이터 또는 메타데이터를 가리키는 URI입니다. 자신의 URI가 없다면 제공된 샘플 URI를 사용할 수 있습니다.
Transfer Fee를 입력합니다. 이는 NFT의 향후 판매 수익의 일정 비율이 원래의 창작자에게 반환될 것임을 의미합니다. 이는 0-50000 사이의 값으로, 전송 비율을 0.000%에서 50.000%까지 0.001%의 증분으로 허용합니다. NFT가 전송 가능하도록 Flags 필드를 설정하지 않는다면, 이 필드를 0으로 설정합니다.
Mint NFT를 클릭합니다.
Get NFTs를 클릭하여 계정이 소유한 NFTs의 목록을 얻습니다.
NFT의 현재 소유자는 언제나 NFT 객체를 파괴(또는 소각)할 수 있습니다.
NFT를 영구히 파괴하는 방법:
Token ID를 입력합니다.
Burn NFT를 클릭합니다.
Quickstart Samples 아카이브를 다운로드하여 각 샘플을 브라우저에서 시도해볼 수 있습니다.
// *******************************************************
// ********************** Mint Token *********************
// *******************************************************
async function mintToken() {
ledger에 연결해서 계정지갑을 가져오세요.
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 NFT.'
standbyResultField.value = results
트랜잭션을 정의하세요.
const transactionJson = {
"TransactionType": "NFTokenMint",
"Account": standby_wallet.classicAddress,
URI 필드에는 리터럴 URI 문자열이 아닌 16진수 값이 필요합니다. convertStringToHex
유틸리티를 사용하여 URI를 실시간으로 변환할 수 있습니다.
"URI": xrpl.convertStringToHex(standbyTokenUrlField.value),
타사에 NFT를 전송하려면 플래그 필드를 8로 설정합니다.
"Flags": parseInt(standbyFlagsField.value),
트랜잭션 수수료는 0 ~ 50000의 값이며, 로열티를 0.001씩 0.000% ~ 50.000%로 설정하는 데 사용됩니다.
"TransferFee": parseInt(standbyTransferFeeField.value),
TokenTaxon
은 필수 값입니다. 발행자가 정의한 임의의 값입니다. 필드를 사용하지 않는 경우 필드를 0으로 설정할 수 있습니다.
"NFTokenTaxon": 0 //Required, but if you have no use for it, set to zero.
}
트랜잭션을 보내고 응답을 기다립니다.
const tx = await client.submitAndWait(transactionJson, { wallet: standby_wallet} )
계정이 소유한 NFT 목록을 요청합니다.
const nfts = await client.request({
method: "account_nfts",
account: standby_wallet.classicAddress
})
결과를 보고합니다.
results += '\n\nTransaction result: '+ tx.result.meta.TransactionResult
results += '\n\nnfts: ' + JSON.stringify(nfts, null, 2)
standbyBalanceField.value = (await client.getXrpBalance(standby_wallet.address))
standbyResultField.value = results
ledger에서 연결을 끊습니다.
client.disconnect()
} //End of mintToken()
// *******************************************************
// ******************* Get Tokens ************************
// *******************************************************
async function getTokens() {
ledger에 연결해 계정을 가져오세요.
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 NFTs...'
standbyResultField.value = results
계정이 소유한 NFT 목록을 요청합니다.
const nfts = await client.request({
method: "account_nfts",
account: standby_wallet.classicAddress
})
결과를 보고합니다.
results += '\nNFTs:\n ' + JSON.stringify(nfts,null,2)
standbyResultField.value = results
ledger에서 연결을 끊습니다.
client.disconnect()
} //End of getTokens()
// *******************************************************
// ********************* Burn Token **********************
// *******************************************************
async function burnToken() {
ledger에 연결해서 계정 지갑을 가져오세요.
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 NFT...'
standbyResultField.value = results
트랜잭션을 정의합니다.
const transactionBlob = {
"TransactionType": "NFTokenBurn",
"Account": standby_wallet.classicAddress,
"NFTokenID": standbyTokenIdField.value
}
트랜잭션을 제출하고 결과를 기다립니다.
const tx = await client.submitAndWait(transactionBlob,{wallet: standby_wallet})
계정이 소유한 NFT 목록을 요청합니다.
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()
이러한 트랜잭션은 Standby account 트랜잭션과 동일하지만 Operational account에 대한 트랜잭션입니다.
// *******************************************************
// ************** 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 NFT.'
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 += '\n\nTransaction result: '+ tx.result.meta.TransactionResult
results += '\n\nnfts: ' + 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 NFTs...'
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 NFT...'
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()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: middle;}
</style>
<script src='https://unpkg.com/xrpl@2.7.0/build/xrpl-latest-min.js'></script>
<script src='ripplex1-send-xrp.js'></script>
<script src='ripplex2-send-currency.js'></script>
<script src='ripplex3-mint-nfts.js'></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" checked>
<label for="testnet">Testnet</label>
<input type="radio" id="dn" name="server"
value="wss://s.devnet.rippletest.net:51233">
<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>
<table>
<tr valign="top">
<td>
<td>
<button type="button" onClick="getAccount('standby')">Get New Standby Account</button>
<table>
<tr valign="top">
<td align="right">
Standby Account
</td>
<td>
<input type="text" id="standbyAccountField" size="40"></input>
<br>
</td>
</tr>
<tr>
<td align="right">
Public Key
</td>
<td>
<input type="text" id="standbyPubKeyField" size="40"></input>
<br>
</td>
</tr>
<tr>
<td align="right">
Private Key
</td>
<td>
<input type="text" id="standbyPrivKeyField" size="40"></input>
<br>
</td>
</tr>
<tr>
<td align="right">
Seed
</td>
<td>
<input type="text" id="standbySeedField" size="40"></input>
<br>
</td>
</tr>
<tr>
<td align="right">
XRP Balance
</td>
<td>
<input type="text" id="standbyBalanceField" size="40"></input>
<br>
</td>
</tr>
<tr>
<td align="right">
Amount
</td>
<td>
<input type="text" id="standbyAmountField" size="40"></input>
<br>
</td>
</tr>
<tr>
<td align="right">
Destination
</td>
<td>
<input type="text" id="standbyDestinationField" size="40"></input>
<br>
</td>
</tr>
<tr valign="top">
<td><button type="button" onClick="configureAccount('standby',document.querySelector('#standbyDefault').checked)">Configure Account</button></td>
<td>
<input type="checkbox" id="standbyDefault" checked="true"/>
<label for="standbyDefault">Allow Rippling</label>
</td>
</tr>
<tr>
<td align="right">
Currency
</td>
<td>
<input type="text" id="standbyCurrencyField" size="40" value="USD"></input>
</td>
</tr>
<tr>
<td align="right">NFT URL</td>
<td><input type="text" id="standbyTokenUrlField"
value = "ipfs://bafybeigdyrzt5sfp7udm7hu76uh7y26nf4dfuylqabf3oclgtqy55fbzdi" size="80"/>
</td>
</tr>
<tr>
<td align="right">Flags</td>
<td><input type="text" id="standbyFlagsField" value="1" size="10"/></td>
</tr>
<tr>
<td align="right">NFT ID</td>
<td><input type="text" id="standbyTokenIdField" value="" size="80"/></td>
</tr>
<tr>
<td align="right">Transfer Fee</td>
<td><input type="text" id="standbyTransferFeeField" value="" size="80"/></td>
</tr>
</table>
<p align="left">
<textarea id="standbyResultField" cols="80" rows="20" ></textarea>
</p>
</td>
</td>
<td>
<table>
<tr valign="top">
<td align="center" valign="top">
<button type="button" onClick="sendXRP()">Send XRP></button>
<br/><br/>
<button type="button" onClick="createTrustline()">Create TrustLine</button>
<br/>
<button type="button" onClick="sendCurrency()">Send Currency</button>
<br/>
<button type="button" onClick="getBalances()">Get Balances</button>
<br/><br/>
<button type="button" onClick="mintToken()">Mint NFT</button>
<br/>
<button type="button" onClick="getTokens()">Get NFTs</button>
<br/>
<button type="button" onClick="burnToken()">Burn NFT</button>
</td>
</tr>
</td>
</tr>
</table>
</td>
</tr>
</table>
</td>
<td>
<table>
<tr>
<td>
<td>
<table>
<tr>
<td align="center" valign="top">
<button type="button" onClick="oPsendXRP()">< Send XRP</button>
<br/><br/>
<button type="button" onClick="oPcreateTrustline()">Create TrustLine</button>
<br/>
<button type="button" onClick="oPsendCurrency()">Send Currency</button>
<br/>
<button type="button" onClick="getBalances()">Get Balances</button>
<br/><br/>
<button type="button" onClick="oPmintToken()">Mint NFT</button>
<br/>
<button type="button" onClick="oPgetTokens()">Get NFTs</button>
<br/>
<button type="button" onClick="oPburnToken()">Burn NFT</button>
<td valign="top" align="right">
<button type="button" onClick="getAccount('operational')">Get New Operational Account</button>
<table>
<tr valign="top">
<td align="right">
Operational Account
</td>
<td>
<input type="text" id="operationalAccountField" size="40"></input>
<br>
</td>
</tr>
<tr>
<td align="right">
Public Key
</td>
<td>
<input type="text" id="operationalPubKeyField" size="40"></input>
<br>
</td>
</tr>
<tr>
<td align="right">
Private Key
</td>
<td>
<input type="text" id="operationalPrivKeyField" size="40"></input>
<br>
</td>
</tr>
<tr>
<td align="right">
Seed
</td>
<td>
<input type="text" id="operationalSeedField" size="40"></input>
<br>
</td>
</tr>
<tr>
<td align="right">
XRP Balance
</td>
<td>
<input type="text" id="operationalBalanceField" size="40"></input>
<br>
</td>
</tr>
<tr>
<td align="right">
Amount
</td>
<td>
<input type="text" id="operationalAmountField" size="40"></input>
<br>
</td>
</tr>
<tr>
<td align="right">
Destination
</td>
<td>
<input type="text" id="operationalDestinationField" size="40"></input>
<br>
</td>
</tr>
<tr>
<td>
</td>
<td align="right"> <input type="checkbox" id="operationalDefault" checked="true"/>
<label for="operationalDefault">Allow Rippling</label>
<button type="button" onClick="configureAccount('operational',document.querySelector('#operationalDefault').checked)">Configure Account</button>
</td>
</tr>
<tr>
<td align="right">
Currency
</td>
<td>
<input type="text" id="operationalCurrencyField" size="40" value="USD"></input>
</td>
</tr>
<tr>
<td align="right">NFT URL</td>
<td><input type="text" id="operationalTokenUrlField"
value = "ipfs://bafybeigdyrzt5sfp7udm7hu76uh7y26nf4dfuylqabf3oclgtqy55fbzdi" size="80"/>
</td>
</tr>
<tr>
<td align="right">Flags</td>
<td><input type="text" id="operationalFlagsField" value="1" size="10"/></td>
</tr>
<tr>
<td align="right">NFT ID</td>
<td><input type="text" id="operationalTokenIdField" value="" size="80"/></td>
</tr>
<tr>
<td align="right">Transfer Fee</td>
<td><input type="text" id="operationalTransferFeeField" value="" size="80"/></td>
</tr>
</table>
<p align="right">
<textarea id="operationalResultField" cols="80" rows="20" ></textarea>
</p>
</td>
</td>
</tr>
</td>
</tr>
</table>
</td>
</tr>
</table>
</td>
</tr>
</table>
</form>
</body>
</html>