Web3.js: methods.call() returns `anonymousFunction()`recursively

Created on 23 Feb 2019  路  6Comments  路  Source: ChainSafe/web3.js

Steps before creating an issue:

  1. on state changing function, I'd like to make a call() first to see what will be returning and only then make a send()
const result = contractInstance.methods[methodName](...funcCallParams).call()

For some reason it doesn't execute and it always returns:

console.log(result)

function anonymousFunction() {
            var methodArguments = Array.prototype.slice.call(arguments);
            if (!isArray(abiItemModel) && abiItemModel.isOfType('constructor')) {
              if (methodArguments[0]['data']) {
                target.contract.options.data = methodArguments[0]['data'];
              }
              if (methodArguments[0]['arguments']) {
                abiItemModel.contractMethodParameters = methodArguments[0]['arguments'];
              }
              return anonymousFunction;
            }
            if (isArray(abiItemModel)) {
              var abiItemModelFound = abiItemModel.some(function (model) {
                model.contractMethodParameters = methodArguments;
                try {
                  model.givenParametersLengthIsValid();
                } catch (error) {
                  return false;
                }
                abiItemModel = model;
                return true;
              });
              if (!abiItemModelFound) {
                throw new Error("Methods with name \"".concat(name, "\" found but the given parameters are wrong"));
              }
              return anonymousFunction;
            }
            abiItemModel.contractMethodParameters = methodArguments;
            return anonymousFunction;
          }

the funny thing if I call the result it will always return same thing, so even if I call
result()()()()() - the outcome is always function anonymousFunction()
-->

Versions

"web3": "^1.0.0-beta.46",

Workaround

  1. generate data with encodeABI()
  2. use web3.eth.call
bug

Most helpful comment

@nivida I use call on state changing methods when I want to get the expected response before executing it. A dry run of a state changing method.

This is a very important use case for us as well.
Since calling the state-changing function incurs costs, we only want to call it if it will actually change the state.

This is the result of a change in one of the recent versions, right @nivida ? In 1.0.0-beta.37 this used to work.

Is there a plan for adding back this functionality?

All 6 comments

Hey,
Thanks for creating this issue!
Could you just for correctness update the issue with the issue template we provide here?

This happens because I'm checking if this is a state changing method or not and will return the correct method then (call/send).
What exactly is the use case for you to call a state-changing method first before you send it?

I am noticing behavior on call() that seems to be related, and I'm working on creating an issue. If I use the call() method repeatedly in sequence such as in a for loop, the call doesn't execute, or it seems to lock up my node tests. Doesn't help if I use a call's callback argument, or use await on a call method, I get same results.

@nivida I use call on state changing methods when I want to get the expected response before executing it. A dry run of a state changing method.

@klivin that's exactly the issue is about. Dry-run of state changing methods

For version 1.0.0.48 I am getting an...

Error Output TypeError: method.call(...).then is not a function

contract.methods.setAllowance(address, qty).call({from: address})
    .then(result => {
    });

The method is a state call with logic - I want to check that no requires are firing prior to a user submitting a send request.

Alternatively utilising the callback functionality results in the callback never returning.

e.g.

contract.methods.setAllowance(address, qty).call({from: address}, (error, result) => {
        // never executed
        console.log("RESULT", result);
        console.log("ERR", error);
    });

@nivida I use call on state changing methods when I want to get the expected response before executing it. A dry run of a state changing method.

This is a very important use case for us as well.
Since calling the state-changing function incurs costs, we only want to call it if it will actually change the state.

This is the result of a change in one of the recent versions, right @nivida ? In 1.0.0-beta.37 this used to work.

Is there a plan for adding back this functionality?

Was this page helpful?
0 / 5 - 0 ratings