Web3js:如何在自定义区块链上显示未决交易

Web3js: How to show pending transactions on custom blockchain

我一直致力于自定义本地区块链测试网,并希望在自定义区块浏览器上显示未决交易。 因此,每当来自前端的 GET 请求到达时,api-server(Express) 应该响应未决事务。 我首先尝试使用 web3.ethgetPendingTransactions 方法,但它总是返回一个空数组。

接下来,我尝试使用 web3.eth.subscribe'pendingTransactions' 选项,例如 docs

下面是我试过的代码。

transactionController.js

const Web3 = require("web3");
const web3 = new Web3("ws://192.168.112.82:7001");
var pndTxns = [];

exports.pendingTransactions = (req, res) => {
web3.eth
      .subscribe("pendingTransactions", function (error, result) {
        if (!error) console.log(result);
        console.log(pndTxns);
      })
      .on("data", function (transaction) {
        pndTxns.push(transaction);
}

res.status(200).json({
  success: true,
  txns: pndTxns,
});

(这里,transactionController.js 一个用于未决事务路由器的控制器。) 但是 pndTxns 作为响应总是 returns 并且数组为空,即使 web3.eth.subscribe 中的 pndTxns 存在。

我认为这是因为web3.eth.subscribe实际上与RPC节点建立了一个web socket连接,使得pndTxns无法走出这个方法

最后,我尝试使用 etherjs 模块,如 this blog,下面是代码。

var ethers = require("ethers");
var url = "ws://192.168.112.82:7001";

var init = function () {
  var customWsProvider = new ethers.providers.WebSocketProvider(url);
  
  customWsProvider.on("pending", (tx) => {
    customWsProvider.getTransaction(tx).then(function (transaction) {
      console.log(transaction);
    });
  });

  customWsProvider._websocket.on("error", async () => {
    console.log(`Unable to connect to ${ep.subdomain} retrying in 3s...`);
    setTimeout(init, 3000);
  });
  customWsProvider._websocket.on("close", async (code) => {
    console.log(
      `Connection lost with code ${code}! Attempting reconnect in 3s...`
    );
    customWsProvider._websocket.terminate();
    setTimeout(init, 3000);
  });
};

init();

res.status(200).json({
  success: true,
  txns: pndTxns,
});

我还可以在 init() 函数中看到待处理的交易,但无法发送带有响应的交易。

这里是 init 函数内交易的示例输出。

[
  {
    hash: '0x4c34186e0e6fee5c83406660cf8ef830c36548bb3b8cc14a0fb1eb29fe438331',
    type: 0,
    accessList: null,
    blockHash: '0x000000c9000004c2e8c3585c051b49972b1de6a64c40ce7310a2a994b00483e4',
    blockNumber: 40964,
    transactionIndex: 0,
    confirmations: 1,
    from: '0x8734CB972d36a740Cc983d5515e160C373A4a016',
    gasPrice: BigNumber { _hex: '0x3b9aca00', _isBigNumber: true },
    gasLimit: BigNumber { _hex: '0x5208', _isBigNumber: true },
    to: '0x9651819cfa16c8F3Ba927d5350Ca25417591166B',
    value: BigNumber { _hex: '0x01236efcbcbb340000', _isBigNumber: true },
    nonce: 224,
    data: '0x',
    r: '0xed3d1d5b94a413ce45a06de77851865281cc41c8cdbbcbc4b96356b4d9e49e5c',
    s: '0x2d05d609590c1d5ff7e3ff69111cc6d3caf6f517c2e0229a10de8e938ccee1ba',
    v: 535,
    creates: null,
    chainId: 250,
    wait: [Function (anonymous)]
  }
]

我不在乎你用什么方式,但你能告诉我如何回应待处理的交易吗?

web3.ethgetPendingTransactions 方法 returns 一个空数组,因为它只返回源自您节点上的帐户的交易。这是 the source code(假设你在 Geth)。

您可以使用eth.subscribe获取所有待处理交易:

const Web3 = require('web3');
const url = 'wss://ENDPOINT';
const web3 = new Web3(url);

var options = {
    address: null,
    topics: [
        null
    ]
};

var subscription = web3.eth.subscribe('logs', options, function(error, result){
    if (!error) console.log('got result');
    else console.log(error);
}).on("data", function(log){
    console.log('got data', log);
}).on("changed", function(log){
    console.log('changed');
});

This might be useful too.