2

I am trying to deploy a contract on testrpc using web3.js,

  1. contract deploys fine when I deploy it from remix, it uses roughly the same amount of gas as the estimate.

  2. However, when I try to deploy the same contract using web3.js, I keep running into "out of gas" error, even though I am supplying 5x the gas estimate.

I am obviously making some mistake in my deployment script...but I have gone over the script and can't spot the problem....some help from a knowing hand would be much appreciated

let source = fs.readFileSync('./xyz.sol', 'utf8');
    let compiledContract = solc.compile(source, 1);
    let abi = compiledContract.contracts[':Xyz'].interface;
    let bytecode = compiledContract.contracts[':Xyz'].bytecode; 

    let bContract = new web3.eth.contract(JSON.parse(abi));

    let gasEstimate = web3.eth.estimateGas({data : bytecode});
    console.log(`GASESTIMATE : ${gasEstimate}`);  // <------------ returns value 120000

    let deployData = bContract.new.getData(name, choices, closesOn, min, {  data : bytecode, });

    let rawTx = {
        from: runENV.acctAddr,
        nonce: web3.toHex(web3.eth.getTransactionCount(runENV.acctAddr)),
        gasPrice: web3.toHex(web3.eth.gasPrice),
        gasLimit: web3.toHex(5*gasEstimate), // <------------- giving 5x gasestimate
        data: deployData,
    }

    let tx = new Tx(rawTx);
    tx.sign(runENV.privateKeyBuffer);

    let serialzedTx = tx.serialize().toString('hex');

    web3.eth.sendRawTransaction( '0x' + serialzedTx, (err, res) => {
            if(err) { console.log(`Error  - ${err}`); } 
            else { console.log(`Xyz contract deployed successfully ${res}`);     }
        }
    );
3
  • 1
    You didn't say what you're using for a chain, e.g. ganache-cli, private chain using geth version x, or the version of solidity you use to compile the contract. There is a compatibility matrix issue because protocol changes (Byzantium) mean you can't just use any-to-any. Also, the contract constructor could be a factor. Commented Sep 6, 2018 at 19:59
  • I mentioned it in the first line, sorry it was obscured by later stuff, I am trying to deploy it locally on ganache...I get the same error when deploying it on rinkeby. BTW I can deploy to both of these successfully if I do the deployment directly from remix....which is why i think the problem is in my code
    – satyendra
    Commented Sep 6, 2018 at 20:26
  • Finally figured this out after three days of trying everything....wish we had a little better documentation. Looks like this was caused by some compatibility issues between compiler and the blockchain...instead of using solc/solcjs to compile the code, I took the bytecode from remix and pasted that into my code...and boom everything works. Thanks to Rob Hitchins from B9lab for poitning out that there might be a compatibility issue.
    – satyendra
    Commented Sep 7, 2018 at 17:37

1 Answer 1

1

A common problem I used to have is that the bytecode needs to be prefixed by '0x'.

I've used this code to deploy a simple contract to a local ganache instance using web3 v1.0

const Web3 = require('web3');
const solc = require('solc');

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

const recipientSource = `
pragma solidity ^0.4.20;
contract Recipient {
  uint public id;
  function deposit(uint _id) public payable {
    id = _id;
  }
}`;

function compileContract(source, name) {
  const result = solc.compile(source, 1);
  const compiled = result.contracts[`:${name}`];
  return compiled;
}

async function deployQueryContract() {
  const compiled = compileContract(recipientSource, 'Recipient');

  const accounts = await web3.eth.personal.getAccounts();

  const Recipient = new web3.eth.Contract(JSON.parse(compiled.interface));

  const toDeploy =  Recipient.deploy({
    data: `0x${compiled.bytecode}`
  });

  const gas = await toDeploy.estimateGas();

  console.log(`Gas: ${gas}`);

  const recipient = await toDeploy.send({
    from: accounts[0],
    gas: `0x${gas.toString(16)}`,
    gasPrice: '30000000000'
  });

  console.log(`Deployed at: ${recipient.options.address}`);
  console.log(`ABI: ${compiled.interface}`);

  await recipient.methods.deposit(4321)
  .send({
    from: accounts[0],
    value: 1000
  });

  const result = await recipient.methods.id().call();
  console.log(`Result: ${result}`);
}

deployQueryContract();

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.