1

I have a smart contract that produces NFTs and emits an event when contract is created.

The definition of the event is:

event NewBKNFT(address indexed contractAddress, address indexed publisherAddress, string indexed name);

I use the ethers decoder to attempt to read the logs emitted by the contract:

let newContractFilter =   bkNFTRoot.filters.NewBKNFT(bknft.address,null, null);
let result = await bkNFTRoot.queryFilter(newContractFilter,0,"latest");
let log = result[0].topics
console.log(log);
let decoder = new ethers.utils.AbiCoder();
let conAddress = decoder.decode(["address"], log[1])[0];
let pubAddress = decoder.decode(["address"], log[2])[0];
let name = decoder.decode(["string"], log[3])[0]; //. <--Error occurs here.
expect(conAddress).eq(bknft.address);
expect(pubAddress).eq(publisherAddress);
expect(name).eq("Magic 8 Ball");

I am able to read the contractAddress value and the publisherAddress value from the event topics with no problem, but the decoder fails trying to decode log[3], which is the "name" part of the event - a string.

Here is the error I am seeing:

 Error: overflow [ See: https://links.ethers.org/v5-errors-NUMERIC_FAULT-overflow ] (fault="overflow", operation="toNumber", value="46239361996083819174354556831166659296979034097517641541041899128465208372197", code=NUMERIC_FAULT, version=bignumber/5.7.0)
      at Logger.makeError (node_modules/@ethersproject/logger/src.ts/index.ts:269:28)
      at Logger.throwError (node_modules/@ethersproject/logger/src.ts/index.ts:281:20)

The actual value inside the 4th topic (logs[3]) is:

 '0x663a8d2b32866266f0828e488189bba07604c87e1084d49c67a027c77853ebe5'

What should be in there is some encoding of the string "Magic 8 Ball".

Any ideas what I am doing wrong?


EDIT: In case anybody else runs into this sort of problem, the solution is not to index the string property, but to emit in the data.

This works as expected with this event def:

event NewBKNFT(address indexed contractAddress, address indexed publisherAddress, string name);
let newContractFilter =   bkNFTRoot.filters.NewBKNFT(bknft.address,null, null);
        let result = await bkNFTRoot.queryFilter(newContractFilter,0,"latest");
        let log = result[0].topics
        let decoder = new ethers.utils.AbiCoder();
        let conAddress = decoder.decode(["address"], log[1])[0];
        let pubAddress = decoder.decode(["address"], log[2])[0];
        let data = result[0].data;
        let name = decoder.decode(["string"],data)[0];
        expect(conAddress).eq(bknft.address);
        expect(pubAddress).eq(publisherAddress);
        expect(name).eq("Magic 8 Ball");

1 Answer 1

1

The way I see it is that decoder.decode is just moving a hex to a string.. that is what is stored in there..

Edit edit edit

The string stored in there is a keccak has of the string you provided to the event.. so you can't actually decode it..

Read this

I suggest you compare like this

Expect(keccak256("your string").to.equal(log[0])

Sorry for the blunt answer, I'm commuting; I'll edit later

3
  • Blunt is no problem. I see now that the value returned is the keccak of "Magic 8 Ball" so I guess that's right. But the example here: docs.ethers.org/v5/api/utils/abi/coder (see abi.decoder section) seems to suggest that decode returns the actual value supplied to the event not just the hash of it. Is there no way to emit an unhashed string in the event log or derive the original value? Its no particular help just to get the hash, I'd have to call the contract to get the name which was what I was trying to avoid by putting the name in the log.
    – GGizmos
    Jan 8 at 4:24
  • I haven't done a lot of research but I can thing of a few workarounds.. like storing the string in a mapping (bytes32 => string) whereas you calc the hash and store it along with the string itself... So later you can read it.. not optimal but a workaround
    – Casareafer
    Jan 9 at 5:35
  • 1
    Thanks @casareafer. I think the answer is just not to index the string event param. In which case it wont be hashed and can be read from the data (not the topics) of the event as shown above.
    – GGizmos
    Jan 9 at 18:07

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.