4
var source = fs.readFileSync("./vote.sol", "utf-8")
var compiled = web3.eth.compile.solidity(source);
var abi = compiled.identify.info.abiDefinition;
var Vote = web3.eth.contract(abi);
var ContractManager = Vote.at(contractAddress);
var csv = "a,string,like,this,";
ContractManager.voteNow.sendTransaction(csv, { from: web3.eth.accounts[0], value: 10000000 });

The voteNow function expects a string as its input.


Error: Invalid address length, expected 40 got 160 bytes
    at Object.module.exports.InvalidResponse (node_modules/web3/lib/web3/errors.js:35:16)
    at RequestManager.send (node_modules/web3/lib/web3/requestmanager.js:61:22)
    at Eth.send [as sendTransaction] (node_modules/web3/lib/web3/method.js:145:58)
    at SolidityFunction.sendTransaction (node_modules/web3/lib/web3/function.js:133:26)

Here is the solidty function:

 event Broadcast(string x,string s1, string s2);

 function voteNow(string vote){
        Broadcast('voteLog','New vote','sender,vote');
        Broadcast('voteLog',toString(msg.sender),vote);

    }
 function toString(address x) returns (string) {
        bytes memory b = new bytes(20);
        for (uint i = 0; i < 20; i++)
            b[i] = byte(uint8(uint(x) / (2**(8*(19 - i)))));
        return string(b);
    }
5
  • 1
    Looks like the function you're calling expects an address, not a string. Without the contract source code, no one will be able to help much more than that. Sep 19, 2016 at 0:51
  • Thanks. Did not consider it could be something in the contract for some reason. I've added the contract source code. Sep 19, 2016 at 23:47
  • There doesn't look to be anything wrong with the contract. That leaves the contractAddress variable. Mind posting that? Sep 20, 2016 at 2:01
  • The contents of contractAddress: 0x908b362fbe19299486ab240e7647f1dbb13c37ff Sep 20, 2016 at 22:49
  • Did you manage to find a solution for this issue? I have a similar issue to what you experienced, expect that I get an error of 'expected 40 got 46 bytes', but cannot find the reason for this error. Any help will be much appreciated
    – poenie123
    Nov 21, 2016 at 11:03

2 Answers 2

0

Here is my solution and it works:

pragma solidity ^0.4.24;

contract Vote {

    event Broadcast(string x, string s1, string s2);

    function voteNow(string vote) public {
        emit Broadcast('voteLog', toString(msg.sender), vote);
    }

    function toString(address x) public pure returns (string) {
        bytes memory b = new bytes(20);
        for (uint i = 0; i < 20; i++)
            b[i] = byte(uint8(uint(x) / (2**(8*(19 - i)))));
        return string(b);
    }

}

2_deploy_contracts.js migration file:

var colors = require('colors');

var Vote = artifacts.require('Vote');

module.exports = function (deployer, network, accounts) {
  return deployer.deploy(Vote)
    .then(function(contract) {
        console.log("Contract address: " + colors.green(contract.address));

        return contract.voteNow("Sending string to deployed contract function", {
            from: accounts[0],
        });
    }).then((tx) => {
        console.log(tx);
    });
}

truffle.js configuration file to demonstrate on locale Ganache and Ropsten testnet:

//module.paths.push('.../node_modules/');

var Web3 = require("web3");
var ethereumjsWallet = require('ethereumjs-wallet');

var ProviderEngine = require("web3-provider-engine");
var FilterSubprovider = require('web3-provider-engine/subproviders/filters.js');
var WalletSubprovider = require('web3-provider-engine/subproviders/wallet.js');
var InfuraSubprovider = require("web3-provider-engine/subproviders/infura.js");

var colors = require('colors');

var privateKey = '[your private key here for ropsten testnet]';

// create wallet from existing private key
console.log("Wallet creating...");
var wallet = ethereumjsWallet.fromPrivateKey(new Buffer(privateKey, "hex"));
var address = "0x" + wallet.getAddress().toString("hex");
console.log("Wallet address:", colors.yellow(address));

var engineRopsten = new ProviderEngine();

// filters
engineRopsten.addProvider(new FilterSubprovider());
engineRopsten.addProvider(new WalletSubprovider(wallet, {}));
engineRopsten.addProvider(new InfuraSubprovider({network: 'ropsten'}));
engineRopsten.start(); // Required by the provider engine.

module.exports = {
  /*solc: {
    optimizer: {
      enabled: true,
      runs: 200
    }
  },*/
  networks: {
    development: {
      host: '127.0.0.1',
      port: 8545,
      network_id: '5777',
      gas: 8000000,
      gasPrice: 20000000000 // 20 gwei
    },
    ropsten: {
        network_id: 3,
        provider: engineRopsten,      // Use our custom provider
        from: address,         // Use the address we derived
        gas: 4700000,
        gasPrice: 50000000000 // 50 gwei
    }
  }
}

To run scripts just call in CLI:

truffle.cmd migrate --network development --reset

or

truffle.cmd migrate --network ropsten --reset

Here is an example of the separate script (run.js):

//module.paths.push('.../node_modules/');

var fs = require("fs");
var Web3 = require("web3");
var colors = require("colors");

const web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545"));

let contractAddress = '[address of deployed contract]';

let abi = JSON.parse(
    fs.readFileSync("./build/contracts/Vote.json", "utf-8")
).abi;
contract = new web3.eth.Contract(abi, contractAddress);

(async () => {
  const accounts = await web3.eth.getAccounts();

  contract.methods.voteNow("Sending string to deployed contract function").send({
      from: accounts[0]
  })
  .on('transactionHash', function(hash){
      console.log("transactionHash:", colors.yellow(hash))
  })
  .on('confirmation', function(confirmationNumber, receipt){
      console.log("   confirmation #", colors.green(confirmationNumber))
  })
  .on('receipt', function(receipt){
      console.log("receipt", receipt);
  })
  .on('error', function(err) {
      console.log("error:", colors.red(err.toString()))
  });
})();
0

it seems only a little parameter you should modify.

you are passing the entire csv string as the first argument to the voteNow function, which is causing the sendTransaction method to treat it as an address instead of a string.

To fix this error, you will need to modify your code so that the csv string is passed as the second argument to the voteNow function, rather than the first. You can do this by changing the following line:

ContractManager.voteNow.sendTransaction(csv, { from: web3.eth.accounts[0], value: 10000000 });

To this:

ContractManager.voteNow.sendTransaction('voteLog', csv, { from: web3.eth.accounts[0], value: 10000000 });

pls have a try, if it's helpful to u.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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