Skip to content
This repository has been archived by the owner on Mar 5, 2025. It is now read-only.

"Error: Invalid number of arguments to Solidity function" when including callback #1471

Closed
wbt opened this issue Mar 16, 2018 · 1 comment
Closed

Comments

@wbt
Copy link
Contributor

wbt commented Mar 16, 2018

Summary

According to the official web3 documentation, contract.myMethod(param1, param2, callback) should asynchronously execute contract.myMethod(param1, param2) and send callback (a function) either an error or a transaction object. However, the callback function is getting interpreted as another argument to the Solidity function, resulting in the error Invalid number of arguments to Solidity function.

Steps to Reproduce

The following code is within a truffle project and run with truffle migrate.
The actual and expected behavior are described in comments near the end.
This is with Truffle v4.0.4 (core: 4.0.4) and Solidity v0.4.18 (solc-js) on Windows 10.
I tested with web3 0.20.0 and 0.20.6 (the latest release).

contracts/Recorder.sol:

pragma solidity ^0.4.0;
contract Recorder {
    uint public score;
    string public name;
    function updateRecord (uint newScore, string newName) public {
        score = newScore;
        name = newName;
    }
}

migrations/1_initial_migration.js:

var Migrations = artifacts.require("./Migrations.sol");
module.exports = function(deployer) {
    deployer.deploy(Migrations);
};

migrations/2_deploy_contract.js:

var Recorder = artifacts.require("./Recorder.sol");
module.exports = function(deployer) {
    deployer.deploy(Recorder);
};

migrations/3_show_bug.js:

var Recorder = artifacts.require("./Recorder.sol");
var Web3 = require('web3');

module.exports = function(deployer) {
    var recorder;
    Recorder.deployed()
    .then(function(instance) {
        recorder = instance;
        console.log("Contract deployed at "+recorder.address);
        var web3 = new Web3(deployer.provider);
        console.log("Web3 version: "+web3.version.api);
        //Demonstrating that synchronous methods work without error:
        return recorder.updateRecord(45, "Alice");
    }).then(function(transaction) {
        console.log("Record updated in transaction "+transaction.tx+
        " with status "+transaction.receipt.status); //status is 0x01
        return recorder.name.call();
    }).then(function(name) {
        //Prints "Name is Alice.":
        console.log("Name is "+name+".");
        return recorder.score.call();
    }).then(function(score) {
        //Prints "Score is 45.":
        console.log("Score is "+score+".");
        //Attempting an asynchronous method results in an error.
        return recorder.updateRecord(51, "Bob", function(error, transaction) {
            //This code is never reached, but is expected to be reached:
            console.log("Callback function after transaction sent.");
        });
    }).catch(function(error) {
        //Prints "Error: Invalid number of arguments to Solidity function"
        //but is not expected to be reached:
        console.log("Error: "+error.message);
    })
};

This might be related to #1043.

@wbt
Copy link
Contributor Author

wbt commented Mar 20, 2018

This issue is caused by what may be a common source of confusion: recorder is a TruffleContract rather than a web3 contract.

The shortest diff is to change the line which does the function call from

return recorder.updateRecord(51, "Bob", function(error, transaction) {

to

return recorder.contract.updateRecord(51, "Bob", Recorder.defaults(), function(error, transaction) {

where the .contract bit gets a simpler contract object for use in web3 and the .defaults() bit is needed to have a valid from address and other default transaction parameters.

Documentation on this could probably be improved.

@wbt wbt closed this as completed Mar 20, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant