【问题标题】:Ethereum/BSC blockchain transaction data以太坊/BSC 区块链交易数据
【发布时间】:2021-07-27 06:11:10
【问题描述】:

我正在尝试通过 Binance Smart Chain 区块链使用 web3js,但在理解交易数据时遇到了困难。

查看example 的此交易,有三个交易转移(代币转移),大多数时候有两个(到目前为止,我已经看到了 2、3 和 5)。 我不明白是什么决定了单笔交易的转账次数。以及如何使用 web3js 检索该数据。

如果交易是关于出售代币而不是购买,我想知道在该交易中支付的 BNB 金额和收到的代币数量,反之亦然。

我设法获得了支付的价格和代币数量,但仅适用于有 2 次代币转移的交易。但如果有 3 个或更多,我无法获取此信息。

web3.eth.getTransaction('0x899e7f3c2138d051eb5246850ded99d519ab65eba58e5f806245cf346ab40e83').then((result) => {
  console.log(result)
  console.log(web3.utils.fromWei(result.value))

  let tx_data = result.input;
  let input_data = '0x' + tx_data.slice(10);  // get only data without function selector

  let params = web3.eth.abi.decodeParameters([
      {
        indexed: false,
        internalType: 'uint256',
        name: 'value',
        type: 'uint256'
      },
      {
        indexed: false,
        internalType: 'uint256',
        name: 'ethReceived',
        type: 'uint256'
      },
    ]
    , input_data);
  console.log(params)

})

这部分代码只为我提供了 2 次令牌传输的数据。无论交易中有多少笔转账,如何让它始终向我退还已支付/收到的现金/代币的金额?可能吗??从我所看到的情况来看,交易中的第一次转账和最后一次转账将是我感兴趣的值。有没有简单的方法来获得这些值?我正在努力理解这一点并使用 ABI 进行解码。它们可以有点通用吗??

【问题讨论】:

    标签: blockchain ethereum web3 web3js binance


    【解决方案1】:

    “转移的令牌”信息来自事件日志。大多数令牌标准都定义了一个事件Transfer(address indexed from, address indexed to, uint256 value),因此您可以在事务中查找此事件的日志。

    getTransactionReceipt() 中提供了事件日志,而不是常规的 getTransaction()

    事件定义中的indexed 修饰符意味着该值将在topics 属性中可用(topics[0] 是事件签名的 keccak256 散列,位于索引值之后)。然后将“未索引”值存储在 data 属性中 - 根据它们的定义顺序排序。

    const transferEventSignature = web3.utils.keccak256('Transfer(address,address,uint256)'); // 0xddf252...
    const jsonAbi = [{
        "constant" :true,
        "inputs": [],
        "name": "decimals",
        "outputs": [{"name":"","type":"uint8"}],
        "type": "function"
    }]; // simplified JSON abi that is only able to read decimals
    
    web3.eth.getTransactionReceipt('0x899e7f3c2138d051eb5246850ded99d519ab65eba58e5f806245cf346ab40e83').then(async (result) => {
        for (const log of result.logs) {
            if (log.topics[0] !== transferEventSignature) {
                continue; // only interested in Transfer events
            }
    
            const from = web3.eth.abi.decodeParameter('address', log.topics[1]);
            const to = web3.eth.abi.decodeParameter('address', log.topics[2]);
            const value = web3.eth.abi.decodeParameter('uint256', log.data);
            const tokenContractAddress = log.address;
    
            const contractInstance = new web3.eth.Contract(jsonAbi, tokenContractAddress);
            const decimals = await contractInstance.methods.decimals().call();
    
            console.log('From: ', from);
            console.log('To: ', to);
            console.log('Value: ', value);
            console.log('Token contract: ', tokenContractAddress);
            console.log('Token decimals: ', decimals);
            console.log('---');
        }
    });
    

    输出:

    From:  0xC6A93610eCa5509E66f9B2a95A5ed1d576cC9b7d
    To:  0xE437fFf464c6FF2AA5aD5c15B4CCAD98DF38cF52
    Value:  31596864050517135
    Token contract:  0x78F1A99238109C4B834Ac100d1dfCf14e3fC321C
    Token decimals:  9
    ---
    From:  0xE437fFf464c6FF2AA5aD5c15B4CCAD98DF38cF52
    To:  0x58F876857a02D6762E0101bb5C46A8c1ED44Dc16
    Value:  4064578781674512
    Token contract:  0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c
    Token decimals:  18
    ---
    From:  0x58F876857a02D6762E0101bb5C46A8c1ED44Dc16
    To:  0xC6A93610eCa5509E66f9B2a95A5ed1d576cC9b7d
    Value:  2552379452401563824
    Token contract:  0xe9e7CEA3DedcA5984780Bafc599bD69ADd087D56
    Token decimals:  18
    

    注意:一些令牌实现是不正确的(即不遵循令牌标准)并且没有将事件参数标记为indexed。在这种情况下,topics[0] 仍然相同,但地址 fromto 不存在于 topics 中,但您必须从 data 字段中解析它们。 address 的长度为 64 个十六进制字符(在实际的 40 个字符地址前添加零)。

    【讨论】:

      猜你喜欢
      • 2019-12-09
      • 2022-07-19
      • 2018-11-04
      • 2017-08-07
      • 2019-01-24
      • 1970-01-01
      • 2018-06-23
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多