web3.eth.abi.decodeLog returns incorrect log parameter values
Asked Answered
C

1

5

I have an Ethereum contract with an event defined like so:

event Apple(address indexed a, address b, address c);

The event is fired and I can see the log in the transaction receipt.

Via web3, when I attempt to parse the logs from the receipt, I am able to retrieve the event parameters, but it looks like the value of a is always the same.

// compiled is the built contract. address is the contract address
const contract = new web3.eth.Contract(compiled.abi, address)

const eventJsonInterface = _.find(
  contract._jsonInterface,
  o => o.name === 'Apple' && o.type === 'event',
)

const log = _.find(
    receipt.logs,
    l => l.topics.includes(eventJsonInterface.signature)
)

web3.eth.abi.decodeLog(eventJsonInterface.inputs, log.data, log.topics)

What I end up with is:

Result {
  '0': '0x42087b16F33E688a9e73BFeef94F8F2bd2BfC98f',
  '1': '0xfc36bFe712f30F75DF0BA9A60A109Ad51ac7Ca38',
  '2': '0x6915d2f3D512F7CfEF968f653D1cA3ed4489798C',
  __length__: 3,
  a: '0x42087b16F33E688a9e73BFeef94F8F2bd2BfC98f',
  b: '0xfc36bFe712f30F75DF0BA9A60A109Ad51ac7Ca38',
  c: '0x6915d2f3D512F7CfEF968f653D1cA3ed4489798C' }

where a is always the same address across events that are fired. I'm generating a new contract with each transaction, and a is the address of this new contract (which I have verified to be correct by firing a separate event from the generated contract that also emits the value of a), so the resolved value of a for event Apple is definitely incorrect.

Has anyone run into this before?

I am using web3 1.0.0-beta.33

Comforter answered 11/5, 2018 at 0:27 Comment(1)
Can you share the code that emits the event?Moussorgsky
C
6

After looking at the web3 docs more closely, I realized that when you use decodeLog, you must not pass the encoded name of the event in the array of topics. I believe non-anonymous events have the event name as the first item in the topics array.

From https://web3js.readthedocs.io/en/1.0/web3-eth-abi.html#decodelog:

topics - Array: An array with the index parameter topics of the log, without the topic[0] if its a non-anonymous event, otherwise with topic[0].

It sounds like the topics passed should only reference indexed parameters. After I sliced topic[0], I started getting the correct results.

// compiled is the built contract. address is the contract address
const contract = new web3.eth.Contract(compiled.abi, address)

const eventJsonInterface = _.find(
  contract._jsonInterface,
  o => o.name === 'Apple' && o.type === 'event',
)

const log = _.find(
  receipt.logs,
  l => l.topics.includes(eventJsonInterface.signature)
)

web3.eth.abi.decodeLog(eventJsonInterface.inputs, log.data, log.topics.slice(1))
Comforter answered 13/6, 2018 at 21:43 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.