Skip to content
This repository has been archived by the owner on Feb 26, 2024. It is now read-only.

Validating the arguments of an overloaded function fails due to having a different number of parameters than the base function #569

Closed
1 task done
GreenFomo opened this issue Sep 14, 2017 · 8 comments
Labels

Comments

@GreenFomo
Copy link


Issue

As the title says, attempting to call an overloaded function from e.g. a JS test fails, since the validation for the number of function parameters fails, not taking into account that there might be 2 functions with the same name.

Steps to Reproduce

In a contract:

function theFn(string p1) {}

function theFn(string p1, string p2) {}

In a test:
instance.theFn.call('first param', 'second param')

will fail, since the validator in cli.bundled.js (see full stacktrace below) doesn't take into account that there could be multiple functions with the same name, but different number of parameters.

It's important to call the function that is defined last, that's the one ignored by the validator (calling the first version of the function, with only 1 param, works fine).

Expected Behavior

I would expect to be able to call an overloaded function from js tests, since it's valid Solidity.

Actual Results

 Error: Invalid number of arguments to Solidity function
      at Object.InvalidNumberOfSolidityArgs (/usr/lib/node_modules/truffle/build/cli.bundled.js:37282:16)
      at SolidityFunction.validateArgs (/usr/lib/node_modules/truffle/build/cli.bundled.js:223127:22)
      at SolidityFunction.toPayload (/usr/lib/node_modules/truffle/build/cli.bundled.js:223143:10)
      at SolidityFunction.call (/usr/lib/node_modules/truffle/build/cli.bundled.js:223184:24)
      at /usr/lib/node_modules/truffle/build/cli.bundled.js:212184:16
      at Promise (<anonymous>)
      at /usr/lib/node_modules/truffle/build/cli.bundled.js:212175:18
      at <anonymous>
      at process._tickCallback (internal/process/next_tick.js:188:7)

Environment

  • Operating System: CentOS 7
  • Truffle version: v3.4.9
  • Ethereum client: EthereumJS TestRPC v4.1.1 (ganache-core: 1.1.2)
  • node version: v8.4.0
  • npm version: 5.3.0
@tcoulter tcoulter added the bug label Sep 15, 2017
markspanbroek added a commit to sustainablesource/sustainablesource that referenced this issue Sep 16, 2017
@wphan
Copy link

wphan commented Sep 28, 2017

Ran into this issue while testing an implementation of ERC223 which overloads transfer() from ERC20.

@rudolfix
Copy link

I fixed this in our truffle fork here
Neufund/truffle-contract@ecae099
You call overloaded functions web3 style

const tx = await token.transfer["address,uint256,bytes"](address, initialBalance, data, { from: fromAddr });

I can provide PR to truffle-contract if maintainers are interested

@elenadimitrova
Copy link

I'm sure maintainers @tcoulter and @gnidan would be interested in a PR @rudolfix :)

@rudolfix
Copy link

rudolfix commented Nov 18, 2017

@DeRain
Copy link

DeRain commented Dec 19, 2017

As an option, we could call overloaded methods via web3 directly, i've created an article with details https://beresnev.pro/test-overloaded-solidity-functions-via-truffle/

@MidnightLightning
Copy link

MidnightLightning commented Feb 7, 2018

It's important to call the function that is defined last

No, that's not how the function "overloading" works in Solidity; it's not that the last-defined function with that name is the "real" one, but rather all functions with the same name are valid, if they have different input parameters.

From the example in the original post, if a contract has the functions:

function theFn(string p1);
function theFn(string p1, string p2);

The ABI would include something like:

[
  {
    name: 'theFn',
    type: 'function',
    inputs: [
      { "name": "p1", "type": "string" }
    ]
  },
  {
    name: 'theFn',
    type: 'function',
    inputs: [
      { "name": "p1", "type": "string" },
      { "name": "p2", "type": "string" }
    ]
  }
]

It would be valid to call either function, since the signature for the two is different (theFn(string) vs. theFn(string,string), which when hashed to get a ).

In this case, the Truffle testing infrastructure needs to know how to parse out:

instance.theFn.call('first param', 'second param'); // call theFn(string,string)
instance.theFn.call('first param'); // call theFn(string)
instance.theFn.call('first param', { from: accounts[3] }); // call theFn(string), using account[3]
instance.theFn.call('first param', 'second param', { from: accounts[3] }); // call theFn(string,string), using account[3]

Done this way, it would need to do some introspection on the last argument given, to see if it's an options object or some other type of input.

Looks like pull requests 75 and 94 do account for this need with two separate (but compatible options), so looks like they are correct, even though this original issue's requested resolution is not the way Solidity handles the situation.

@MartinKral
Copy link

instance.theFn.call('first param', 'second param'); // call theFn(string,string)
instance.theFn.call('first param'); // call theFn(string)

How would I call a function overload with the same number of parameters, but different types (string and uint)?

bingen pushed a commit to aragon/aragonOS that referenced this issue Apr 25, 2018
jenncoop added a commit to fission-codes/fission-translate that referenced this issue Sep 25, 2018
@gnidan
Copy link
Contributor

gnidan commented Jan 9, 2019

Closing this, as Truffle v4 basically had no support for overloaded functions. This is now resolved in Truffle v5. Please see the v5 release notes about overloaded functions. Thanks!

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

No branches or pull requests

9 participants