Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

JS ABI Issue #182

Closed
joeykrug opened this issue Apr 23, 2015 · 18 comments
Closed

JS ABI Issue #182

joeykrug opened this issue Apr 23, 2015 · 18 comments

Comments

@joeykrug
Copy link

Take the following contract for example:

def createMarket(events:arr): return(events[0]

Its address is bf1f9a04cb5c85e9538a6f0e6ba15c824808cfee
And its description is:

[{ "name": "createMarket(int256[])", "type": "function", "inputs": [{ "name": "events", "type": "int256[]" }], "outputs": [{ "name": "out", "type": "int256" }] }]

If called in the web3.js console, e.g.

> contract.call({"from": eth.coinbase}).createMarket([-2333333333333333333333333333333333333333333333333332222222222233]).toNumber();```   it'll return ```-2.3333333333333333e+63

which is the correct value.

Now if we use this contract:

def createMarket(branch, description:str, alpha, initialLiquidity, tradingFee, events:arr): return(events[0])

with address 0xe95aa1829447058201872db6ae3f04c3785a05b0
And description:

[{ "name": "createMarket(int256,string,int256,int256,int256,int256[])", "type": "function", "inputs": [{ "name": "branch", "type": "int256" }, { "name": "description", "type": "bytes" }, { "name": "alpha", "type": "int256" }, { "name": "initialLiquidity", "type": "int256" }, { "name": "tradingFee", "type": "int256" }, { "name": "events", "type": "int256[]" }], "outputs": [{ "name": "out", "type": "int256" }] }]

We end up getting completely wrong responses:

> contract.call({"from": eth.coinbase}).createMarket(2, "ok", 2, 2, 2, [444]).toNumber();
0
> contract.call({"from": eth.coinbase}).createMarket(2, "ok", 2, 2, 2, [-371]).toNumber();
65535
> contract.call({"from": eth.coinbase}).createMarket(2, "ok", 2, 2, 2, [371]).toNumber();
0
> contract.call({"from": eth.coinbase}).createMarket(2, "ok", 2, 2, 2, [-37117353667364131058659323780745282444029701754006041568106926382588839136039]).toNumber();
44528
> contract.call({"from": eth.coinbase}).createMarket(2, "ok", 2, 2, 2, [-4443434345]).toNumber();
65535

Edit: now contract.foo().call() is returning

error: could not decode, json: cannot unmarshal array into Go value of type struct { From string; To string; Value interface {}; Gas interface {}; GasPrice interface {}; Data string }
@frozeman
Copy link
Contributor

i reformatted you issue it was unreadable. ;)
Btw what kind of contract language you use?

@frozeman
Copy link
Contributor

web3.js contracts are solely for solidity at the moment and the contracts you're showing there are either incomplete or no solidity contracts i guess.

@joeykrug
Copy link
Author

Oh yes it's a serpent contract ---

Any reason it's giving this error?
error: could not decode, json: cannot unmarshal array into Go value of type struct

Even with a solidity contract that takes an array as a parameter it gives me that error when trying to call contract

@frozeman
Copy link
Contributor

the problem is, i have without line numbers no way to tell where this error is generated.

@joeykrug
Copy link
Author

Latest output it gives:

> contract.createMarket.call([3])

error: could not decode, json: cannot unmarshal array into Go value of type struct { From string; To string; Value interface {}; Gas interface {}; GasPrice interface {}; Data string }

Invalid JSON RPC response at InvalidResponse (<anonymous>:-14377:-32) at send (<anonymous>:-29300:-32) at call (<anonymous>:-27355:-32) at call (<anonymous>:-23992:-32) at <anonymous>:1:1

@obscuren
Copy link
Contributor

The calls generate very odd output. The eth_call or eth_transact look like [[0xaaadress]] which fails in decoding. It expects [{"to":...,"from":..., etc}]

@debris
Copy link
Contributor

debris commented Apr 26, 2015

1

[{ "name": "createMarket(int256,string,int256,int256,int256,int256[])", "type": "function", "inputs": [{ "name": "branch", "type": "int256" }, { "name": "description", "type": "bytes" }, { "name": "alpha", "type": "int256" }, { "name": "initialLiquidity", "type": "int256" }, { "name": "tradingFee", "type": "int256" }, { "name": "events", "type": "int256[]" }], "outputs": [{ "name": "out", "type": "int256" }] }]

that's not correct. should be

- [{ "name": "createMarket(int256,string,int256,int256,int256,int256[])", "type": "function", "inputs": [{ "name": "branch", "type": "int256" }, { "name": "description", "type": "bytes" }, { "name": "alpha", "type": "int256" }, { "name": "initialLiquidity", "type": "int256" }, { "name": "tradingFee", "type": "int256" }, { "name": "events", "type": "int256[]" }], "outputs": [{ "name": "out", "type": "int256" }] }]
+ [{ "name": "createMarket(int256,bytes,int256,int256,int256,int256[])", "type": "function", "inputs": [{ "name": "branch", "type": "int256" }, { "name": "description", "type": "bytes" }, { "name": "alpha", "type": "int256" }, { "name": "initialLiquidity", "type": "int256" }, { "name": "tradingFee", "type": "int256" }, { "name": "events", "type": "int256[]" }], "outputs": [{ "name": "out", "type": "int256" }] }]

name of the function is used to generate function sha3. It cannot be string any more. Use bytes instead. Or even bytes32.

2

parsing input should be ok. But just to be 100% sure, I've created test for encoding your input params:

test({ types: ['int', 'bytes', 'int', 'int', 'int', 'int[]'], values: [1, 'gavofyork', 2, 3, 4, [5, 6, 7]],
                                                            expected: '0000000000000000000000000000000000000000000000000000000000000009' +
                                                                      '0000000000000000000000000000000000000000000000000000000000000003' +
                                                                      '0000000000000000000000000000000000000000000000000000000000000001' +
                                                                      '0000000000000000000000000000000000000000000000000000000000000002' +
                                                                      '0000000000000000000000000000000000000000000000000000000000000003' +
                                                                      '0000000000000000000000000000000000000000000000000000000000000004' +
                                                                      '6761766f66796f726b0000000000000000000000000000000000000000000000' +
                                                                      '0000000000000000000000000000000000000000000000000000000000000005' +
                                                                      '0000000000000000000000000000000000000000000000000000000000000006' +
                                                                      '0000000000000000000000000000000000000000000000000000000000000007'});

3

Latest output it gives:

contract.createMarket.call([3])

You are right. I fixed it in latest web3.js develop. Here is test

Thanks for reporting it, cause it was critical.

@chriseth
Copy link
Contributor

Does this really work? The expectation should be
1 9 2 3 4 3 676176... 5 6 7
If this still causes problems, it would be another point in favour for moving to the new ABI proposal: https://github.com/ethereum/wiki/wiki/Proposal-for-new-ABI-value-encoding

@debris
Copy link
Contributor

debris commented Apr 26, 2015

@chriseth why 1 9 2 3 4 3 676176... 5 6 7 ?

I though length of dynamic params, should be always at the beginning. Look at sam example

@debris
Copy link
Contributor

debris commented Apr 26, 2015

also, I though that constants should be before dynamic contents, #85

@debris
Copy link
Contributor

debris commented Apr 26, 2015

btw. the proposal looks good, but it would be nice, to have 2-3 examples of encoding to clarify everything.

@chriseth
Copy link
Contributor

The examples on the wiki page of the specification seem to contradict the specification itself.
I hope that the new proposal does not need examples for clarification, only for illustration :-)

@joeykrug
Copy link
Author

Hmmm when i call a contract, getting a different error now
contract.double({from: eth.coinbase}).call(1010101)

new BigNumber() not a number: [object Object]

Nvm, was using wrong syntax

contract.getCreator.call(1010101, {from: eth.coinbase}): is proper syntax

@frozeman
Copy link
Contributor

yes ;)

@chriseth
Copy link
Contributor

Actually, I looked at the sam example again at it does not contradict the specification because all of its parameters are dynamic.

@debris
Copy link
Contributor

debris commented Apr 28, 2015

I fixed old encoding/decoding in #187. @chriseth can you verify that this tests for encoding and decoding are correct?

@debris
Copy link
Contributor

debris commented May 5, 2015

fixed in #187

@ethers
Copy link
Contributor

ethers commented May 7, 2015

update: this is changing / being fixed in #194

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants