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

Call with blockTag property fails #329

Closed
elenadimitrova opened this issue Nov 3, 2018 · 13 comments
Closed

Call with blockTag property fails #329

elenadimitrova opened this issue Nov 3, 2018 · 13 comments
Labels
discussion Questions, feedback and general information.

Comments

@elenadimitrova
Copy link

Using the blockTag option as specified in #226 (comment) (sorry I didn't find any other reference documentation)
contract.method.call(param1, param2, { blockTag: blockNumber });
Where blockNumber is either "latest" or a specific block number value.

The above call fails with
Error: invalid input argument (arg="_id", reason="invalid number value", value={"blockTag":"latest"}, version=4.0.7)

@ricmoo
Copy link
Member

ricmoo commented Nov 3, 2018

Heya!

Can you provide a code snippet?

If you are using the call directly, I think you may be using the JavaScript Function.prototype.call, which requires the first parameter to set this.

I think you likely just want: contract.method(param1, param2, { blockTag: blockNumber }); (less the .call).

Anyways, just my first thought, please feel free to include a code snippet and I'll look at it further. :)

@ricmoo ricmoo added the discussion Questions, feedback and general information. label Nov 3, 2018
@elenadimitrova
Copy link
Author

Hi @ricmoo !
the .call is on the ethers.Contract method call where {blocktag} is passed in. I was reading the logic as only available for read calls and not transactions. I tried removing .call() and got this error below which seems to confirm the above:

     Error: unknown transaction override blockTag
      at Contract.getReputationUpdateLogEntry (node_modules/ethers/contracts/contract.js:83:27)
      at ReputationMiner._callee2$ (packages/reputation-miner/ReputationMiner.js:117:41)

The original source I test with and well as code snippet below
JoinColony/colonyNetwork@f48f77e#diff-9c228e1a1f7fe6683164300c770b62ffR117

this.provider = new ethers.providers.JsonRpcProvider(`http://localhost:8545`);
this.signer = this.provider.getSigner(accounts[0]);

this.myContractDef = await this.loader.load({ contractName: "IReputationMiningCycle" }, { abi: true, address: false });
const myContract = new ethers.Contract(myAddress, this.myContractDef.abi, this.signer);
myContractDef.someMethod.call({blockTag: X})

@elenadimitrova
Copy link
Author

Some additional troubleshooting shows this happens when the method called has input parameters, e.g.
works: myContractDef.someMethod.call({blockTag: X})
fails: myContractDef.someMethod.call(someParam1, {blockTag: X})

@ricmoo
Copy link
Member

ricmoo commented Nov 5, 2018

Oh, so the Call vs. Transaction behaviour is based on the ABI, so there is no way to “call” a state-changing method (there is a tricky way; in the ABI set constant to true, but often this will not actually be what you want to do, since calling a state-changing transaction method will do odd things, and may depend on the node you are connected to).

You can not override the block number of a transaction though. It is useful to do this for call, since you might be curious, for example, of the balance of an ERC-20 contract at a specific block height. But a transaction MUST occur at the height it is mined in. It cannot be overridden. Also note, even in the call case, the node can only satisfy correct results if it is non-pruning, which is often not the case.

Make sense?

Also, keep in mind in your last example, the call you are calling has nothing to do with ethers.js. There is no call property I set. You are calling the native implementation of JavaScript call, passing in a non-instance to be used as this, so things will likely explode... :s

@ricmoo
Copy link
Member

ricmoo commented Nov 5, 2018

For more information on the Function.prototype.call method:

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/call

@elenadimitrova
Copy link
Author

I am simply interacting with a view function on the contract at a specific block number rather than make a state changing transaction call. The above examples of invoking someMethod on ethers.Contract myContractDef are just that. If I remove the .call() on them I get a

Error: unknown transaction override blockTag
      at Contract.getReputationUpdateLogLength (node_modules/ethers/contracts/contract.js:83:27)

@ricmoo
Copy link
Member

ricmoo commented Nov 5, 2018

Oh! Ok, so you are calling a view function? Sorry, I misread the above.

That should work then. What version are you using of ethers? console.log(ethers.version)

@elenadimitrova
Copy link
Author

4.0.7
Interestingly I just switched the property from blockTag to blockNumber like this myContractDef.someMethod({blockNumber: X}) and that tests ok. Did I simply get the property name wrong?

@ricmoo
Copy link
Member

ricmoo commented Nov 5, 2018

That is super strange... I'm at a McDonald's in Prague post DevCon, but have switched to a laptop (from my iPhone) so I can respond with more meaningful responses and include code as needed... I'm looking into this more now. Feel free to jump onto gitter too, if you want more real-time interactivity. :)

@ricmoo
Copy link
Member

ricmoo commented Nov 5, 2018

Can you also try blowing away the build directory and re-building? Sometimes Truffle and company use old binary code, or don't update the address properly.

@ricmoo
Copy link
Member

ricmoo commented Nov 5, 2018

It is definitely blockTag. I'm very confused as to why it is doing that... Here is the relevant code in Contract:

https://github.com/ethers-io/ethers.js/blob/master/src.ts/contract.ts#L159

It makes a copy of the overrides, and if blockTag exists, copies it out and deletes it from the overrides, then checks the overrides for bad keys, which is where your error comes from... It shouldn't be able to get there with that key...

@elenadimitrova
Copy link
Author

After more testing blockTag is indeed correct so closing this. For future reference there is a problem when passing no value in but still setting it to the property like { blockTag: undefined } leading to Error: unknown transaction override blockTag

@ricmoo
Copy link
Member

ricmoo commented Nov 8, 2018

Excellent point! I have added a fix for when using an explicit { blockTag: undefined }.

Thanks! :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
discussion Questions, feedback and general information.
Projects
None yet
Development

No branches or pull requests

2 participants