Solidity hints. Часть 10
Потихоньку перешагиваем экватор лета, пытаемся отдохнуть и, возможно, открыть для себя что-то новое.
Я все еще продолжаю возиться со свои личным проектом, выкладываю уроки на летнем модуле и проверяю домашние задания, а также отслеживаю небольшие конкурсные аудиты, чтобы оставаться в курсе современных протоколов и уязвимостей в них.
А на канале мы продолжаем разбирать пункты из репо Chinmaya, и сегодня у нас по счету уже 14:
14. After a failed call, Do not assume that the error message is coming directly from the called contract: The error might have happened deeper down in the call chain and the called contract just forwarded it (bubbling up of errors)
что в переводе:
После неудачного вызова не думайте, что сообщение об ошибке пришло непосредственно от вызванного контракта: ошибка могла произойти глубже в цепочке вызовов, а вызванный контракт просто переслал ее.
В простых протоколах обычно вызовы могут идти в "соседний" контракт, например:
Контракт А => Контракт В
В более сложных протоколах, каких-нибудь DeFi, эти вызовы могут проходить через несколько контрактов, или даже протоколов:
А => В => С => А => Е
и т.д. И вот если мы вызываем из контракта А такую функцию и на каком-то этапе происходит откат транзакции и нам возвращается ошибка, не стоит предполагать, что вернул ее контракт В.
В таком случае необходимо использовать программы для тестирования смарт контрактов или дебаггеры и смотреть, как проходит вызов, откуда идет ошибка и что ее выдает.
15. Calling a function on a different contract (instance) will perform an EVM function call and thus switch the context such that state variables in the calling contract are inaccessible during that call (except if you use delegatecall)
и перевод:
Вызов функции на другом контракте выполнит вызов функции EVM и, таким образом, переключит контекст так, что переменные состояния в вызывающем контракте будут недоступны во время этого вызова (не считая использования delegatecall)
Тут также все достаточно просто. Например, если мы делаем вызов из контракта А в контракт В, то переменные контракта А будут недоступны для изменения в контракте В, так как вызов "переключится" контекстом на В.
Еще проще, допустим у нас есть переменная owner в А. Мы делаем вызов из А в В и там вызываем функцию для изменения адреса владельца.
И несмотря на то, что вызов идет через А, переменная будет изменения в В.
При этом, если мы используем функция с delegatecall в А, делая вызов в В, то мы "как бы захватываем" функцию из В, переносим ее в А и изменяем уже состояние в памяти А.
Звучит немного запутано, но стоит разобраться с call() и delegatecall(), как все встанет на свои места!
#solidity #call #delegatecall
Post #1146
944
- 👍 3