I am experimenting with the MyAdvancedToken code at: https://www.ethereum.org/token

    function setPrices(uint256 newSellPrice, uint256 newBuyPrice) onlyOwner public {
        sellPrice = newSellPrice;
        buyPrice = newBuyPrice;

    function buy() payable public {
        uint amount = msg.value / buyPrice;               // calculates the amount
        _transfer(this, msg.sender, amount);              // makes the transfers

If the amount purchased = msg.value/buyPrice, how is it ever possible to buy a token that is worth less than 1ETH? buyPrice cannot be a decimal less than 1. In other words, I want it so a person can send 1 ETH and receive 10 tokens. This math does not allow that (buyPrice cannot be 0.1).

Some of the documentation says that value and buyPrice should be in wei, not ETH. In that case, I could make the math work. However, in testing using MyEtherWallet and the Ethereum Wallet application, I am seeing msg.value come over as ETH. If I send 1 ETH, with buyPrice = 10, the user ends up buying 0.1 tokens.

Is there a trick to getting the msg.value to be wei instead of ETH?


1 Answer 1


Within a contract, msg.value is always in Wei. Front-end applications will sometimes display values in Eth as a "convenience" to the user, but within the transaction it's always Wei.

Note that a similar thing is true for token values within contracts. For example, this MyAdvancedToken token has decimals set to 18 (the same as Ether). When you buy 0.1 tokens, internally you are actually buying 1017 tokens. A user interface may use the decimals parameter to translate this to 0.1 for display.

[To expand on this now I'm no longer on mobile.]

For both Ether and tokens you've got two things going on:

  1. The internal representation, which is always an integer. For Ether, this is Wei.
  2. The user interface representation, which can be different. UIs know that 1 Eth = 10^18 Wei (i.e. 18 decimal places). ERC20 tokens tell the UI how many internal units make up a whole token via the decimals parameter. This is often also 18, but does not need to be.

In your example, MyAdvancedToken has decimals equal to 18, the same as Ether. So you cannot issue more tokens than the amount of Ether coming in, since buyPrice is an integer of one or greater.

If you want to issue 10 tokens for 1 Eth, you can do one of the following:

  • Set buyPrice to 1 and decimals to 17. Each Wei will buy 1 token, but the UI will display it as 10x bigger.

  • Set buyPrice to 1017 and decimals to 0. Each Ether will buy 10 base tokens, and they will be displayed as whole tokens.

  • Set buyPrice to 10x and decimals to 17 - x.

Or you can forget about all of this and just multiply by the inverse of buyPrice (10) rather than dividing by buy price. This is probably the simplest.

This is all a huge headache of course. I really hate the ERC20 token decimals concept. Here's a long discussion about it. I favour hardcoding decimals to 0, fwiw.

  • In other words, in all the contracts made using that ethereum.org boilerplate code, a purchased token cannot have a value less than 1 ETH? Thanks for the great answer.
    – GAEfan
    Jan 15, 2018 at 16:24

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.