-1

I am trying to make a token generator, I have made two contracts the following way:

pragma solidity ^0.8.0;

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

contract Token is ERC20 {
    constructor(string memory name, string memory symbol) ERC20(name, symbol) { 
        _mint(msg.sender, 1000);
    }
}

TokenGenerator contract:

pragma solidity ^0.8.0;

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

contract TokenGenerator{ 
    
    function generateToken(string memory name, string memory symbol) public returns(address){
        Token token = new Token(name, symbol);
        address myAddress = address(token);
        return myAddress;
    }
}

However, I am struggling to understand how to use it in the frontend side. The way I generally do is that I deploy the contract and use that abi to generate more token, in which case the token holder is the deployed contract address and not the account that is generating the token. How do I generate a token whereupon every time the user clicks generate a new smart contract of the token is made on the go, and the token holder is the user account address?

2 Answers2

2

I would recommend you:

  1. emit some event on generateToken transaction execution. So you will be able to subscribe to this event on your UI and keep track of newly generated Token contracts

  2. keep track of the generated Token contract addresses on the blockchain side for easy access outside of the blockchain

    contract TokenGenerator {
    
        address[] public allTokens;
        event TokenGeneration(address indexed tokenAddress);
        function generateToken(string memory name, string memory symbol) public returns (address) {
            Token token = new Token(name, symbol);
            address myAddress = address(token);
    
            // Add the address of generated Token contract to the allTokens array
            allTokens.push(myAddress);
    
            // Emit event with the address of generated Token contract
            emit TokenGeneration(myAddress);
    
            return myAddress;
        }
    }
    

So now:

  1. from your UI you can subscribe to TokenGeneration event to get notified when the new Token contract is generated
  2. from your UI you can access all generated Token contract addresses using allTokens array

The ABI for all Token contracts will be the same.

Igor Senych
  • 56
  • 1
  • 3
  • I think you have misunderstood my question. When the new token is generated, it is generated on the same contract address because I am deploying the smart contract and using the deployed contract address to generate other tokens. I want a new smart contract to be deployed whenever the user clicks on generate token and have the user as the token holder of the contract. – thecalendar Jul 11 '22 at 16:59
  • Do you mean that every generated Token contract will have that same address? – Igor Senych Jul 11 '22 at 18:47
  • That is the current behaviour. The intended behaviour is that every generated token will have a different contract address. I guess for that I need to deploy the contract on the go while passing the arguments inputted from the user. I am not sure how to do that in ethers.js. – thecalendar Jul 11 '22 at 19:25
  • No, the new Token contract with a unique address will be generated on each generateToken execution. Please try to play with it in Remix. – Igor Senych Jul 12 '22 at 06:26
  • Hey, so the problem was with how I was executing it on the frontend. I was using the deployed contract address to mint other tokens. I changed it to deploying the contract once the generate token is clicked, and it started working as intended. Thank you for your input tho. I wanted to ask the ethers.js part instead. – thecalendar Jul 13 '22 at 08:05
1

I was committing an error by deploying the contract and using the deployed contract address to call generateToken function. With this method, the contract address becomes the msg.sender and not the account address interacting with the smart contract. I did the following to have the account address as the token holder and generate a new address every time someone clicks the generate token button:

const generateToken = async () => {
    try {
      const { ethereum } = window;

      if (ethereum) {
        const provider = new ethers.providers.Web3Provider(ethereum);
        const signer = provider.getSigner();
        const factory = new ethers.ContractFactory(Token.abi, bytecode, signer);
        const tokenGeneratorContract = await factory.deploy(name, symbol);

        await console.log("Token Address:", tokenGeneratorContract.address);
      } else {
        console.log("Ethereum object doesn't exist!");
      }
    } catch (error) {
      console.log(error);
    }
  };

I didn't have to use the TokenGenerator contract and only used the Token contract, its ABI and bytecode to deploy the contract. So generally one would have the private key to deploy the contract. Signer from ethers.js allows one to create a function where the client can deploy the contract directly through their Metamask account, without knowing their private_key.