1

I'm working with an app where different users can create their own ERC721 tokens by passing token, symbol total supply etc. Currently, the code is creating the token, but it has common name only.

pragma solidity ^0.5.0;

import "./token/ERC721/ERC721Full.sol";
import "./drafts/Counters.sol"; 


contract MyContract is ERC721Full {

    using Counters for Counters.Counter;
    Counters.Counter private _tokenIds;

    constructor() ERC721Full("MYToken", "MYT") public {          
    }

    function mint(address player) public returns (uint256) {

        _tokenIds.increment();

        uint256 newItemId = _tokenIds.current();
        _mint(player, newItemId);
        return newItemId;
    }
}

How to create tokens with different name and symbol for each user? and mint to their account?

Do I need to deploy a smart contract per user? if so, the complexity will be increased by time. And is there any best practice available.

  • I would suggest write a contract which creates ERC721 contracts for the users - users simply enter the required information. Or do this in your backend so your backend deploys a contract for the user. – Lauri Peltonen Apr 3 at 9:43
  • Thanks @LauriPeltonen, any good example for contract which creates ERC721 contracts ? – Div Apr 3 at 10:04
  • sorry, no. maybe mr. Google can find some – Lauri Peltonen Apr 3 at 10:09
1

You can use a clone factory smart contract to do so. https://github.com/optionality/clone-factory/blob/master/contracts/CloneFactory.sol

An example of your ERC721 factory would be

pragma solidity ^0.6.0;
import "./clone_factory.sol";
import "./erc721.sol";


contract ERC721Factory is cloneFactory {
    address  payable template;


    constructor(address payable _templateAddress) public {
        template = _templateAddress;
    }

    function create(string memory myName, string memory mySymbol)
    external returns (address) {
        address payable _address = payable(createClone(template));
        ERC721(_address).set(msg.sender, myName, mySymbol);
        return _address;
    }
}

template will be the address of your ERC721 contract.

The new _address will be the address of new ERC721 token with the myName and mySymbol. The owner of new ERC721 token will be msg.sender. You can pass more variable to set function as per your requirements.

Your constructor function of the ERC721 contract should ideally be empty and should have a set function that will set myName and mySymbol.

| improve this answer | |
  • Thanks, I'll give a try and let you know. – Div Apr 6 at 6:26
0

You can pass the strings to the constructor instead hardcoding them (if I understood your question correctly).

pragma solidity ^0.5.0;

import "./token/ERC721/ERC721Full.sol";
import "./drafts/Counters.sol"; 


contract MyContract is ERC721Full {

    using Counters for Counters.Counter;
    Counters.Counter private _tokenIds;

    constructor(string myName, string mySymbol) ERC721Full(myName, mySymbol) public {          
    }

    function mint(address player) public returns (uint256) {

        _tokenIds.increment();

        uint256 newItemId = _tokenIds.current();
        _mint(player, newItemId);
        return newItemId;
    }
}`

| improve this answer | |
  • I'm sorry if the question is not cleared. The constructor will be called only once, then the name of that tokens will be same. Do I need to deploy new contract for each user? – Div Apr 3 at 8:30
  • Ok - I misunderstood the question. – Mikko Ohtamaa Apr 3 at 8:53
0

Here is the full contract that worked for me:

pragma solidity ^0.5.0;

import "./ERC721Full.sol";
import "./Counters.sol";     

contract MyContract is ERC721Full {

    using Counters for Counters.Counter;
    Counters.Counter private _tokenIds;

    constructor(string memory myName, string memory mySymbol) ERC721Full(myName, mySymbol) public {

    }

    function mint(address player, uint totalSupply) public returns (bool) {

        for(uint256 i = 1; i<= totalSupply; i++){
            _tokenIds.increment();
            uint256 newItemId = _tokenIds.current();
            _mint(player, newItemId);
        }
    }
}

contract ContractFactory {

    address[] public contracts;
    address public lastContractAddress;       

    function getContractCount() public view returns(uint contractCount) {
        return contracts.length;
    }

     // deploy a new purchase contract
    function deploy(string memory name, string memory symbol) public returns(address newContract){
         MyContract c = new MyContract(name,symbol);
         address cAddr = address(c);
         contracts.push(cAddr);
         lastContractAddress = cAddr;

         return cAddr;
    }        
    function mint(MyContract tokenAddress, uint256 totalSupply) public {

      tokenAddress.mint(msg.sender, totalSupply);
    }       
}
| improve this answer | |

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.