Функция Buy() не работает должным образом

Я экспериментирую с MyAdvancedTokenкодом по адресу: 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
    }

Если amount purchased = msg.value/buyPrice, то как вообще можно купить токен стоимостью менее 1ETH? buyPriceне может быть десятичным числом меньше 1. Другими словами, я хочу, чтобы человек мог отправить 1 ETH и получить 10 токенов. Эта математика не позволяет этого ( buyPriceне может быть 0,1).

В некоторых документах говорится, что valueэто buyPriceдолжно быть в wei, а не в ETH. В этом случае я мог заставить математику работать. Однако при тестировании с использованием MyEtherWallet и приложения Ethereum Wallet я вижу, msg.valueчто это ETH. Если я отправлю 1 ETH с помощью buyPrice = 10, пользователь купит 0,1 токена.

Есть ли какой-то трюк, чтобы получить msg.valueWei вместо ETH?

Спасибо.

Ответы (1)

В рамках контракта msg.valueвсегда находится в Вэй. Внешние приложения иногда отображают значения в Eth для «удобства» пользователя, но внутри транзакции это всегда Wei.

Обратите внимание, что то же самое верно и для значений токенов в контрактах. Например, этот MyAdvancedTokenтокен имеет decimalsзначение 18 (такое же, как у эфира). Когда вы покупаете 0,1 токена, внутри вы фактически покупаете 10 17 токенов. Пользовательский интерфейс может использовать этот decimalsпараметр для преобразования его в 0,1 для отображения.


[Чтобы расширить это, теперь я больше не на мобильном телефоне.]

Как для эфира, так и для токенов у вас есть две вещи:

  1. Внутреннее представление, которое всегда является целым числом. Для Эфира это Вэй.
  2. Представление пользовательского интерфейса, которое может быть различным. Пользовательские интерфейсы знают, что 1 Eth = 10^18 Wei (т.е. 18 знаков после запятой). Токены ERC20 сообщают пользовательскому интерфейсу, сколько внутренних единиц составляет целый токен с помощью decimalsпараметра. Часто это также 18, но не обязательно.

В вашем примере MyAdvancedTokenравно decimals18, как и Эфир. Таким образом, вы не можете выпустить больше токенов, чем количество поступающего эфира, поскольку buyPriceэто целое число, равное единице или больше.

Если вы хотите выпустить 10 токенов за 1 Eth, вы можете сделать одно из следующих действий:

  • Установите buyPrice1 и decimals17. Каждый Wei купит 1 токен, но пользовательский интерфейс будет отображать его в 10 раз больше.

  • Установите buyPrice10 17 и decimals0. Каждый Эфир будет покупать 10 базовых токенов, и они будут отображаться как целые токены.

  • Установите buyPriceна 10 x и decimalsна 17 - x.

Или вы можете забыть обо всем этом и просто умножить на величину, обратную buyPrice(10), а не делить на цену покупки. Это, пожалуй, самое простое.


Все это, конечно, большая головная боль. Я действительно ненавижу концепцию токена ERC20 decimals. Вот долгое обсуждение этого. Я предпочитаю жесткое кодирование decimalsдо 0, между прочим.

Другими словами, во всех контрактах, заключенных с использованием стандартного кода ethereum.org, стоимость купленного токена не может быть меньше 1 ETH? Спасибо за отличный ответ.