4

Following this tutorial on writing a voting contract and deploying on testrpc I created the below js code into voting.js and ran it by:

> node
> require('./voting.js');

After printing web3.isConnected() in some places it seems that after requiring the solc package the connection looses. Any idea why? how to solve?

voting.js:

Web3 = require('web3');
web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545"));
console.log(web3.eth.accounts);
console.log(web3.isConnected());

fs = require('fs');
console.log(web3.isConnected());
code = fs.readFileSync('Voting.sol').toString();
console.log(web3.isConnected());

solc = require('solc');
console.log(web3.isConnected());
compiledCode = solc.compile(code);

console.log(web3.isConnected());

abiDefinition = JSON.parse(compiledCode.contracts['Voting'].interface);
byteCode = compiledCode.contracts['Voting'].bytecode;

console.log(web3.isConnected());
VotingContract = web3.eth.contract(abiDefinition);
console.log(web3.isConnected());
deployedContract = VotingContract.new(['Rama','Nick','Jose'],{data: byteCode, from: web3.eth.accounts[0], gas: 4700000});
console.log(deployedContract.address);
contractInstance = VotingContract.at(deployedContract.address);

contractInstance.totalVotesFor.call('Rama');

The output:

> node
> require('./voting.js');
[ '0xabefa5873fe5c980a2b7ffe84a6726386a1c6c3a',
  '0xe4bf2c9df073808c187066adac463f2b2a4a3847',
  '0x49d61cad7ad214f968a4d5b402e936aa3eef1ef5',
  '0xbb3ae1453c1c843f28952611c3948691376003bc',
  '0xb57b5c0f2ec7869c2371831c11a4d1f8c54086bb',
  '0xb14fad57e7ab17d378499e8aa0f2bbefa9f70344',
  '0xc911f8c0f1d2e2e4a08d0c5eaf3390d54cb6ce93',
  '0x6ee5769268c665f0c9541ecd0216041af111dced',
  '0x79a88a34d78151d9d79b997b51f14ea4211faacd',
  '0x8a287c6e4407ed53723cc9cde6741125efdbc8ba' ]
true
true
true
false
false
false
false
Error: CONNECTION ERROR: Couldn't connect to node http://localhost:8545.
    at Object.InvalidConnection (/home/bush/hello_world_voting/node_modules/web3/lib/web3/errors.js:31:16)
    at HttpProvider.send (/home/bush/hello_world_voting/node_modules/web3/lib/web3/httpprovider.js:83:22)
    at RequestManager.send (/home/bush/hello_world_voting/node_modules/web3/lib/web3/requestmanager.js:58:32)
    at Eth.get [as accounts] (/home/bush/hello_world_voting/node_modules/web3/lib/web3/property.js:107:62)
    at Object.<anonymous> (/home/bush/hello_world_voting/voting.js:24:93)
    at Module._compile (module.js:570:32)
    at Object.Module._extensions..js (module.js:579:10)
    at Module.load (module.js:487:32)
    at tryModuleLoad (module.js:446:12)
    at Function.Module._load (module.js:438:3)
> 
5

I can confirm that requiring 'solc' causes the connection to TestRPC to drop. I have not investigated why, but a workaround is to avoid requiring 'solc' in your current node console session by compiling the contract and writing it to a file before starting your console session.

Run compile.js at the command line with: ~$ node compile.js before requiring voting.js in your node console.

File contents:

compile.js


solc = require('solc');
fs = require('fs');

code = fs.readFileSync('Voting.sol').toString();
compiledCode = solc.compile(code);
fs.writeFileSync("./Voting.compiled", JSON.stringify(compiledCode), 'utf-8');


voting.js


Web3 = require('web3');
web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545"));
console.log(web3.eth.accounts);

compiledCode = JSON.parse(fs.readFileSync("./Voting.compiled").toString());

abiDefinition = JSON.parse(compiledCode.contracts[':Voting'].interface);
VotingContract = web3.eth.contract(abiDefinition);
byteCode = compiledCode.contracts[':Voting'].bytecode;

deployedContract = VotingContract.new(['Rama', 'Nick', 'Jose'], 
        {   data: byteCode,
            from: web3.eth.accounts[0],
             gas: 4700000,
        });



setTimeout(
    function(){
        console.log(deployedContract.address);
        contractInstance = VotingContract.at(deployedContract.address);
        console.log(contractInstance.address);
        console.log(contractInstance.totalVotesFor.call('Rama'));
}, 3000);



Note: You have to wait for VotingContract.new to return before you can set contractInstance, or else it will be undefined. I therefore wrap it in a setTimeout that waits three seconds, plenty of time for VotingContract to return after submitting the contract to your TestRPC server. This is not usually best practice for dealing with asynchronous functions, but satisfies the requirements for the demo with the minimal amount of rewriting and additional packages.

1
  • Why did you put ':' before Voting in compiledCode.contracts[':Voting'].interface? (it throws an exception that it doesn't know such object. Also - missing fs = require("fs"); at the beginning of voting.js
    – Bush
    Jul 15 '17 at 11:08

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.