[Ethereum] Deploying a contract with Web3.js

contract-deploymentweb3js

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!!!

Best Answer

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.

Related Topic