跳至主要內容
本頁面使用機器翻譯自英語,可能包含錯誤或不清楚的語言。如需最準確的信息,請參閱英文原文。由於更新頻繁,部分內容可能與英文原文有出入。請加入我們在 Crowdin 上的努力,幫助我們改進本頁面的翻譯。 (Crowdin translation page, Contributing guide)

無氣

匯入 ethers@kaiachain/ethers-ext/v6 套件,在 ethers.js 上加入無氣功能

ERC20 代幣地址(Kairos 測試網的 TEST 代幣)。

宣告 senderAddr: 執行交換的寄件者的錢包地址,以及 senderPriv: 用於簽署交易的寄件者私密金鑰。

使用 Kaia Kairos 測試網路建立 JSON-RPC 提供者和 Wallet 的實例

ERC20 代幣的最小 ABI,包括查詢小數、符號、免稅額和餘額的功能。

寄件者希望從交換中收到的固定金額 0.01 KAIA(Wei),以便為後續的應用程式交易提供資金。

在地址處顯示代幣:

建立 ERC20 代幣合約的實體,以與其功能互動。

查詢標記的符號 (例如:"TEST" 代表 TEST 標記)。

查詢代幣的小數位數 (例如,大多數 ERC20 代幣如 ETH 或 TEST 為 18)。

查詢寄件者的 ERC20 代幣餘額。

顯示寄件者的初始餘額。

擷取 GaslessSwapRouter 契約的實體,該契約可促進 Kaia 區塊鏈上的無瓦斯代幣交換。

擷取 GaslessSwapRouter 契約的區塊鏈位址。

檢查 GaslessSwapRouter 是否支援指定的 ERC20 令牌進行無氣體交換。

擷取 GaslessSwapRouter 為促進無瓦斯交換而收取的佣金費率。

顯示 GaslessSwapRouter 位址、true(如果支援代幣)和傭金費率。

檢查 GaslessSwapRouter 允許代表寄件者花費多少代幣。

透過檢查備用金是否為零,決定是否需要進行核准交易。

初始化一個空陣列,用來儲存稍後傳送的交易。

根據 approveRequired 標誌檢查是否需要核准交易。 產生 ERC20 核准交易,允許 GaslessSwapRouter 使用寄件者的代幣。

從區塊鏈擷取目前的瓦斯價格,並將其轉換成 JavaScript 數字。

計算寄件者必須償還給區塊礦工的 KAIA 總金額 (單位:Wei),以支付交易的瓦斯費用。

計算掉期必須產生的最低 KAIA 金額(Wei),以支付還款、傭金和所需的申請交易費用。

計算要交換多少 ERC20 代幣才能至少收到 minAmountOut KAIA,並計入滑點。

檢查寄件者的 ERC20 代幣餘額是否不足以支付交換所需的代幣數量。

產生交換交易,以指定數量的 ERC20 代幣交換至少最低數量的 KAIA,並結合無瓦斯還款邏輯。 將 swap 交易加入 txs 陣列,以便批次執行。

使用寄件者的錢包傳送 txs 陣列中的所有交易。 迭代已傳送的交易,以記錄其詳細資訊。

等待交易被挖出,並擷取其交易收據。

列出與寄件者相關的區塊交易

寄件人的最終結餘

Gasless.js

const ethers = require("ethers");
const { Wallet, gasless } = require("@kaiachain/ethers-ext/v6");
// Replace with ERC20 token address to be spent
const tokenAddr = "0xcB00BA2cAb67A3771f9ca1Fa48FDa8881B457750"; // Kairos:TEST token
// Replace with your wallet address and private key
const senderAddr = "0xa0Ee7A142d267C1f36714E4a8F75612F20a79720";
const senderPriv = "0x2a871d0798f97d79848a013d4936a73bf4cc922c825d33c1cf7073dff6d409c6";
const provider = new ethers.JsonRpcProvider("https://public-en-kairos.node.kaia.io");
const wallet = new Wallet(senderPriv, provider);
const ERC20_ABI = [
"function decimals() view returns (uint8)",
"function symbol() view returns (string)",
"function allowance(address owner, address spender) view returns (uint256)",
"function balanceOf(address owner) view returns (uint256)"
];
// senderAddr wants to swap the ERC20 token for at least 0.01 KAIA so she can execute the AppTx.
async function main() {
const appTxFee = ethers.parseEther("0.01").toString();
// Query the environment
console.log(`Using token at address: ${tokenAddr}`);
const token = new ethers.Contract(tokenAddr, ERC20_ABI, provider);
const tokenSymbol = await token.symbol();
const tokenDecimals = await token.decimals();
const tokenBalance = await token.balanceOf(senderAddr);
console.log(`\nInitial balance of the sender ${senderAddr}`);
console.log(`- ${ethers.formatEther(await provider.getBalance(senderAddr))} KAIA`);
console.log(`- ${ethers.formatUnits(tokenBalance, tokenDecimals)} ${tokenSymbol}`);
const router = await gasless.getGaslessSwapRouter(provider);
const routerAddr = await router.getAddress();
const isTokenSupported = await router.isTokenSupported(tokenAddr);
const commissionRate = Number(await router.commissionRate());
console.log(`\nGaslessSwapRouter address: ${routerAddr}`);
console.log(`- The token is supported: ${isTokenSupported}`);
console.log(`- Commission rate: ${commissionRate} bps`);
// If sender hasn't approved, include ApproveTx first.
const allowance = await token.allowance(senderAddr, routerAddr);
const approveRequired = (allowance == 0n);
const txs = [];
if (approveRequired) {
console.log("\nAdding ApproveTx because allowance is 0");
const approveTx = await gasless.getApproveTx(
provider,
senderAddr,
tokenAddr,
routerAddr,
gasPrice,
);
txs.push(approveTx);
} else {
console.log("\nNo ApproveTx needed");
}
// - amountRepay (KAIA) is the cost of LendTx, ApproveTx, and SwapTx. The block miner shall fund it first,
// then the sender has to repay from the swap output.
// - minAmountOut (KAIA) is the required amount of the swap output. It must be enough to cover the amountRepay
// and pay the commission, still leaving appTxFee.
// - amountIn (token) is the amount of the token to be swapped to produce minAmountOut plus slippage.
console.log("\nCalculating the amount of the token to be swapped...");
const gasPrice = Number((await provider.getFeeData()).gasPrice);
console.log(`- gasPrice: ${ethers.formatUnits(gasPrice, "gwei")} gkei`);
const amountRepay = gasless.getAmountRepay(approveRequired, gasPrice);
console.log(`- amountRepay: ${ethers.formatEther(amountRepay)} KAIA`);
const minAmountOut = gasless.getMinAmountOut(amountRepay, appTxFee, commissionRate);
console.log(`- minAmountOut: ${ethers.formatEther(minAmountOut)} KAIA`);
const slippageBps = 50 // 0.5%
const amountIn = await gasless.getAmountIn(router, tokenAddr, minAmountOut, slippageBps);
console.log(`- amountIn: ${ethers.formatUnits(amountIn, tokenDecimals)} ${tokenSymbol}`);
if (tokenBalance < amountIn) {
console.log(`\nInsufficient balance of the token: ${ethers.formatUnits(tokenBalance, tokenDecimals)} ${tokenSymbol}`);
console.log(`- Please transfer more ${tokenSymbol} to the sender ${senderAddr}`);
return;
}
const swapTx = await gasless.getSwapTx(
provider,
senderAddr,
tokenAddr,
routerAddr,
amountIn,
minAmountOut,
amountRepay,
gasPrice,
approveRequired,
);
txs.push(swapTx);
console.log("\nSending transactions...");
const sentTxs = await wallet.sendTransactions(txs);
for (const tx of sentTxs) {
console.log(`- Tx sent: (nonce: ${tx.nonce}) ${tx.hash}`);
}
console.log("\nWaiting for transactions to be mined...");
let blockNum = 0;
for (const sentTx of sentTxs) {
const receipt = await sentTx.wait();
console.log(`- Tx mined at block ${receipt.blockNumber}`);
blockNum = receipt.blockNumber;
}
console.log("\nListing the block's transactions related to the sender...");
const block = await provider.getBlock(blockNum, true);
const names = {
[senderAddr.toLowerCase()]: "sender",
[tokenAddr.toLowerCase()]: "token",
[routerAddr.toLowerCase()]: "router",
}
for (const txhash of block.transactions) {
const tx = await provider.getTransaction(txhash);
const fromName = names[tx.from.toLowerCase()] || tx.from;
const toName = names[tx.to.toLowerCase()] || tx.to;
if (fromName != tx.from || toName != tx.to) {
console.log(`- Tx ${tx.hash}: ${fromName} => ${toName}`);
}
}
console.log(`\nFinal balance of the sender ${senderAddr}`);
console.log(`- ${ethers.formatEther(await provider.getBalance(senderAddr))} KAIA`);
console.log(`- ${ethers.formatUnits(await token.balanceOf(senderAddr), tokenDecimals)} ${tokenSymbol}`);
}
main().catch(console.error);

output

❯ node Gasless.js
Using token at address: 0xcB00BA2cAb67A3771f9ca1Fa48FDa8881B457750
Initial balance of the sender 0xa0Ee7A142d267C1f36714E4a8F75612F20a79720
- 49.9969537425 KAIA
- 3.0 TEST
GaslessSwapRouter address: 0x4b41783732810b731569E4d944F59372F411BEa2
- The token is supported: true
- Commission rate: 0 bps
- 3.0 TEST
GaslessSwapRouter address: 0x4b41783732810b731569E4d944F59372F411BEa2
- The token is supported: true
- Commission rate: 0 bps
GaslessSwapRouter address: 0x4b41783732810b731569E4d944F59372F411BEa2
- The token is supported: true
- Commission rate: 0 bps
- The token is supported: true
- Commission rate: 0 bps
- Commission rate: 0 bps
Adding ApproveTx because allowance is 0
Calculating the amount of the token to be swapped...
- gasPrice: 27.5 gkei
- amountRepay: 0.0170775 KAIA
- minAmountOut: 0.0270775 KAIA
- amountIn: 0.027300931296609197 TEST
Sending transactions...
- Tx sent: (nonce: 5) 0x1d2bd9e5ae11653b8cddb297d040074b189fe456ae986197c4c2bbf74a51e6ef
- Tx sent: (nonce: 6) 0x96dd81962d7ae14baf31bd0a8afb900be1a6c9c8d30ad854011a4120fb0efbaf
Waiting for transactions to be mined...
- Tx mined at block 192123894
- Tx mined at block 192123894
Listing the block's transactions related to the sender...
- Tx 0x50769b14c7814f4e6b169f63595c1c19d9c46ce1c626c14b6b3c5610f691f58a: 0xB74Ff9DEa397fE9E231df545eb53fE2ADF776cb2 => sender
- Tx 0x1d2bd9e5ae11653b8cddb297d040074b189fe456ae986197c4c2bbf74a51e6ef: sender => token
- Tx 0x96dd81962d7ae14baf31bd0a8afb900be1a6c9c8d30ad854011a4120fb0efbaf: sender => router
Final balance of the sender 0xa0Ee7A142d267C1f36714E4a8F75612F20a79720
- 50.016275725 KAIA
- 2.972699068703390803 TEST

讓這個頁面變得更好