NodeJS 如何使用Web3.js从交易回单中读取Event日志?

bprjcwpo  于 2022-12-29  发布在  Node.js
关注(0)|答案(5)|浏览(527)

我已经在我的solidity项目中实现了函数,它记录了一些事件,事件名称为“NewRound”,我希望在发送交易后从中获取值,并保存在我的集中式数据库中,我收到了如下所示的收据。

{
  blockHash: '0x8df078a04e47cbe4ea7e58626ffc894f0d7b2620e821f9432aa1c03b3431d480',
  blockNumber: 19125457,
  contractAddress: null,
  cumulativeGasUsed: 995561,
  from: '0x0c46c078196461b17f7e1e652004bd7ee448ed49',
  gasUsed: 116384,
  logs: [
    {
      address: '0xc032d238fd4deD8A8AB97a8983AE3B51ccfa8fd3',
      topics: [Array],
      data: '0x',
      blockNumber: 19125457,
      transactionHash: '0x1e13744ddaf81cb3ca7a9cbd98ca6b2ede51a22d7e2795305b2621d59a0b9ac1',
      transactionIndex: 5,
      blockHash: '0x8df078a04e47cbe4ea7e58626ffc894f0d7b2620e821f9432aa1c03b3431d480',
      logIndex: 7,
      removed: false,
      id: 'log_301e03cb'
    }
  ],
  logsBloom: '0x00000000000000000000000000000000000000000000000000000000000000000000000000003000000000000000000000040000800000000020000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000',
  status: true,
  to: '0xc032d238fd4ded8a8ab97a8983ae3b51ccfa8fd3',
  transactionHash: '0x1e13744ddaf81cb3ca7a9cbd98ca6b2ede51a22d7e2795305b2621d59a0b9ac1',
  transactionIndex: 5,
  type: '0x0'
}

我的日志数据在主题参数中。但是我不知道如何解码它。有人做过这样的事情吗?
我的活动数据。

r8xiu3jd

r8xiu3jd1#

topics[0]字段总是存储事件签名散列,它是事件名称的keccak-256散列,后面是括号中的参数数据类型。
在您的示例中,这是字符串NewRound(uint256)的散列。
topics数组的以下项是事件的索引参数。最后一项是所有未索引参数的连接(这不适用于您的情况,因为没有未索引参数)。
这些项目为ABI encoded,以十六进制表示。
假设您有发出事件的契约的ABI JSON,那么您可以使用web3.eth.abi.decodeLog()函数解码值。

gmxoilav

gmxoilav2#

This library对于解码交易收据日志非常有帮助。只需要手动加载合同ABI并使用提供的对象进行解码

2ul0zpep

2ul0zpep3#

data字段将包含给定事件的所有未索引参数。要对其进行解码,可以使用web3.eth.abi.decodeLog(inputs, hexString, topics),如here所示。
您可以从字段topics的第一个元素(即topics[0])中获取事件的名称。此处的第一个元素对应于事件签名的keccak256。web3.utils.sha3(string)可用于散列您的事件签名,以检查topics数组的第一个条目是否匹配。此处提供更多信息。
如果事件具有索引参数,则可以从topics数组的其余条目中找到这些参数。要将其转换为人类可读的形式,请按照与解码data字段中的元素相同的步骤操作。

unftdfkk

unftdfkk4#

来源:https://community.infura.io/t/web3-js-how-to-track-nft-erc-721-1155-transfers-and-mints-specific-address-nft/5500
ERC1155的实施示例:

...
const contract = new web3.eth.Contract(ABI_ARRAY, "0xContractAddress");

let events = await cont.get("0x1e13744ddaf81cb3ca7a9cbd98ca6b2ede51a22d7e2795305b2621d59a0b9ac1")
//or

let events = await contract.getPastEvents(...); // -> you have your response like this
/*
{
  blockHash: '0x8df078a04e47cbe4ea7e58626ffc894f0d7b2620e821f9432aa1c03b3431d480',
  blockNumber: 19125457,
  contractAddress: null,
  cumulativeGasUsed: 995561,
  from: '0x0c46c078196461b17f7e1e652004bd7ee448ed49',
  gasUsed: 116384,
  logs: [
    {
      address: '0xc032d238fd4deD8A8AB97a8983AE3B51ccfa8fd3',
      topics: [Array],
      data: '0x',
      blockNumber: 19125457,
      transactionHash: '0x1e13744ddaf81cb3ca7a9cbd98ca6b2ede51a22d7e2795305b2621d59a0b9ac1',
      transactionIndex: 5,
      blockHash: '0x8df078a04e47cbe4ea7e58626ffc894f0d7b2620e821f9432aa1c03b3431d480',
      logIndex: 7,
      removed: false,
      id: 'log_301e03cb'
    }
  ],
  logsBloom: '0x00000000000000000000000000000000000000000000000000000000000000000000000000003000000000000000000000040000800000000020000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000',
  status: true,
  to: '0xc032d238fd4ded8a8ab97a8983ae3b51ccfa8fd3',
  transactionHash: '0x1e13744ddaf81cb3ca7a9cbd98ca6b2ede51a22d7e2795305b2621d59a0b9ac1',
  transactionIndex: 5,
  type: '0x0'
}
*/

let transaction = web3.eth.abi.decodeLog(
    [
        {
            type: "address",
            name: "operator",
            indexed: true,
        },
        {
            type: "address",
            name: "from",
            indexed: true,
        },
        {
            type: "address",
            name: "to",
            indexed: true,
        },
        {
            type: "uint256",
            name: "id",
        },
        {
            type: "uint256",
            name: "value",
        },
    ],
    events.logs.data,
    [events.logs.topics[1], events.logs.topics[2], events.logs.topics[3]]
);

console.log(
    `\n` +
        `New ERC-1155 transaction found in block ${events.logs.blockNumber} with hash ${event.logs.transactionHash}\n` +
        `Operator: ${transaction.operator}\n` +
        `From: ${
            transaction.from === "0x0000000000000000000000000000000000000000"
                ? "New mint!"
                : transaction.from
        }\n` +
        `To: ${transaction.to}\n` +
        `id: ${transaction.id}\n` +
        `value: ${transaction.value}`
);

对于ERC721最后一部分:

let transaction = web3.eth.abi.decodeLog(
    [
        {
            type: "address",
            name: "from",
            indexed: true,
        },
        {
            type: "address",
            name: "to",
            indexed: true,
        },
        {
            type: "uint256",
            name: "tokenId",
            indexed: true,
        },
    ],
    events.log.data,
    events.log.topics
);

console.log(
    `\n` +
        `New ERC-712 transaction found in block ${events.log.blockNumber} with hash ${events.log.transactionHash}\n` +
        `From: ${
            transaction.from ===
            "0x0000000000000000000000000000000000000000"
                ? "New mint!"
                : transaction.from
        }\n` +
        `To: ${transaction.to}\n` +
        `Token contract: ${events.log.address}\n` +
        `Token ID: ${transaction.tokenId}`
);

问候

jm81lzqq

jm81lzqq5#

对于非匿名(大多数情况下)事件,用途:

const decoded = web3.eth.abi.decodeLog(EVENT_ABI, event.data, event.topics.slice(1));
console.log(decoded);

否则,用途:

const decoded = web3.eth.abi.decodeLog(EVENT_ABI, event.data, event.topics);
console.log(decoded);

完整示例:

const TOPIC = web3.eth.abi.encodeEventSignature('Event(uint256,bytes32)');
const EVENT_ABI = []; // your event ABI here 

const subscription = web3.eth.subscribe("logs", { topics: [TOPIC] });
subscription.on("data", (event) => { 
  const decoded = web3.eth.abi.decodeLog(EVENT_ABI, event.data, 
  event.topics.slice(1));
  console.log(decoded);

} );

相关问题