[Ethereum] Smart Contract is being deployed but call does not return contract address after deployment

ganache-clijavascriptnodejsweb3js

So I have been trying to deploy a smart contract using nodejs, but when I call the function to deploy, I get no contract address on my console. It's like the send() function never completed its execution. And that's why the next instruction never starts its execution, even though I know that the contract is still being deployed on my local blockchain network (I know it because I can see on the cmd prompt where my ganache-cli is running.
I'm trying to get the deployed contract address, please tell me how to do the same.

Expected behavior
Calling await contract.deploy({..}).send({..}) should return response, and after that contract address should be printed on the console.

Actual behavior
Instead, no output is printed on the console after this: 'Deploy function called, about to deploy'.

command prompt output stops after:

D:/User/project>node src/deploy

No web3? You should consider trying MetaMask!

[AsyncFunction: deploy] entered, about to deploy

Although, I know that the contract has been deployed because my ganache-cli shows this output:

Transaction: 0x12345

Contract created: 0x12345

Gas usage: 1605526

Block Number: 6

Block Time: Date and time of deployment is shown

Here is the code that I'm trying to run: (deploy.js)

var Web3 = require('web3');

// abibytecode[0] has abi, abibytecode[1] has bytecode
const abibytecode = require('../src/compile');
var web3;

if (typeof web3 !== 'undefined') {
    web3 = new Web3(web3.currentProvider);
} else {
    // set the provider you want from Web3.providers
    console.log('No web3? You should consider trying MetaMask!');
    web3 = new Web3('ws://localhost:8545');
}

let account = 'my account address is here';

const contract = new web3.eth.Contract(abibytecode[0]);

const deploy = async () => {
    console.log('Deploy function called, about to deploy');
    const response = await contract.deploy({data: abibytecode[1]}).send({
      from: account,
      gas: '3000000'
    });
    console.log('Contract deployed to:', response.address);
    console.log('Contract deployed to:', response.options.address);

    return response;
};
console.log(deploy);
deploy((res)=>{console.log(res)});

Versions:

  • web3.js: 1.0.0-beta.55

  • nodejs: v10.16.0

  • browser: None, running the script from command

  • ethereum node: ganache-cli

Also, this is my first ever post on stackexchange, so if I've missed out some information let me know and I'll fill the voids.

Best Answer

To deploy a contract a signer is required. Using web3 requires the private key for the address to be present in the node. Ensure the account private key is present in the local test node. One way is to constantly start ganache-cli with a set of private keys.

There is an issue in the way the deploy async function is invoked it should be

deploy().then(function(response){ console.log(response)})

You can also switch to ethers.js it's more developer friendly

const { ContractFactory, Wallet, providers } = require('ethers')
const provider = new providers.JsonRpcProvider('http://localhost:8545')
const wallet = new Wallet(privateKey, provider)
async function deployContracts() {
    let token = new ContractFactory(tokenabi, tokenbytecode, wallet)
    // this deploys the contract
    token = await token.deploy()
    // we must wait until it is mined
    token = await token.deployed()
    return token
}
Related Topic