5

I am trying to deploy a contract as explained in this section on Web3.js docs.

As I understand it, I need to do the following:

  1. Create a new contract via web3.eth.Contract
  2. Take the returned-object and call deploy with it
  3. Take the returned-object and call send with it

Some questions about this:

  1. Why do I need to pass the address of the contract to web3.eth.Contract? Wouldn't the contract be allocated wherever there's a "free space"? It's as if I would allocate a variable dynamically, but then tell the compiler exactly where I wanted it.
  2. I see several redundancies, which make me feel like I've got something wrong in my understanding of the 3-step process described above:
    • Both web3.eth.Contract and deploy take the byte-code as input
    • Both web3.eth.Contract and send take the owner-address, gas and gas-price as input

Here is the code that I've implemented:

let fs = require("fs");
let Web3 = require("web3");

async deploy(contractName, contractArgs) {
    let web3 = new Web3(new Web3.providers.HttpProvider(NODE_URL));
    let abi = fs.readFileSync(contractName + ".abi").toString();
    let bin = fs.readFileSync(contractName + ".bin").toString();
    let contract = new web3.eth.Contract(JSON.parse(abi), CONTRACT_ADDRESS, {from: MY_ADDRESS, gasPrice: '1000', gas: 2310334, data: "0x" + bin});
    await contract.deploy({data: "0x" + bin, arguments: contractArgs}).send({from: MY_ADDRESS, gasPrice: '1000', gas: 2310334});
    return contract;
}

Can somebody please point out what I need to do differently (in correlation with my questions above)?

Thank you!!!

2

You can create the contract instance using only the ABI, which is the only required field when you create the contract. web3.eth.Contract(JSON.parse(abi)). You don't have the contract address yet, since you're deploying it, so don't need to be provided. The third parameter, options, define the global options for that contract; the values provided are used as fallback for calls and transactions.

To answer to your second point, the redundancy is because the options when you create the contract are there as default settings and fallback, while you can still specify your own in any call/transaction.

let contract = new web3.eth.Contract(JSON.parse(abi)));
await contract.deploy({
                data: "0x" + bin, 
                arguments: contractArgs
               })
              .send({
                from: MY_ADDRESS, 
                gasPrice: '1000', gas: 2310334
               });

so your code could be simplified in this way.

  • Can you please also explain, how can I make this transaction "go through". Because the promise doesn't seems to be fulfilled (i.e., the await never returns). I think I need to sign the transaction somehow, but here is the paradox - the transaction exists only after I send it, and I don't understand how I can sign it before it exists. Do I need to start another process which will communicate with the same provider and sign the transaction? Or what exactly am I missing here? Thank you for your help! – goodvibration Jun 6 '18 at 11:26
  • How did you resolve this @goodvibration? – Miguel Mota May 8 at 20:38
0

To deploy contract you have to use sendRaw transaction and make it signed to send it and include your bin in data section of the transaction.

for example:-

var rawTx = {
  from: Your Address,
  nonce: web3.toHex(web3.eth.getTransactionCount(address)),
  gasLimit:3000000,

  gasPrice: web3.toHex(20000000000),
  data: Your bin data

}

function sendRaw(rawTx) {

    var transaction = new tx(rawTx);
    transaction.sign(privateKey);

    var serializedTx = transaction.serialize().toString('hex');
    web3.eth.sendRawTransaction(
    '0x' + serializedTx, function(err, result) {
                hs = result;
        if(err) {
            console.log(err);
        } else {

            console.log(result);
        }

    });

}
0

Example of deploying a contract using Web3.js:

  const ExampleContract = require('./contracts/Example.json')
  const MyContract = new web3.eth.Contract(ExampleContract.abi)

  const gas = await MyContract.deploy({
    data: ExampleContract.bytecode
  }).estimateGas()

  AccountContract.deploy({
    data: ExampleContract.bytecode
  }).send({
    from: accounts[0],
    gas: gas,
  })
  .on('error', (error) => {
    console.log(error)
  })
  .on('transactionHash', (transactionHash) => {
    console.log(transactionHash)
  })
  .on('receipt', (receipt) => {
     // receipt will contain deployed contract address
     console.log(receipt)
  })
  .on('confirmation', (confirmationNumber, receipt) => {
    console.log(receipt)
  })

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.