跳到正文
DEV Community· rene·· 3 小時前AI 評分31

無需後端也沒問題:我如何用 eth_call 建立靜態加密貨幣結帳頁

No Backend? No Problem: How I Built a Static Crypto Checkout Using eth_call

AI 導讀

作者以單次 eth_call 建立靜態 USDT 結帳頁,並在瀏覽器內核實付款,毋須後端伺服器。系統把起始餘額和預期付款額存入 localStorage,每 20 秒檢查餘額差,並以 0.1% 容差確認付款。同一地址短時間收到多筆付款時,系統或難以配對訂單;商品交付和退款亦須商戶手動處理。

正文

No Backend? No Problem: How I Built a Static Crypto Checkout Using eth_call

Accepting crypto payments usually means running a server to watch the blockchain. But what if you could do it all from a static HTML page? No database, no backend, no websocket—just a browser and an RPC endpoint. Here's how I built a working USDT checkout that verifies payments using a single eth_call.

The Magic of eth_call and Selector 0x70a08231

Every ERC-20 token, including USDT, has a balanceOf(address) function. When you call this function via an RPC provider, the Ethereum Virtual Machine (EVM) returns the token balance for that address. The function signature is balanceOf(address) which hashes to the 4-byte selector 0x70a08231.

To call it from JavaScript, you encode the ABI:

const abi = [
  {
    constant: true,
    inputs: [{ name: "_owner", type: "address" }],
    name: "balanceOf",
    outputs: [{ name: "balance", type: "uint256" }],
    type: "function",
  },
];
const iface = new ethers.utils.Interface(abi);
const data = iface.encodeFunctionData("balanceOf", [customerAddress]);

Then send it as an eth_call to any public RPC (e.g., Infura, Alchemy, or a free endpoint):

const response = await fetch(rpcUrl, {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({
    jsonrpc: "2.0",
    id: 1,
    method: "eth_call",
    params: [{ to: usdtContract, data: data }, "latest"],
  }),
});
const { result } = await response.json();
const balance = ethers.BigNumber.from(result);

That's it. No server, no API key needed if you use a public RPC. The entire payment verification runs in the browser.

The Verification Algorithm

My system uses three steps:

1. Baseline Balance Check

When a user initiates a checkout, the app records their current USDT balance. This baseline is stored in localStorage along with the expected payment amount.

2. Delta Comparison with 0.1% Tolerance

Every 20 seconds, the app fetches the current balance and compares it to the baseline. If the difference is within 0.1% of the expected amount, the payment is considered confirmed. The tolerance accounts for tiny fluctuations (dust) and rounding errors.

const delta = currentBalance.sub(baselineBalance);
const expected = ethers.utils.parseUnits(expectedAmount, 6); // 6 decimals for USDT
const tolerance = expected.mul(10).div(1000); // 0.1% tolerance

if (delta.gte(expected.sub(tolerance)) && delta.lte(expected.add(tolerance))) {
  // Payment confirmed!
  markAsPaid();
}

3. Polling Loop

The verification runs in a simple polling loop that checks every 20 seconds. This interval balances responsiveness with RPC call efficiency.

Honest Limitations

While this approach is elegant, it's important to understand its limitations:

Balance-Delta Confusion with Concurrent Payments

If multiple payments are sent to the same address in quick succession, the system may struggle to distinguish which payment corresponds to which order. This is a known limitation of the balance-delta approach.

Manual Delivery

This system does not automate product delivery. Once a payment is verified, the merchant must manually fulfill the order. There's no webhook, no automated email, and no digital download trigger.

No Refunds

The system has no built-in refund mechanism. If a customer requests a refund, you'll need to handle it manually outside of this system.

Conclusion

This static crypto payment verification system demonstrates how you can accept cryptocurrency payments without running a backend server. By leveraging eth_call and a simple polling mechanism, you can create a trustless payment experience that works entirely in the user's browser.

The approach is particularly valuable for small businesses or developers who want to experiment with crypto payments without the infrastructure overhead of traditional payment gateways.

Live Demo: https://crypto-store-mvchv2id.netlify.app/

AI Assistance Disclosure: This article was assisted in its creation by AI technology to ensure comprehensive coverage of the topic and maintain a consistent writing style. The content has been reviewed and refined by human editors to ensure accuracy and coherence.

來源:DEV Community · dev.to