Replies: 4 comments 2 replies
-
I once did a hacky way for the same. Copy-pasting it here function removeNumericKeysFromStruct(inputStruct: ethers.utils.Result) {
const returnObj: { [key: string]: any } = {};
Object.entries(inputStruct)
.filter((entry, i) => {
if (entry[0] === 'length') return false;
if (entry[0] === String(i)) return false;
return true;
})
.forEach((entry) => (returnObj[entry[0]] = entry[1]));
return returnObj;
} |
Beta Was this translation helpful? Give feedback.
-
Oh I just recalled that there's a catch to it. If you have a event or function with a unnamed output parameter e.g.: event Hello(bytes2 config, bytes2, bytes2 payload);
function hello() public view returns (bytes2 config, bytes2, bytes2 payload); It will generate:
So removing the numeric keys would cause you to lose that parameter. So, that needs an approach that involves checking out @ricmoo I'd like to ask if ethers js should return a default name like |
Beta Was this translation helpful? Give feedback.
-
Thanks @zemse. There are a few things to note here. First, the result object is actually an Array. If you use All values are always available as their positional arguments. Only if an argument is named is it available as a named argument. So, it is in general far less safe to rely on named values since they are optional. My first question would be why you want to remove the Array indexed elements, there may be another way to do what you are trying. But if you genuinely want to pull these out, like @zemse pointed out, you would need to decide what to do with unnamed properties. It actually quite hard to come up with a generic solution that doesn't just end up in a cascade of escapes. For example, what if there was an arg called If this is something you need to do, you will likely need to turn to the ABI to extract these out, using a const data = '0x00000000000000000000000000000000000000000000000000000000000004d20000000000000000000000000000000000000000000000000000000000000001'
const iface = new ethers.utils.Interface([
"function foo() view returns (uint256 value, bool)"
])
const result = iface.decodeFunctionResult("foo", data);
// This has your numbered elements 0 and 1
console.log(result);
/*
[
BigNumber { _hex: '0x04d2', _isBigNumber: true },
true,
value: BigNumber { _hex: '0x04d2', _isBigNumber: true }
]
*/
// Get the ABI fragment which knows the named elements...
const fragment = iface.getFunction("foo");
// Reduce the elements out
const onlyNamedResult = result.reduce((accum, value, index) => {
let name = fragment.outputs[index].name;
if (name == null) {
// Whatever you want to do here? Let's use zemse's idea
name = "arg" + String(index);
}
accum[name] = value;
return accum;
}, { });
console.log(onlyNamedResult);
/*
{
value: BigNumber { _hex: '0x04d2', _isBigNumber: true },
arg1: true
}
*/ Does that help? At least help explain why there are positional elements in the first place? :) |
Beta Was this translation helpful? Give feedback.
-
(also, moving to discussions ;)) |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
-
After I do the decoding, let's say
decodeFunctionData
or any other decoding, The result seems to be something like this:As shown,
0
key data corresponds toconfig
and1
corresponds topayload
.Is there any way that decoding doesn't add numbered keys such as
0
,1
and so on ?Thank you.
Beta Was this translation helpful? Give feedback.
All reactions