wealdtech / ethereal

Apache License 2.0
209 stars 41 forks source link

How to read from contract? #36

Closed danimesq closed 2 years ago

danimesq commented 2 years ago

Should use "send" or "call"?

Sample contract:

https://etherscan.io/readContract?m=normal&a=0x3f8c2152b79276b78315caf66ccf951780580a8a&v=0x3f8c2152b79276b78315caf66ccf951780580a8a#readCollapse11

tokenOfOwnerByIndex | |- owner (address) (I've put 0xDDfC2e10702d8A781727A34D83B3bb3CA94a3E91) |- index (uint256) (I've put 0)

Result is the NFT ID I hold, in uint256: 7

@wealdtech How to do the same but, instead of Etherscan using ethereal? And how to parse NFT IDs of an ETH address that holds more than one NFT of same contract (eg. owning multiple Axies, CryptoKitties or Expansion Punks)? Have tried with Axie Infinity (using tokenOfOwnerByIndex and the same 0xDDfC2e10702d8A781727A34D83B3bb3CA94a3E91 and 0) and all it returns for my ETH address is 142388. BTW, Rockstars of EPNS is ERC-721 and Axie is ERC-20 but there should have a common pattern.

mcdee commented 2 years ago

This is not an ethereal question, pleas ask in a solidity support channel.

danimesq commented 2 years ago

This is not an ethereal question, pleas ask in a solidity support channel.

Sorry for the long description in the issue; others complain how short they are so I should review how to balance.

But yes: this question is related to ethereal-specific functionality.

The README.md's have a short explanation on writing to contracts (which here is better explained), but not much about reading.

When I try:

ethereal contract call --contract=0x3f8C2152b79276b78315CAF66cCF951780580A8a --call='tokenOfOwnerByIndex("0xDDfC2e10702d8A781727A34D83B3bb3CA94a3E91")' --from=0xDDfC2e10702d8A781727A34D83B3bb3CA94a3E91

Output:

Failed to parse call: unknown method name tokenOfOwnerByIndex Does it also requires providing an ABI for reading a known function?

danimesq commented 2 years ago

Successfully got its ABI from Etherscan, inserted into the --abi=abi.json and now it progresses. But:

ethereal contract call --contract=0x3f8C2152b79276b78315CAF66cCF951780580A8a --abi=abi.json --call='tokenOfOwnerByIndex("0xDDfC2e10702d8A781727A34D83B3bb3CA94a3E91")' --from=0xDDfC2e10702d8A781727A34D83B3bb3CA94a3E91

As expected, results in:

Failed to convert arguments: argument count mismatch: got 1 for 2

This is expected as I don't know how to properly format it and I saw no example in the README.md

But when I do what it is asking to:

ethereal contract call --contract=0x3f8C2152b79276b78315CAF66cCF951780580A8a --abi=abi.json --call='tokenOfOwnerByIndex("0xDDfC2e10702d8A781727A34D83B3bb3CA94a3E91","0")' --from=0xDDfC2e10702d8A781727A34D83B3bb3CA94a3E91

Results in:

Failed to convert arguments: abi: cannot use string as type array as argument

Even using a proper formatting with a simpler method (balanceOf instead of tokenOfOwnerByIndex):

ethereal contract call --contract=0x3f8C2152b79276b78315CAF66cCF951780580A8a --abi=abi.json --call='balanceOf("0xDDfC2e10702d8A781727A34D83B3bb3CA94a3E91")' --from=0xDDfC2e10702d8A781727A34D83B3bb3CA94a3E91

Outputs the same as previously:

Failed to convert arguments: abi: cannot use string as type array as argument

danimesq commented 2 years ago

Progress

Removed the quotes and now it worked:

ethereal contract call --contract=0x3f8C2152b79276b78315CAF66cCF951780580A8a --abi=abi.json --call='balanceOf(0xDDfC2e10702d8A781727A34D83B3bb3CA94a3E91)' --from=0xDDfC2e10702d8A781727A34D83B3bb3CA94a3E91

Output:

[1]

The more complex call also works:

ethereal contract call --contract=0x3f8C2152b79276b78315CAF66cCF951780580A8a --abi=abi.json --call='tokenOfOwnerByIndex(0xDDfC2e10702d8A781727A34D83B3bb3CA94a3E91,0)' --from=0xDDfC2e10702d8A781727A34D83B3bb3CA94a3E91

Output:

[7]

I'll test it with other contracts. Possibly the same ABI could be re-used as an universal template at other contracts. Edit: confirmed; could re-use the Rockstars of EPNS ABI (ERC-721) into Axie Infinity (ERC-20).

danimesq commented 2 years ago

@wealdtech, there's a issue which may be of the program or of my formatting:

ethereal contract call --contract=0xf5b0a3efb8e8e4c201e2a935f110eaaf3ffecb8d --abi=abi-axie.json --call='tokenURI(142388)' --from=0xDDfC2e10702d8A781727A34D83B3bb3CA94a3E91

Output:

panic: interface conversion: interface {} is []interface {}, not string

goroutine 1 [running]: github.com/wealdtech/ethereal/cmd.contractValueToString(0x0, 0x0, 0x3, 0xc000554e48, 0x6, 0x0, 0x0, 0x0, 0x0, 0x0, ...) /go/src/github.com/wealdtech/ethereal/cmd/contract.go:185 +0x14ad github.com/wealdtech/ethereal/cmd.glob..func8(0x212ec80, 0xc0000464c0, 0x0, 0x4) /go/src/github.com/wealdtech/ethereal/cmd/contractcall.go:119 +0xfdc github.com/spf13/cobra.(Command).execute(0x212ec80, 0xc000046480, 0x4, 0x4, 0x212ec80, 0xc000046480) /go/pkg/mod/github.com/spf13/cobra@v1.1.1/command.go:854 +0x2aa github.com/spf13/cobra.(Command).ExecuteC(0x213ac20, 0x4436fa, 0x21611c0, 0xc000000180) /go/pkg/mod/github.com/spf13/cobra@v1.1.1/command.go:958 +0x349 github.com/spf13/cobra.(*Command).Execute(...) /go/pkg/mod/github.com/spf13/cobra@v1.1.1/command.go:895 github.com/wealdtech/ethereal/cmd.Execute() /go/src/github.com/wealdtech/ethereal/cmd/root.go:301 +0x31 main.main() /go/src/github.com/wealdtech/ethereal/main.go:19 +0x20

I used the same formatting before and it has worked, but not now.

danimesq commented 2 years ago

Issue from the latest comment: https://github.com/wealdtech/ethereal/issues/37