本文へスキップ
このページは英語からの機械翻訳を使用しており、誤りや不明瞭な表現が含まれている可能性があります。最も正確な情報については、オリジナルの英語版をご覧ください。頻繁な更新のため、一部のコンテンツはオリジナルの英語になっている可能性があります。Crowdinでの取り組みに参加して、このページの翻訳改善にご協力ください。 (Crowdin translation page, Contributing guide)

ガスレス

ethers.jsにガスレス機能を追加するために、ethersパッケージと**@kaiachain/ethers-ext/v6**パッケージをインポートする。

ERC20トークンのアドレス(Kairos testnet上のTESTトークン)。

senderAddr:**スワップを行う送信者のウォレットアドレスと、**senderPriv:**トランザクションに署名するための送信者の秘密鍵を宣言する。

KaiaKairosテストネットでJSON-RPCプロバイダとWalletのインスタンスを作成する

ERC20トークンのための最小限のABIで、小数、記号、手当、残高を照会する関数を含む。

送金人がスワップから受け取りたい固定額0.01KAIA(ウェイ)。

アドレスにトークンを表示する:

ERC20トークンコントラクトのインスタンスを作成し、その機能と対話します。

トークンのシンボルを問い合わせる(例えば、TESTトークンなら "TEST")。

トークンの小数点以下の桁数を問い合わせる(例えば、ETHやTESTのようなほとんどのERC20トークンは18)。

ERC20トークンの送信者の残高を照会します。

送信者の初期残高を表示する。

Kaiaブロックチェーン上のガスレストークンスワップを促進するGaslessSwapRouterコントラクトのインスタンスを取得します。

GaslessSwapRouter 契約のブロックチェーンアドレスを取得します。

指定されたERC20トークンがガスレススワップ用のGaslessSwapRouterでサポートされているかどうかをチェックします。

ガスレススワップを促進するために GaslessSwapRouter が請求する手数料率を取得します。

GaslessSwapRouterのアドレス、トークンがサポートされている場合はtrue、手数料率を表示します。

GaslessSwapRouter が送信者に代わって使用できるトークンの数をチェックする。

引当金がゼロかどうかをチェックすることにより、承認トランザクションが必要かどうかを判断する。

後で送信されるトランザクションを格納する空の配列を初期化する。

approveRequired フラグに基づいて、承認トランザクションが必要かどうかをチェックする。 GaslessSwapRouterが送信者のトークンを使用できるように、ERC20の承認トランザクションを生成する。

ブロックチェーンから現在のガス価格を取得し、JavaScriptの数値に変換する。

トランザクションのガスコストを賄うために送金者がブロックマイナーに返済しなければならないKAIAの合計額(ウェイ)を計算する。

スワップが、返済、手数料、希望する申込取引手数料をカバーするために生み出さなければならないKAIAの最低額(ウェイ)を計算します。

スリッページを考慮して、少なくとも minAmountOut KAIA を受け取るためにスワップすべき ERC20 トークンの量を計算します。

送信者の ERC20 トークンの残高が、スワップに必要なトークンの量に不足しているかどうかをチェックします。

指定された量のERC20トークンを少なくとも最低量のKAIAと交換するスワップ取引を生成し、ガスなし返済ロジックを組み込む。 スワップトランザクションをバッチ実行のために 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

ページを改善してください。