2

Testing on TestRPC, when trying to pass an array parameter to a contract function during

truffle migrate --reset

I've been getting the following error:

Unhandled promise rejection (rejection id: 2): Error: Invalid number of arguments to Solidity function

In an attempt to hunt down the culprit I have made a toy example, amending the original /contracts/MetaCoin.sol example by removing any ConvertLib reference and adding an initialize function which accepts a uint[] parameter:

contract MetaCoin {
   mapping (address => uint) balances;
   uint testArraySum;

   event Transfer(address indexed _from, address indexed _to, uint256 _value);

   function MetaCoin() {
       balances[tx.origin] = 10000;

   }

   function initialize(uint[] _test_array) returns(bool){
      for(uint i = 0; i < _test_array.length; i++) {
         testArraySum += _test_array[i];
      }
      return true;
   }

   function sendCoin(address receiver, uint amount) returns(bool sufficient) {
       if (balances[msg.sender] < amount) return false;
       balances[msg.sender] -= amount;
       balances[receiver] += amount;
       Transfer(msg.sender, receiver, amount);
       return true;
   }
   function getBalance(address addr) returns(uint) {
       return balances[addr];
   }
}

The above has been successfully compiled with

truffle compile

For simplicity, I have also removed the migrations contract and written the following deployment script in /migrations/2_deploy_contracts.js:

   var MetaCoin = artifacts.require("./MetaCoin.sol");
   module.exports = function(deployer, network) {
     var metaCoin;

     if (network == 'development') {
       metaCoin = {
         address : '0xa8e055d89579a74b0110728a740e18e80c44e211',
         test_array : [web3.toBigNumber(3).valueOf(), web3.toBigNumber(3).valueOf(), web3.toBigNumber(3).valueOf()]
       };
     } else if (network == "ropsten") { // ropsten testnet
     } else if (network == "rinkeby") { // rinkeby testnet
     } else if (network == "live") {
       throw "error: deployment for live network is not yet supported";
     }

     var mPromise = MetaCoin.at(metaCoin.address).then(function (exiM) {
       console.log('Found existing MetaCoin contract at ' + exiM.address);
       return Promise.resolve(exiM);
     });

     mPromise.then(function (m) {
       console.log('MetaCoin contract at ' + m.address);
       return m.initialize(metaCoin.test_array);
     }).catch(function (err) {
       if (err.message && err.message.includes('Cannot create instance of')) {
         console.log('Deploying new MetaCoin contract');
         MetaCoin.new().then(function (newM) {
           console.log('Deployed new MetaCoin contract at ' + newM.address);
           console.log(JSON.stringify(metaCoin.test_array));
           return newM.initialize(metaCoin.test_array);
         });
       } else {
         console.error(err);
         return Promise.resolve(null);
       }
     });
  };

Yet, even in this simplest of examples the error still persists no matter how I declare the test array or format the fields.

Continuing my search I ran across this related issue on github: https://github.com/trufflesuite/truffle/issues/526 Where they conclude that this is an issue of web3 as of v0.19

Version Information -

MacOS Sierra v10.12.6

Truffle v3.4.9

Solidity v0.4.15

EthereumJS TestRPC v4.1.1

Web3js v0.20.1

Node v6.11.2

Any workaround or solution would be greatly appreciated!

  • The whole example looks bizzare, like some copy-pasted code with lot's of unneeded lines. My suggestion is to make it as small as possible, it will be easier to find an error. – Lukasz Zuchowski Sep 8 '17 at 7:54
1

I created new project with truffle init. Pasted your metacoin file and migration file and it works fine.

stack1$ truffle deploy
Compiling ./contracts/ConvertLib.sol...
Compiling ./contracts/MetaCoin.sol...
Compiling ./contracts/Migrations.sol...
Writing artifacts to ./build/contracts

Using network 'development'.

Running migration: 1_initial_migration.js
  Deploying Migrations...
  Migrations: 0x8d2fc79377f2e736bfe606ab5cf1a4d6a9b98d3f
Saving successful migration to network...
Saving artifacts...
Running migration: 2_deploy_contracts.js
Saving successful migration to network...
Deploying new MetaCoin contract
Saving artifacts...
Deployed new MetaCoin contract at 0x39a59797ea58d98055cd719470285554cb164580
["3","3","3"]
  1. You have code trying to fetch contract from blockchain, are you sure that you are working with your test RPC? Maybe you are calling old version of metacoin from test or live network? Try to deploy the contract first and remove/comment out code that tries to fetch it.
  2. Did you try to call that function in test instead of migration?
  3. Maybe it would be better to pass the parameter thru constructor instead of "initialize" function (I know that just example, so maybe this point is inaccurate). e.g. deployer.deploy(MetaCoint, myArray);
  4. return exiM would be enough here return Promise.resolve(exiM);
| improve this answer | |
0
test_array : [web3.toBigNumber(3).valueOf(), web3.toBigNumber(3).valueOf(), web3.toBigNumber(3).valueOf()]

Try passing big numbers as strings.

| improve this answer | |
  • Is this just for this example? strings are expensive(with regards to gas) right? – Vignesh Karthikeyan Jun 8 '18 at 18:43
  • 1
    If your contract expects large numbers, truffle will internally convert the strings to numbers for you. So you don't have to change anything in your contract, and it won't be any more expensive. – Nikita Fuchs Jun 9 '18 at 8:45

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.