Flashblocks#

Flashblocks 在 X Layer 上提供 200 毫秒的预确认(preconfirmation),大幅缩短交易反馈的等待时间,非常适合对速度要求极高的应用场景。

概述#

Flashblocks 大幅降低用户感知延迟,为需要实时交互的应用(如游戏、高频交易、社交应用)提供近乎即时的用户体验。

使用 Flashblocks#

开发者可通过以下方式轻松利用 Flashblocks 的能力:

  1. Pending 标签查询:使用 pending 标签查询已启用 Flashblocks 的 RPC 端点。
  2. 原始数据流式传输:直接从原始 Flashblocks 数据流中获取数据。

支持的 RPC API#

Flashblocks API 完全兼容以太坊(Ethereum)JSON-RPC 标准。Flashblocks API 使用 pending 标签表示最后接收到的 flashblock 链状态,并将其应用于待确认状态(pending state)。

eth_blockNumber#

返回当前 Flashblocks 待确认区块的高度。

shell
curl https://rpc.xlayer.tech/flashblocks -X POST -H "Content-Type: application/json" -d '{"jsonrpc":"2.0","method":"eth_blockNumber","params":["pending"],"id":1}'

响应示例

json
{
  "jsonrpc": "2.0",
  "id": 1,
  "result": "0x832437"
}

eth_call#

立即执行一次新的消息调用,不在区块链上创建交易。

shell
curl https://rpc.xlayer.tech/flashblocks -X POST -H "Content-Type: application/json" -d '{"jsonrpc":"2.0","method":"eth_call","params":[{"to":"0x...","data":"0x..."},"pending"],"id":1}'

响应示例

json
{
  "jsonrpc": "2.0",
  "id": 1,
  "result": "0x0000000000000000000000000000000000000000000000000000000000000001"
}

eth_estimateGas#

返回完成该交易所需的 gas 估算值。

shell
curl https://rpc.xlayer.tech/flashblocks -X POST -H "Content-Type: application/json" -d '{"jsonrpc":"2.0","method":"eth_estimateGas","params":[{"to":"0x...","data":"0x..."},"pending"],"id":1}'

响应示例

json
{
  "jsonrpc": "2.0",
  "id": 1,
  "result": "0x5208"
}

eth_getBalance#

返回给定地址的原生代币余额。

shell
curl https://rpc.xlayer.tech/flashblocks -X POST -H "Content-Type: application/json" -d '{"jsonrpc":"2.0","method":"eth_getBalance","params":["0x...","pending"],"id":1}'

响应示例

json
{
  "jsonrpc": "2.0",
  "id": 1,
  "result": "0x1234"
}

eth_getTransactionCount#

返回给定地址的交易数量(nonce)。

shell
curl https://rpc.xlayer.tech/flashblocks -X POST -H "Content-Type: application/json" -d '{"jsonrpc":"2.0","method":"eth_getTransactionCount","params":["0x...","pending"],"id":1}'

响应示例

json
{
  "jsonrpc": "2.0",
  "id": 1,
  "result": "0x1b"
}

eth_getCode#

返回部署在给定地址的合约字节码。

shell
curl https://rpc.xlayer.tech/flashblocks -X POST -H "Content-Type: application/json" -d '{"jsonrpc":"2.0","method":"eth_getCode","params":["0x...","pending"],"id":1}'

响应示例

json
{
  "jsonrpc": "2.0",
  "id": 1,
  "result": "0x606060..."
}

eth_getStorageAt#

返回指定地址在给定存储位置的值。

shell
curl https://rpc.xlayer.tech/flashblocks -X POST -H "Content-Type: application/json" -d '{"jsonrpc":"2.0","method":"eth_getStorageAt","params":["0x...","0x0","pending"],"id":1}'

响应示例

json
{
  "jsonrpc": "2.0",
  "id": 1,
  "result": "0x0000000000000000000000000000000000000000000000000000000000000001"
}

eth_getBlockByHash#

根据给定的区块哈希返回对应区块。注意,flashblock 与其对应的规范区块(canonical block)共享相同的区块号,但区块哈希可能不同。

shell
curl https://rpc.xlayer.tech/flashblocks -X POST -H "Content-Type: application/json" -d '{"jsonrpc":"2.0","method":"eth_getBlockByHash","params":["0x...",true],"id":1}'

响应示例

json
{
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    "number": "0x832437",
    "hash": "0x...",
    // ... other fields
    "transactions": ["0x..."]
  }
}

eth_getBlockByNumber#

根据区块号返回对应区块。

shell
curl https://rpc.xlayer.tech/flashblocks -X POST -H "Content-Type: application/json" -d '{"jsonrpc":"2.0","method":"eth_getBlockByNumber","params":["pending",true],"id":1}'

响应示例

json
{
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    "number": "0x832437",
    "hash": "0x...",
    // ... other fields
    "transactions": [{}]
  }
}

eth_getBlockReceipts#

返回指定区块的交易收据。

shell
curl https://rpc.xlayer.tech/flashblocks -X POST -H "Content-Type: application/json" -d '{"jsonrpc":"2.0","method":"eth_getBlockReceipts","params":["pending"],"id":1}'

响应示例

json
{
  "jsonrpc": "2.0",
  "id": 1,
  "result": [
    {
      "transactionHash": "0x...",
      "transactionIndex": "0x0",
      // ... other fields
      "status": "0x1"
    }
  ]
}

eth_getBlockTransactionCountByNumber#

返回指定区块的交易数量。

shell
curl https://rpc.xlayer.tech/flashblocks -X POST -H "Content-Type: application/json" -d '{"jsonrpc":"2.0","method":"eth_getBlockTransactionCountByNumber","params":["pending"],"id":1}'

响应示例

json
{
  "jsonrpc": "2.0",
  "id": 1,
  "result": "0xa"
}

eth_getBlockTransactionCountByHash#

返回给定区块哈希对应区块中的交易数量。

shell
curl https://rpc.xlayer.tech/flashblocks -X POST -H "Content-Type: application/json" -d '{"jsonrpc":"2.0","method":"eth_getBlockTransactionCountByHash","params":["0x..."],"id":1}'

响应示例

json
{
  "jsonrpc": "2.0",
  "id": 1,
  "result": "0xa"
}

eth_getTransactionByHash#

返回给定交易哈希对应的交易数据。

shell
curl https://rpc.xlayer.tech/flashblocks -X POST -H "Content-Type: application/json" -d '{"jsonrpc":"2.0","method":"eth_getTransactionByHash","params":["0x..."],"id":1}'

响应示例

json
{
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    "hash": "0x...",
    "nonce": "0x1",
    // ... other fields
    "s": "0x..."
  }
}

eth_getRawTransactionByHash#

返回给定交易哈希对应的原始交易数据。

shell
curl https://rpc.xlayer.tech/flashblocks -X POST -H "Content-Type: application/json" -d '{"jsonrpc":"2.0","method":"eth_getRawTransactionByHash","params":["0x..."],"id":1}'

响应示例

json
{
  "jsonrpc": "2.0",
  "id": 1,
  "result": "0xf86c018503b9aca008252089400000000000000000000000000000000000000008800de0b6b3a7640000801ba0..."
}

eth_getTransactionReceipt#

返回给定交易哈希对应的交易收据。

shell
curl https://rpc.xlayer.tech/flashblocks -X POST -H "Content-Type: application/json" -d '{"jsonrpc":"2.0","method":"eth_getTransactionReceipt","params":["0x..."],"id":1}'

响应示例

json
{
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    "transactionHash": "0x...",
    "transactionIndex": "0x0",
    // ... other fields
    "status": "0x1"
  }
}

eth_getTransactionByBlockNumberAndIndex#

返回给定区块号和交易索引对应的交易数据。

shell
curl https://rpc.xlayer.tech/flashblocks -X POST -H "Content-Type: application/json" -d '{"jsonrpc":"2.0","method":"eth_getTransactionByBlockNumberAndIndex","params":["pending","0x0"],"id":1}'

响应示例

json
{
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    "hash": "0x...",
    "nonce": "0x1",
    // ... other fields
    "s": "0x..."
  }
}

eth_getTransactionByBlockHashAndIndex#

返回给定区块哈希和交易索引对应的交易数据。

shell
curl https://rpc.xlayer.tech/flashblocks -X POST -H "Content-Type: application/json" -d '{"jsonrpc":"2.0","method":"eth_getTransactionByBlockHashAndIndex","params":["0x...","0x0"],"id":1}'

响应示例

json
{
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    "hash": "0x...",
    "nonce": "0x1",
    // ... other fields
    "s": "0x..."
  }
}

快速开始#

以下库可配合任何已启用 Flashblocks 的 RPC 端点使用。

Viem#

javascript
import { createWalletClient, createPublicClient, http, defineChain } from 'viem';
import { privateKeyToAccount } from 'viem/accounts';
import dotenv from 'dotenv';

dotenv.config();

// TODO: create PR to viem
const xlayerPreconf = defineChain({
    id: 195,
    name: 'X Layer Preconf',
    nativeCurrency: { name: 'OKB', symbol: 'OKB', decimals: 18 },
    rpcUrls: {
        default: { http: ['https://rpc.xlayer.tech/flashblocks'] },
    },
    blockExplorers: {
        default: { name: 'Explorer', url: 'https://www.oklink.com/xlayer-test' },
    },
    testnet: true,
});

const account = privateKeyToAccount(process.env.PRIVATE_KEY);

const walletClient = createWalletClient({
    account,
    chain: xlayerPreconf,
    transport: http('https://rpc.xlayer.tech/flashblocks'),
});

const publicClient = createPublicClient({
    chain: xlayerPreconf,
    transport: http('https://rpc.xlayer.tech/flashblocks'),
});

async function sendTransaction() {
    try {
        const submissionTime = new Date();
        const hash = await walletClient.sendTransaction({
            to: '0x0000000000000000000000000000000000000001',
            value: BigInt('100000000000000'),
        });

        console.log(`Transaction submitted time: ${submissionTime.toISOString()}`);
        console.log(`Transaction hash: ${hash}`);

        let receipt = null;
        while (!receipt) {
            try {
                receipt = await publicClient.getTransactionReceipt({ hash });
            } catch (e) {
                await new Promise(resolve => setTimeout(resolve, 10));
            }
        }

        const confirmationTime = new Date();
        console.log(`Transaction confirmed time: ${confirmationTime.toISOString()}`);
        console.log(`Time difference: ${confirmationTime.getTime() - submissionTime.getTime()}ms`);
    } catch (error) {
        console.error('Error sending transaction:', error);
    }
}

sendTransaction();
// node src/ViemExample.js

Ethers#

javascript
import { ethers } from 'ethers';
import dotenv from 'dotenv';

dotenv.config();

const provider = new ethers.JsonRpcProvider(
    "https://rpc.xlayer.tech/flashblocks"
);

async function sendTransaction() {
    try {
        const tx = {
            to: "0x0000000000000000000000000000000000000001",
            value: ethers.parseEther("0.0000001"),
        };

        // Submit transaction
        const submissionTime = new Date();
        const wallet = new ethers.Wallet(process.env.PRIVATE_KEY, provider);
        const transaction = await wallet.sendTransaction(tx);

        console.log(`Transaction submitted time: ${submissionTime.toISOString()}`);
        console.log(`Transaction hash: ${transaction.hash}`);

        await transaction.wait(0); // Set confirmation count to 0 for flashblocks
        const confirmationTime = new Date();
        console.log(`Transaction confirmed time: ${confirmationTime.toISOString()}`);
        console.log(`Time difference: ${confirmationTime.getTime() - submissionTime.getTime()}ms`);
    } catch (error) {
        console.error('Error sending transaction:', error);
    }
}

sendTransaction();
// node src/EthersExample.js