I would like to write three token contracts A, B and C that can interact with each other. A is the main token, B and C are the sub-tokens. A buyer can buy the main token(token A) and use them to buy the sub-tokens(token B and token C). After buying the sub-tokens, the buyer's balance of the main token should decrease, and the balance of the sub-tokens should increase. How should I design these three contracts? I am now modifying the ERC20 standard token, but I don't know how to design the function transferFrom in the ERC20 to satisfy the above conditions?

  • Are you considering making the main token and sub-tokens mint/burn coins as they get transferred?
    – supakaity
    Commented Mar 31, 2018 at 4:48
  • No. I would like the let the coins flow back to the original tokens. Commented Mar 31, 2018 at 4:52
  • I think this blog can solve your problem. Ethereum smart service payment with tokens
    – magicly007
    Commented Aug 17, 2018 at 3:38
  • it's better you can quote from the blog and elaborate more. Commented Aug 17, 2018 at 9:06
  • While this link may answer the question, it is better to include the essential parts of the answer here and provide the link for reference. Link-only answers can become invalid if the linked page changes. - From Review
    – Henk
    Commented Aug 20, 2018 at 8:57

2 Answers 2


Allowing contracts to interact with each other

This is as easy as putting in methods that will allow the parent contracts to execute functions in the child contract that will perform actions.

You could have a function in the parent which when executed by a token holder, allows them to transfer funds down to a child contract, and subsequently in the child contract to call the parent again.


The following example implements a contract which creates 2 subcontracts, and transfer functions that allow the funds to be transferred back and forwards between the parent and the children.

It will initially give the creator 1000 Main tokens, then the owner could call for example Main.buyB(10). The owner would then have 990 Main, and 10 B. The owner could then subsequently call B.sell(5) and have 995 Main and 5 B.

pragma solidity ^0.4.21;

/// @title Tracks ownershipt of the descendant token.
contract Owned {
    address owner;

    modifier onlyOwner() {
        require(msg.sender == owner);

/// @title Should be a fully functioning token, only a stub is provided below,
/// for demonstration purposes.
contract Token is Owned {
    mapping(address => uint) balances;

    /// @notice ERC20 - Returns the balance of the requested address.
    /// @param _to The address to return the balance for.
    /// @return The token balance of `_to`.
    function balanceOf(address _to) external view returns (uint) {
        return balances[_to];

    // Contains all the other standard ERC20 token junk.

/// @title Is the main contract which can buy B or C tokens.
contract Main is Owned, Token {
    // The first "B" sub-token.
    Sub public b_token;
    // The second "C" sub-token.
    Sub public c_token;

    /// @notice Creates a new Main token, then creates 2 sub-tokens and saves them.
    function Main() public {
        // Grant the creator 1000 Main tokens.
        balances[msg.sender] = 1000;

        // Create 2 new sub contracts and save them as b_token and c_token.
        b_token = new Sub();
        c_token = new Sub();

    /// @notice Buys a given number of B tokens using the balance of the Main token.
    /// @param _value The amount of B to buy with Main.
    function buyB(uint _value) external {
        require(balances[msg.sender] > _value);
        balances[msg.sender] -= _value;
        b_token._give(msg.sender, _value);

    /// @notice Buys a given number of C tokens using the balance of the Main token.
    /// @param _value The amount of C to buy with Main.
    function buyC(uint _value) external {
        require(balances[msg.sender] > _value);
        balances[msg.sender] -= _value;
        c_token._give(msg.sender, _value);

    /// @notice Gives `_value` worth of Main tokens to `_to`.
    /// @dev Only callable by B or C children contracts.
    /// @param _to The address to give Main to.
    /// @param _value The amount of Main to give to `_to`.
    function _give(address _to, uint _value) external {
        require(msg.sender == address(b_token) || msg.sender == address(c_token));
        balances[_to] += _value;
        require(balances[_to] >= _value);

/// @title A sub-token of `Main`, purchasable using Main token, and sellable for
/// Main token.
contract Sub is Token {
    /// @notice Creates a new Sub token and assigns the creator (`Main`) as the owner.
    function Sub() public {
        owner = msg.sender;

    /// @notice Gives `_value` worth of this tokens to `_to`.
    /// @dev Only callable by parent Main contract.
    /// @param _to The address to give this token to.
    /// @param _value The amount of this token  to give to `_to`.
    function _give(address _to, uint _value) external onlyOwner {
        balances[_to] += _value;
        require(balances[_to] >= _value);

    /// @notice Sells a given value of this token and gives back parent `Main` token.
    /// @param _value The amount of this token to sell.
    function sell(uint _value) external {
        require(balances[msg.sender] >= _value);
        balances[msg.sender] -= _value;
        Main(owner)._give(msg.sender, _value);
  • so do I need to create three contracts?(one Main and two Subs) Or I just need to create one Main contract? Because when creating the Main contract, I found out that it automatically generated two sub -contract address for me Commented Mar 31, 2018 at 9:24
  • That's correct, you create the main contract and it will create the subcontracts itself.
    – supakaity
    Commented Mar 31, 2018 at 9:25
  • but how would I know which two accounts are the owners of b_token and c_token? Commented Mar 31, 2018 at 10:57
  • The Main contract owns the B and C contracts as it created them.
    – supakaity
    Commented Mar 31, 2018 at 11:01
  • If this answered your question, please mark it as the correct answer. If not let me know so I can further assist.
    – supakaity
    Commented Apr 2, 2018 at 3:03

One way to go is to keep contract A a basic ERC20 token with nothing added. So when someone transfers A, the balances array gets modified.

Contracts B and C would be a bit special ERC20 tokens. Start with ERC20, but add some purchase (and sell) methods which modify balance in contract A to decrease their A tokens and increase balance in B/C contract. I actually don't think there would be much other oddities - otherwise B and C could be used like normal ERC20.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.