Это то, что Ремикс говорит мне. Теперь, когда я смотрю на документацию о том, что это значит, кажется, что речь идет, как я понимаю, о рекурсивном вводе потока управления (если):
Передача эфира всегда может включать в себя выполнение кода, поэтому получателем может быть контракт, который вызывает возврат.
Глядя на мой код, я не вижу, как это можно использовать, я даже не добавляю токены в принимающую учетную запись до конца, после требований, единственное, что я вижу, это то, что затем может пойти не так или быть использовано, это то, что они не получат сдачу:
/*
* Allows a user to buy tokens for Ether.
*/
function buy() public payable {
// check that the amount of ether sent is greater than 0
require(msg.value > 0);
// check the amount sent is enough for at least one token
require(msg.value >= tokenPriceInWei);
// NOTE: balance is automatically updated by the payable modifier
// calculate tokens to be distributed as integer
uint numToDistribute = msg.value / tokenPriceInWei;
// calculate remainder to be refunded, e.g. 7.1eth sent, 1.1eth to be refunded
uint refundableRemainderInWei = msg.value - (toWei(numToDistribute));
// distribute token to sender
distribute(msg.sender, numToDistribute);
// refund the remainder
msg.sender.transfer(refundableRemainderInWei);
Bought(msg.sender, numToDistribute);
}
/*
* Distribute tokens from distributor to a receiver.
*/
function distribute(address _receiver, uint _amount) private {
// check for at least one token, if not something went wrong
require(_amount > 0);
// check for balance overflow, causing incorrect balances value
require(balances[_receiver] + _amount > balances[_receiver]);
// decrement from distributor and increment receiver
balances[distributor] -= _amount;
balances[_receiver] += _amount;
}
Кроме того, если кто-нибудь может сказать мне, почему стоимость газа для этого метода высока до бесконечности и почему он говорит то же самое, когда я пытаюсь развернуть контракт через Mist и не могу развернуть, это действительно сделало бы мой день!
Спасибо, если вы дочитали до этого места и за любой совет, который вы можете дать этому подающему надежды инженеру по смарт-контрактам!
Измените это:
// refund the remainder
msg.sender.transfer(refundableRemainderInWei);
Bought(msg.sender, numToDistribute);
К этому: // refund the remainder Bought(msg.sender, numToDistribute); msg.sender.transfer(refundableRemainderInWei);
Атаку с повторным входом можно рассматривать как неожиданное изменение потока перед важным изменением состояния. Итак, хорошая защита — привести свой дом в порядок, прежде чем передать управление другому контракту, что transfer
и происходит.
Размещение эмиттера событий перед transfer
гарантирует, что журнал обновляется и корректен. Это «оптимистичный учет». Если transfer
по какой-то причине произойдет сбой, это вызовет откат, и событие не будет сгенерировано.
Газ неизвестен или, возможно, бесконечен, потому что transfer
приемники неизвестны. Это могут быть внешние счета, которые просто принимают средства. С другой стороны, это могут быть контракты с резервными функциями, которые запускаются при получении средств (это передача управления потоком).
В лучшем случае эти функции будут использовать неизвестное количество газа. Это может быть бесконечно , если они наотрез откажутся принимать эфир (случайно или намеренно).
Предупреждение указывает на то, что оценка просто непоследовательна или непознаваема, и разработчика предупреждают о возможности полного отказа в некоторых случаях.
Надеюсь, это поможет.
Медведев1088
distribute
function. Remix может учитывать это при проверке уязвимости повторного входа и при оценке газа.Крисселтин