Я хочу использовать переменную rewardsAmount для расчета вознаграждения:
uint вознагражденияСумма = 0; // Только здесь я могу вывести награды функция removeRewards() onlyВладелец внешний { требуется (сумма вознаграждения! = 0); владелец.transfer (сумма вознаграждения); сумма вознаграждения = 0; } // Если в контракте нет средств пользователей, то я могу его уничтожить только функция kill() Владелец внешний { требуют(адрес(этот).баланс - сумма вознаграждения == 0); самоуничтожение (владелец); } функция someFunction() публичная { // какой-то код сумма вознаграждения += 100; }
Если кто-то отправит на адрес контракта немного эфира, я никогда не смогу убить контракт, верно? Итак, как я могу предотвратить отправку эфира на мой контракт?
Нет, вы не можете предотвратить отправку эфира на ваш контракт.
Остерегайтесь кодировать инвариант, который строго проверяет баланс контракта.
Злоумышленник может принудительно отправить эфир на любую учетную запись, и это невозможно предотвратить (даже с помощью резервной функции, выполняющей revert()).
Злоумышленник может сделать это, создав контракт, финансируя его с помощью 1 wei и вызвав selfdestruct(victimAddress). Код жертвы не вызывается, поэтому предотвратить это невозможно. Это также верно для вознаграждения за блок, которое отправляется на адрес майнера, который может быть любым произвольным адресом.
Кроме того, поскольку адреса контрактов могут быть предварительно вычислены, эфир может быть отправлен на адрес до того, как контракт будет развернут.
См. SWC-132
Вы не можете надежно отклонить средства, переведенные на контрактный адрес. Будьте осторожны, чтобы не сделать вектор атаки (отключить ваш selfdestruct
), потому что кто-то selfdestruct(yourContract)
покажет вам ошибку. Ой!
Более неясный способ — это охота за пасхальными яйцами, но не слишком надуманная. Учитывая адрес развертывателя и одноразовый номер, адрес развернутого контракта предсказуем , поэтому можно иметь положительный баланс до развертывания контракта . Это полезно для эзотерических шаблонов, озорства и возможного саботажа, если ваш контракт, опять же, использует address(this).balance
важную логику. Имейте в виду, что это может быть не то, что вы ожидаете.
Я понимаю, что это надуманный пример. Настоящая опасность здесь заключается в использовании address(this).balance
логики. В интересах всех, кто еще сталкивался, я бы отговаривал selfdestruct
вообще. Самоуничтожение — это ошибка .
Надеюсь, поможет.
ффи
Роб Хитченс
onlyIfRunning
и он долженrequire(!pause, "the contract is stopped.")
.Роб Хитченс
ффи