EOSIO / eosjs

General purpose library for the EOSIO blockchain.
http://eosio.github.io/eosjs
MIT License
1.43k stars 463 forks source link

Bug? action struct missmatch. #349

Closed ghost closed 6 years ago

ghost commented 6 years ago

When calling an action eosjs searches the abi for a matching struct. But it should search for a struc by action.type instead, not action .name. Most of the time the matching struct has the same name as the action so then its not a problem but when reusing structs in different actions it is a problem. image So I'm calling "stprofileuns" action and eosjs complains that it can't find a struct with name "stprofileuns"... image As you can see in the abi, eosjs doesn't use the action.type for finding the correct struct.

nsjames commented 6 years ago

It seems this is happening inside of Scatter on this line:

https://github.com/GetScatter/ScatterDesktop/blob/master/src/plugins/defaults/eos.js#L310

Which only calls does

const data = abi.fromBuffer(action.name, action.data);

The action.name consoles out to stprofileuns and the data in this instance is 00000000001aa36a0477686174. It seems to not be able to convert it properly.

ghost commented 6 years ago

yes scatter related I'll close the issue...

jcalfee commented 6 years ago

When calling an action eosjs searches the abi for a matching struct. But it should search for a struc by action.type instead, not action .name. Most of the time the matching struct has the same name as the action so then its not a problem but when reusing structs in different actions it is a problem.

Other way around. The action name is like the exposed API action name and needs to a valid name (12 in length or shorter). The type is the internal struct that tells it how to serialize.

Is abi.fromBuffer the eos.fc.fromBuffer? @nsjames You need to figure out the type behind the name for the fromBuffer function.

nsjames commented 6 years ago

It would be (await eos.contract(contractAccount)).fc;

I'm trying something like this now

const typeName = abi.abi.actions.find(x => x.name === action.name).type;
const struct= abi.structs[typeName];

But don't really see a way to deserialize that from that struct object.

I'll have to keep messing around with it, but it's 100% on my side. I'm surprised this has never come up before.

nsjames commented 6 years ago

Nevermind, I'm being ridiculous.

const typeName = abi.abi.actions.find(x => x.name === action.name).type;
const data = abi.fromBuffer(typeName, action.data);

Pushing a fix soon.