0

I'm starting up with solidity and I'm deploying my smart contracts using web3 with the following function:

    deployContract(args) {
    var web3 = <MY-WEB3-PROVIDER>;
    var privateKey = <MY-PRIVATE-KEY>;

    return new Promise(function (resolve, reject) {

        const file = fs.readFileSync('./contracts/Dummy.json').toString();
        var output = JSON.parse(file);
        var ABI = output.abi;
        var bytecode = output.bytecode;
        
        const contract = new web3.eth.Contract(ABI);

        var deployData = contract
        .deploy({
            data: bytecode,
            arguments: args
        })
        .encodeABI();

        var txData = {
            data: deployData
        }

        var estimatedGas = contract
        .deploy({
            data: bytecode,
            arguments: args
        })
        .estimateGas()
        .then(function(gas) {
            txData.gas = web3.utils.toHex(3000000);
            web3.eth.accounts.signTransaction(txData, privateKey)
            .then((signed) => {
                web3.eth.sendSignedTransaction(signed.rawTransaction)
                .on("receipt", (receipt) => {
                    resolve(receipt.contractAddress);
                })
            });
        })

    });
}

It works well so far until I'm trying to deploy an ERC20 token contract which is supposed to mint the initial supply of tokens to the message sender, for some reason it sees zero address as the message sender and thus the transaction fails.

This is the contract:

//SPDX-License-Identifier: MIT
pragma solidity >=0.6.2;

import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import "@openzeppelin/contracts/access/Ownable.sol";

contract GoldToken is ERC20, Ownable, Whitelist {
  string public TOKEN_NAME = "Gold Token";
  string public TOKEN_SYMBOL = "GLD";

  uint256 private constant TOTAL_SUPPLY = 50000;

  constructor()ERC20(TOKEN_NAME, TOKEN_SYMBOL) {
    _mint(_msgSender(), TOTAL_SUPPLY);
  }

  function mint(address to, uint256 amount) public onlyOwner {
    _mint(to, amount);
  }
}

Funny thing is the deployment of this contract works perfectly on Remix (either with the Remix VM or using Injected Provider to use Metamask and deploy the contract to the very same testnet I'm using from nodejs) which leds me to think I'm missing something on the deployment process

I'm almost out of ideas here, I'll appreciate if someone can give me an idea of what could be causing this or a workaround. Thanks in advance guys!

1 Answer 1

1

Yes, tokens are technically created out of thin air. On mainnet it is seen as coming from the zero address.

What you need to do in this case is rather add an input paramater to the constructor for example:

 constructor()ERC20(TOKEN_NAME, TOKEN_SYMBOL, address payable _initialPayWallet) {
    _mint(_initialPayWallet, TOTAL_SUPPLY);
  }

That should work.

3
  • Thanks a lot man, that is in fact a viable solution and it is what I ended up doing. However I'm not quite grasping the concept of why can't you mint ERC20 tokens in constructor, see here docs.openzeppelin.com/contracts/2.x/erc20-supply
    – Chrishow
    Aug 1 at 16:40
  • What happends if you use msg.sender instead of _msgSender() Aug 3 at 9:22
  • Already tried it, exactly the same thing.
    – Chrishow
    Aug 3 at 11:27

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.