레슨2
계정 생성 및 XRP 보내기
XRPL 테스트넷에 계정을 만들고 두 계정 간에 XRP를 전송하세요.
이 수업에서는 다음 방법을 보여줍니다.
- 실제 가치가 없는 930 XRP를 지원받은 계정을 테스트넷에 만듭니다.
- 시드 값에서 계정을 검색합니다.
- 계정 간에 XRP를 전송합니다.
계정을 생성하면 공개/ 개인키 쌍을 오프라인으로 받게 됩니다. 이는 XRP를 지원받을 때까지는 원장에 나타나지 않습니다. 이 수업에서는 테스트넷용 계정을 만드는 방법을 보여주지만, 메인넷에서 사용할 수 있는 계정을 만드는 방법은 보여주지 않습니다.
코드를 편집해 보세요: get-accounts-send-xrp.js
아래의 대화형 코드 예제는 모든 XRP Ledger 네트워크(테스트넷 , 개발넷 또는 메인넷) 와 함께 사용할 수 있습니다. 코드를 직접 빌드할 때, 다른 XRP Ledger 네트워크나 추가 XRP Ledger 네트워크를 선택할 수 있도록 코드를 업데이트할 수 있습니다.
토큰 테스트 코드를 열고 테스트 계정을 받으세요.
- CodeSandbox를 엽니다.
- 테스트넷을 ****선택합니다.
- “Create Standy Account” 를 ****클릭합니다 .
- “Create Operational Account” 를 클릭합니다.
- 메모장과 같은 영구적인 위치에 시드 ****필드를 복사하여 붙여 넣으면 폼을 다시 로드한 후 계정을 다시 사용할 수 있습니다.
새 계정 간에 XRP를 전송할 수 있습니다. 각 계정에는 고유한 필드와 버튼이 있습니다.
계정 간에 XRP를 전송하기:
- 보낼 XRP 금액을 입력합니다 .
- 대상 ****계정을 입력합니다 (예: Operational Account 필드를 Standby Destination Account 에 붙여넣기).
- Standby Account 에서 Operational Account 로 XRP를 이체하기 위해 “Send XRP→” 를 클릭합니다. 혹은, Operational Account 에서 Standby Account 로 XRP를 이체하기 위해 “←Send XRP” 를 클릭합니다.
JavaScript 코드 연습: get-accounts-send-xrp.js
이 예는 모든 XRP Ledger 네트워크(테스트넷 , 개발넷 또는 메인넷) 에서 사용할 수 있습니다 . 다른 XRP Ledger 네트워크나 추가 XRP Ledger 네트워크를 선택할 수 있도록 코드를 업데이트할 수 있습니다.
getAccount() 함수는 getNet()으로 선택한 장부를 가져오는 것으로 시작됩니다.
그 후 results 변수를 사용하여 진행 상황 정보를 기록하세요.
폼 필드 정의
코드 전체에서 JavaScript 함수 document.getElementById() 를 사용하는데, 이는 CSS ID로 HTML 요소를 타겟팅하는 데 사용됩니다. 이러한 함수를 사용하여 토큰 테스트 코드의 HTML 폼 필드에서 값을 설정하고 가져옵니다. 코드의 가독성을 유지하기 위해 이러한 함수 호출을 대체하는 일부 상수를 정의했습니다.
// *** Define HTML Form Fields **
const xls = document.getElementById("xls")
const tn = document.getElementById("tn")
const dn = document.getElementById("dn")
const standbyResultField = document.getElementById('standbyResultField');
const operationalResultsField = document.getElementById('operationalResultField');
const standbyAccountField = document.getElementById('standbyAccountField');
const standbyPubKeyField = document.getElementById('standbyPubKeyField');
const standbyPrivKeyField = document.getElementById('standbyPrivKeyField');
const standbyBalanceField = document.getElementById('standbyBalanceField');
const standbySeedField = document.getElementById('standbySeedField');
const operationalAccountField = document.getElementById('operationalAccountField');
const operationalPubKeyField = document.getElementById('operationalPubKeyField');
const operationalPrivKeyField = document.getElementById('operationalPrivKeyField');
const operationalSeedField = document.getElementById('operationalSeedField');
const operationalBalanceField = document.getElementById('operationalBalanceField');
getNet() 및 getAccount(type)
// ************* Get the Preferred Network **************
function getNet() {
let net
if (tn.checked) net = "wss://s.altnet.rippletest.net:51233"
if (dn.checked) net = "wss://s.devnet.rippletest.net:51233"
return net
} // End of getNet()
// *******************************************************
// ************* Get Account *****************************
// *******************************************************
async function getAccount(type) {
let net = getNet()
const client = new xrpl.Client(net)
results = 'Connecting to ' + net + '....'
// This uses the default faucet for Testnet/Devnet
let faucetHost = null
if(document.getElementById("xls").checked) {
faucetHost = "faucet-nft.ripple.com"
}
if (type == 'standby') {
standbyResultField.value = results
} else {
operationalResultField.value = results
}
await client.connect()
results += 'nConnected, funding wallet.'
if (type == 'standby') {
standbyResultField.value = results
} else {
operationalResultField.value = results
}
// -----------------------------------Create and fund a test account wallet
const my_wallet = (await client.fundWallet(null, { faucetHost })).wallet
results += 'nGot a wallet.'
if (type == 'standby') {
standbyResultField.value = results
} else {
operationalResultField.value = results
}
// -----------------------------------Get the current balance.
const my_balance = (await client.getXrpBalance(my_wallet.address))
if (type == 'standby') {
standbyAccountField.value = my_wallet.address
standbyPubKeyField.value = my_wallet.publicKey
standbyPrivKeyField.value = my_wallet.privateKey
standbyBalanceField.value =
(await client.getXrpBalance(my_wallet.address))
standbySeedField.value = my_wallet.seed
results += 'nStandby account created.'
standbyResultField.value = results
} else {
operationalAccountField.value = my_wallet.address
operationalPubKeyField.value = my_wallet.publicKey
operationalPrivKeyField.value = my_wallet.privateKey
operationalSeedField.value = my_wallet.seed
operationalBalanceField.value =
(await client.getXrpBalance(my_wallet.address))
results += 'nOperational account created.'
operationalResultField.value = results
}
// --------------- Capture the seeds for both accounts for ease of reload.
seeds.value = standbySeedField.value + 'n' + operationalSeedField.value
client.disconnect()
} // End of getAccount()
getAccountsFromSeeds()
// *******************************************************
// ********** Get Accounts from Seeds ********************
// *******************************************************
async function getAccountsFromSeeds() {
let net = getNet()
const client = new xrpl.Client(net)
results = 'Connecting to ' + getNet() + '....'
standbyResultField.value = results
await client.connect()
results += 'nConnected, finding wallets.n'
standbyResultField.value = results
// -----------------------------------Find the test account wallets
var lines = seeds.value.split('n');
const standby_wallet = xrpl.Wallet.fromSeed(lines[0])
const operational_wallet = xrpl.Wallet.fromSeed(lines[1])
// -----------------------------------Get the current balance.
const standby_balance = (await client.getXrpBalance(standby_wallet.address))
const operational_balance = (await client.getXrpBalance(operational_wallet.address))
// ------------------Populate the fields for Standby and Operational accounts
standbyAccountField.value = standby_wallet.address
standbyPubKeyField.value = standby_wallet.publicKey
standbyPrivKeyField.value = standby_wallet.privateKey
standbySeedField.value = standby_wallet.seed
standbyBalanceField.value = (await client.getXrpBalance(standby_wallet.address))
operationalAccountField.value = operational_wallet.address
operationalPubKeyField.value = operational_wallet.publicKey
operationalPrivKeyField.value = operational_wallet.privateKey
operationalSeedField.value = operational_wallet.seed
operationalBalanceField.value = (await client.getXrpBalance(operational_wallet.address))
client.disconnect()
} // End of getAccountsFromSeeds()
sendXRP()
// // *******************************************************
// ******************** Send XRP *************************
// *******************************************************
async function sendXRP() {
results = "Connecting to the selected ledger.n"
standbyResultField.value = results
let net = getNet()
results = 'Connecting to ' + getNet() + '....'
const client = new xrpl.Client(net)
await client.connect()
results += "nConnected. Sending XRP.n"
standbyResultField.value = results
const standby_wallet = xrpl.Wallet.fromSeed(standbySeedField.value)
const operational_wallet = xrpl.Wallet.fromSeed(operationalSeedField.value)
const sendAmount = standbyAmountField.value
results += "nstandby_wallet.address: = " + standby_wallet.address
standbyResultField.value = results
// ------------------------------------------------------- Prepare transaction
// Note that the destination is hard coded.
const prepared = await client.autofill({
"TransactionType": "Payment",
"Account": standby_wallet.address,
"Amount": xrpl.xrpToDrops(sendAmount),
"Destination": standbyDestinationField.value
})
// ------------------------------------------------ Sign prepared instructions
const signed = standby_wallet.sign(prepared)
// -------------------------------------------------------- Submit signed blob
const tx = await client.submitAndWait(signed.tx_blob)
results += "nBalance changes: " +
JSON.stringify(xrpl.getBalanceChanges(tx.result.meta), null, 2)
standbyResultField.value = results
standbyBalanceField.value =
(await client.getXrpBalance(standby_wallet.address))
operationalBalanceField.value =
(await client.getXrpBalance(operational_wallet.address))
client.disconnect()
} // End of sendXRP()
상호 거래: oPsendXRP()
각 거래에는 operational account 에 대한 접두사 oP 가 붙은 동반 상호 거래가 있습니다. 코드 설명은 standby account에 대한 해당 기능을 참조하세요.
// *******************************************
// ****** Reciprocal Transactions ************
// *******************************************
// *****Send XRP from Operational account ****
// *******************************************
async function oPsendXRP() {
results = "Connecting to the selected ledger.n"
operationalResultField.value = results
let net = getNet()
results = 'Connecting to ' + getNet() + '....'
const client = new xrpl.Client(net)
await client.connect()
results += "nConnected. Sending XRP.n"
operationalResultField.value = results
const operational_wallet = xrpl.Wallet.fromSeed(operationalSeedField.value)
const standby_wallet = xrpl.Wallet.fromSeed(standbySeedField.value)
const sendAmount = operationalAmountField.value
results += "noperational_wallet.address: = " + operational_wallet.address
operationalResultField.value = results
// ------------------------------------------------------- Prepare transaction
// Note that the destination is hard coded.
const prepared = await client.autofill({
"TransactionType": "Payment",
"Account": operational_wallet.address,
"Amount": xrpl.xrpToDrops(operationalAmountField.value),
"Destination": operationalDestinationField.value
})
// ------------------------------------------------ Sign prepared instructions
const signed = operational_wallet.sign(prepared)
// -------------------------------------------------------- Submit signed blob
const tx = await client.submitAndWait(signed.tx_blob)
results += "nBalance changes: " +
JSON.stringify(xrpl.getBalanceChanges(tx.result.meta), null, 2)
operationalResultField.value = results
standbyBalanceField.value =
(await client.getXrpBalance(standby_wallet.address))
operationalBalanceField.value =
(await client.getXrpBalance(operational_wallet.address))
client.disconnect()
} // End of oPsendXRP()
HTML 폼 미리보기: 1.get-accounts-send-xrp.html
거래 및 요청을 보내고 결과를 표시하기 위한 표준 HTML 폼을 만듭니다.
<html>
<head>
<title>Token Test Harness</title>
<link href='https://fonts.googleapis.com/css?family=Work Sans' rel='stylesheet'>
<script src='https://unpkg.com/xrpl@2.2.3'></script>
<script>
if (typeof module !== "undefined") {
const xrpl = require('xrpl')
}
</script>
<style>
body{font-family: "Work Sans", sans-serif;padding: 20px;background: #fafafa;font-size:.8em;}
h1{font-weight: bold;}
input, button {padding: 6px;margin-bottom: 8px;font-size:.8em;}
button{font-weight: bold;font-family: "Work Sans", sans-serif;}
td{vertical-align: top;padding-right:10px;}
</style>
</head>
<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">... You can use this later once you generate seeds</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>
<td>
<p align="right">
<button type="button" onClick="sendXRP()">Send XRP ↓</button>
</p>
</td>
</tr>
</table>
</td>
<td>
<textarea id="standbyResultField" cols="60" rows="20" ></textarea>
</td>
</tr>
</table>
<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>
<td>
<p align="right">
<button type="button" onClick="oPsendXRP()">Send XRP ↑</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>
</html>