В этой главе вы изучите различные темы, связанные с безопасностью и управлением блокчейном в TON.
Глава начинается с углубленного исследования наивной реализации кошелька, атак повторов, атак отказа в обслуживании и рекомендаций по контрактам. После этого фокус смещается на поток сообщений, направляя вас через необходимые знания и навыки для эффективной работы с ним.
Управление газом в TON - это еще один критический аспект, рассмотренный в одном из уроков, позволяющий вам понять и внедрить эффективные стратегии управления газом.
Кроме того, глава включает в себя учебное пособие, которое углубляется в управление хранилищем в TON, предоставляя вам необходимые идеи и методы для эффективного хранения данных.
📚Lecture Notes
TON - это инновационный блокчейн, который включает в себя новые концепции в дизайне смарт-контрактов.
Тем не менее, разработка смарт-контрактов все еще требует точности. В дополнение к традиционным аспектам безопасности и атак добавляются новые, уникальные для TON. Давайте обсудим их.
В этом шаге мы поговорим о внешних сообщениях.
Точки входа смарт-контракта
Как вы, вероятно, уже знаете, смарт-контракты TON имеют три возможные точки входа:
- Каждый контракт должен иметь функцию recv_internal.
- Необязательный recv_external для входящих внешних сообщений.
- run_ticktock вызывается в транзакциях ticktock специальных смарт-контрактов. Не используется в обычных контрактах.
Здесь мы поговорим о recv_external. Концепция знакома: пользователь совершает транзакцию вне сети, обычно подписывает ее своим закрытым ключом и отправляет в контракт.
Реализация наивного кошелька
Кошелек в TON - это просто смарт-контракт. Давайте напишем наивный кошелек, он пересылает только сообщения, подписанные нашим закрытым ключом. Базовая реализация выглядит следующим образом:
Replay attack
Владелец кошелька теперь должен предоставить порядковый номер, который привыкается по количеству сохраненного. Это гарантирует, что любое сообщение может быть обработано только один раз:
Denial of Service Attack
Failed Replay Attack
Обратите внимание, что если после accept_message() будет выброшена какая-либо ошибка, транзакция будет записана в блокчейн, и сборы будут вычтены из баланса контракта, но хранилище не будет обновлено, и действия не будут применены, как в любой транзакции с кодом выхода ошибки. В результате, если контракт принимает внешнее сообщение, а затем выдает исключение из-за ошибки в данных сообщения или отправки неправильно сериализованного сообщения, он будет платить за обработку, но не сможет предотвратить воспроизведение сообщения.
То же самое сообщение будет приниматься контрактом снова и снова, пока он не потратит весь остаток.
Вот почему мы сохраним обновленное состояние перед разбором и исполнением сообщения:
EVM vs TON
В виртуальной машине Ethereum (EVM) защита от воспроизведения выходит из коробки:
- Закрытый ключ имеет только один связанный адрес
- Nonce автоматически увеличивается после каждой обработанной транзакции
- Владелец кошелька платит за газ, и неудачная транзакция не может быть воспроизведена
TON более гибкий:
- Один закрытый ключ может управлять многими кошельками
- Кошелек может иметь любую логическую кодовку
Recommendation
К счастью, для большинства разработчиков контрактов есть простая рекомендация: избегайте обработки внешних сообщений.
- Пусть контракт выполняет эту работу, в вашем контракте есть только recv_internal.
- Даже если вы пишете "multisig" или специальный кошелек, вы все равно можете обрабатывать только внутренние сообщения с обычных кошельков.
- В этом случае вы получите транзакции в стиле EVM со всей гибкостью под капотом.