I have a project in mind and I want to have a crowd sale where two separate tokens are issued.

The simple flow is this. Send X ETH > X token_A. Use token_A as a way to vote. There will be X amount of voting wallets that the person can choose from. Once all of that persons token_A are deposited(voted with) the person will receive Token_B which will have another use.

My first thought would be just have 2 tokens created and issued right off the bat. Is that possible? I just liked the idea of almost forcing the votes before receiving the second token.

I wouldn't even know where to begin to have the second token issued once all of token_A are spent. Not sure how you could track it all should they be spread among the available voting wallets.

Has anyone done something similar to this? Is it even possible?

I appreciate any help or suggestions.

1 Answer 1


You can either issue two tokens right off the bat, or you can do a check after the person votes to see if they have any left, and if not, issue Token B. This is some pseudocode for how you would do it the latter way (the way you wanted).

contract tokenA { function transfer(address receiver, uint amount){  } }

contract tokenB { function transfer(address receiver, uint amount){  } }
contract Crowdsale {

   tokenA public tokenRewardA;
   tokenB public tokenRewardB;

   mapping(address => uint256) balancesA;
   mapping(address => uint256) balancesB;

   function Crowdsale(address _addressOfTokenA, address _addressOfTokenB) {
        tokenRewardA = tokenA(_addressOfTokenA);
        tokenRewardB = tokenB(_addressOfTokenB); 
   function () payable {
      uint amount = msg.value;
      uint tokensA = // do some calculations for amount of tokensA
      tokenRewardA.transfer(msg.sender, tokensA);
      balancesA[msg.sender] += tokensA;

   function vote(uint256 _amount) {
      // calculate the vote for tokens A
      // and decrement their vote amount
      // do that part however ylike.
      // then check the balanceA amount
      if (balancesA[msg.sender] == 0) {
         // decide how many tokenB to give them
         uint tokensB = //calculations;
         tokenRewardB.transfer(msg.sender, tokensB);
         balancesB[msg.sender] += tokensB;
         // now set a variable somewhere to indicate
         // this user has claimed their tokensB already

You could also add checks to the default payable function so that once they've bought some A, used them, and now have B, they are not able to buy A anymore. Keep another mapping of address => bool to see if they've already gone through the process, and update it in vote().

If you want instead to do it for the total votes/tokenA, and not a single users, then just keep a running tally. Say you know there are 1,000,000 tokens. Every time tokens sell, just += uint256 tokensSold with the amount. Every time tokens are used to vote, += uint256 tokensVotedWith. That way you know how many tokens have been used without querying a gigantic amount of wallets.

Create a bool issuingTokenB and set it to true when you're ready to globally issue them (ie, when tokenVotedWith is at whatever number you decide). Check in the default function () payable to see if (issuingTokenB && msg.value == 0), in which case a 0 eth transaction has been sent from someone. Then give them their tokenB.

This doesn't account for many things, like a user sending tokens to someone else, as now they have less but obviously your balances here on the Crowdfund wouldn't update, just the TokenA or TokenB contract. This is just a skeleton. You could make calls to the balances mapping and balanceOf function on the token contracts themselves instead of keeping two running totals.

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.