I'm new to smart contracts and still learning some solidity basics. The contract I created, should give the sender custom tokens for Ether. I have trouble in calculating tokens and also decrease the token amount.

Here are my initial values

   uint8 public constant decimals = 18;
   uint256 _totalSupply = 1000000;
   uint128 constant RATE = 2;

For example, if I pay 1 ETH I should get 2 Tokens.

For some reason, it doesn't work here properly:

When I pay 1 Ether to this contract, I'm getting 2000 tokens but instead, it should be 2 tokens

uint256 tokens = msg.value * RATE;

Here is also something weird, I'm getting this value for balances[owner] and _totalSupply 115792089237316195423570985008687907853269984665640564039455.584

balances[owner] = balances[owner] - tokens;  
_totalSupply = _totalSupply - tokens;

here the function:

 function createTokens() payable
    require(msg.value > 0);

    uint256 tokens = msg.value * RATE;  
    balances[msg.sender] = balances[msg.sender] + tokens; //add tokens to senders balance
    balances[owner] = balances[owner] - tokens;           //subtract tokens from owners balance

    owner.transfer(msg.value);                            // transfer amount of ether to cotract owner
    Transfer(owner, msg.sender, tokens);                  // Broadcast a message to the blockchain

   _totalSupply = _totalSupply - tokens ;

Your _totalSupply is far too low. Remember that you have 18 decimal places, so 1 token is 1000000000000000000 (a 1 with 18 zeros after it). If you want to start with 1,000,000 tokens, you need to set _initialSupply to a 1 with 24 zeros after it (18 + 6).

Assuming you assign all the tokens to the owner upon initialization, both balances are suffering from an integer overflow after you subtract more tokens than exist. You should consider something like require(_totalSupply >= tokens && balances[owner] >= tokens) to guard against this.

As to why you're getting 2000 tokens instead of 2, I can't really say. Ether itself and your token both appear to use 18 decimal places. If you can share the full source code (and perhaps a link to where it's deployed, if it's deployed somewhere public), I might be able to help more.

| improve this answer | |
  • Ohh I really missed the part with the decimals.... Thank you very much, so when I'm declaring decimals all values are based on it ? for example if the sender sends 2 Ether then the msg.value = 2 * 10^18 ? do I need to then calc (msg.value * RATE)/10^18 ? – Samy Jan 1 '18 at 23:10
  • Yes, the msg.value is 2 * 10^18, and no, you don't want to divide that away. (Because you want to award 4 * 10^18 in your token. This will be 4 tokens.) – user19510 Jan 1 '18 at 23:11

Maybe you want to try this conversion tool: https://ico.atorresg.com/

| 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.