Советы по разработке контрактов: ценный опыт, полученный из кода Uniswap
Недавно, при написании руководства по разработке децентрализованных бирж, я изучал код Uniswap V3 и узнал много приемов разработки контрактов. Как новичку, только начинающему заниматься разработкой Defi контрактов, эти небольшие советы были для меня очень полезными, и я уверен, что они также помогут другим новичкам, желающим изучить разработку контрактов.
Предсказуемый адрес развертывания контракта
Обычно адреса, полученные при развертывании контрактов, выглядят случайными и трудно предсказуемыми. Однако в некоторых случаях нам необходимо сделать вывод о адресе контракта на основе информации о торговых парах и связанных данных, например, для определения прав на сделку или получения адреса пула.
Uniswap использует метод CREATE2 для создания контрактов, добавляя параметр "salt", что делает адрес создаваемого контракта предсказуемым. Логика генерации нового адреса: hash("0xFF", адрес создателя, salt, initcode). Этот метод очень полезен во многих случаях.
Умелое использование функций обратного вызова
Контракты в Solidity могут вызывать друг друга. Иногда A вызывает метод B, и B вызывает A в своем вызываемом методе, что полезно в некоторых сценариях.
Например, в методе swap Uniswap контракт UniswapV3Pool вызывает обратный вызов swapCallback, передавая необходимые для этой транзакции токены. Вызывающая сторона должна передать нужные токены в UniswapV3Pool в обратном вызове, а не разделять метод swap. Это обеспечивает безопасность и целостность выполнения метода swap без необходимости в сложной записи переменных.
Передача информации с помощью исключений, реализация оценки транзакций с помощью try catch
В контракте Quoter Uniswap используется конструкция try catch для выполнения метода swap UniswapV3Pool. Это делается для симуляции swap с целью оценки необходимых токенов для сделки. Во время оценки токены не будут фактически обменены, поэтому возникнет ошибка. Uniswap выбрасывает специальную ошибку в колбэк-функции, а затем перехватывает эту ошибку и извлекает необходимую информацию.
Этот метод кажется хитрым, но он очень практичен. Не нужно модифицировать метод свопа для оценки торгового спроса, логика проще.
Большие числа решают проблемы точности
В коде Uniswap имеется множество вычислительной логики, такой как вычисление токенов для обмена на основе текущей цены и ликвидности. Чтобы избежать потери точности при операции деления, в процессе вычислений часто используется операция "<< FixedPoint96.RESOLUTION", что соответствует смещению влево на 96 бит, эквивалентно умножению на 2^96. После смещения выполняется деление, что обеспечивает точность при нормальных транзакциях без переполнений.
Хотя теоретически все еще будет незначительная потеря точности, это уже приемлемо.
Расчет доходов по методу Share
Uniswap должен записывать доход от комиссий ликвидности для поставщиков ликвидности LP( и ). Очевидно, что нельзя записывать комиссию для каждого LP при каждой сделке, это потребует много газа.
Структура Position в Uniswap содержит feeGrowthInside0LastX128 и feeGrowthInside1LastX128, которые фиксируют комиссионные, причитающиеся каждому ликвидному активу при последнем извлечении комиссионных.
Необходимо просто записывать общую комиссию и комиссию, которую необходимо распределить между каждым ликвидным активом. Комиссия, подлежащая извлечению LP, рассчитывается на основе удерживаемой ликвидности. Это похоже на владение акциями компании: при извлечении дохода нужно просто знать историческую доходность на акцию и доходность при последнем извлечении.
Не ключевую информацию не нужно записывать в блокчейн
Хранение на блокчейне относительно дорого, и не вся информация должна храниться в блокчейне или извлекаться из него. Например, многие интерфейсы, вызываемые фронтендом Uniswap, являются традиционными интерфейсами Web2.
Список торговых пулов, информация и т.д. могут храниться в обычной базе данных, часть из них необходимо периодически синхронизировать с блокчейном. Нет необходимости в реальном времени вызывать RPC-интерфейсы цепочки или узлов для получения соответствующих данных.
Конечно, ключевые сделки должны осуществляться в сети.
Разделение контрактов и использование стандартных контрактов
Проект может содержать несколько фактически развернутых контрактов. Даже если фактически развернут только один, его можно разделить на несколько контрактов для поддержки с помощью наследования.
Как контракт NonfungiblePositionManager Uniswap наследует несколько контрактов. В частности, ERC721Permit напрямую использует контракт ERC721 от OpenZeppelin, что упрощает управление позициями через NFT и повышает эффективность разработки.
Заключение
Практическая разработка упрощенной версии децентрализованной биржи позволит вам глубже понять реализацию кода Uniswap и узнать больше о практических аспектах проектов. Чтение множества статей не заменит практического опыта, надеюсь, что этот опыт будет полезен для новичков, желающих изучить разработку смарт-контрактов.
На этой странице может содержаться сторонний контент, который предоставляется исключительно в информационных целях (не в качестве заявлений/гарантий) и не должен рассматриваться как поддержка взглядов компании Gate или как финансовый или профессиональный совет. Подробности смотрите в разделе «Отказ от ответственности» .
20 Лайков
Награда
20
10
Репост
Поделиться
комментарий
0/400
GasGuzzler
· 07-18 21:18
靠 别跟 Новичок 玩这么深
Посмотреть ОригиналОтветить0
LowCapGemHunter
· 07-17 14:17
Советы для опытных разработчиков готовы.
Посмотреть ОригиналОтветить0
SmartMoneyWallet
· 07-15 22:24
в блокчейне交易都逃不过我的眼睛
Посмотреть ОригиналОтветить0
WalletDetective
· 07-15 22:24
Так просто v3? Посмотрев, я понял, что ничего не понимаю.
Посмотреть ОригиналОтветить0
gas_guzzler
· 07-15 22:21
Снова зарабатываю на Клиповые купоны.
Посмотреть ОригиналОтветить0
AllInDaddy
· 07-15 21:55
Код V3 действительно жесткий.
Посмотреть ОригиналОтветить0
SleepyValidator
· 07-15 21:55
Говорить так подробно, лучше уж самому закатать исходный код.
7 основных советов по разработке контрактов Uniswap: повышение эффективности и безопасности проектов Децентрализованные финансы
Советы по разработке контрактов: ценный опыт, полученный из кода Uniswap
Недавно, при написании руководства по разработке децентрализованных бирж, я изучал код Uniswap V3 и узнал много приемов разработки контрактов. Как новичку, только начинающему заниматься разработкой Defi контрактов, эти небольшие советы были для меня очень полезными, и я уверен, что они также помогут другим новичкам, желающим изучить разработку контрактов.
Предсказуемый адрес развертывания контракта
Обычно адреса, полученные при развертывании контрактов, выглядят случайными и трудно предсказуемыми. Однако в некоторых случаях нам необходимо сделать вывод о адресе контракта на основе информации о торговых парах и связанных данных, например, для определения прав на сделку или получения адреса пула.
Uniswap использует метод CREATE2 для создания контрактов, добавляя параметр "salt", что делает адрес создаваемого контракта предсказуемым. Логика генерации нового адреса: hash("0xFF", адрес создателя, salt, initcode). Этот метод очень полезен во многих случаях.
Умелое использование функций обратного вызова
Контракты в Solidity могут вызывать друг друга. Иногда A вызывает метод B, и B вызывает A в своем вызываемом методе, что полезно в некоторых сценариях.
Например, в методе swap Uniswap контракт UniswapV3Pool вызывает обратный вызов swapCallback, передавая необходимые для этой транзакции токены. Вызывающая сторона должна передать нужные токены в UniswapV3Pool в обратном вызове, а не разделять метод swap. Это обеспечивает безопасность и целостность выполнения метода swap без необходимости в сложной записи переменных.
Передача информации с помощью исключений, реализация оценки транзакций с помощью try catch
В контракте Quoter Uniswap используется конструкция try catch для выполнения метода swap UniswapV3Pool. Это делается для симуляции swap с целью оценки необходимых токенов для сделки. Во время оценки токены не будут фактически обменены, поэтому возникнет ошибка. Uniswap выбрасывает специальную ошибку в колбэк-функции, а затем перехватывает эту ошибку и извлекает необходимую информацию.
Этот метод кажется хитрым, но он очень практичен. Не нужно модифицировать метод свопа для оценки торгового спроса, логика проще.
Большие числа решают проблемы точности
В коде Uniswap имеется множество вычислительной логики, такой как вычисление токенов для обмена на основе текущей цены и ликвидности. Чтобы избежать потери точности при операции деления, в процессе вычислений часто используется операция "<< FixedPoint96.RESOLUTION", что соответствует смещению влево на 96 бит, эквивалентно умножению на 2^96. После смещения выполняется деление, что обеспечивает точность при нормальных транзакциях без переполнений.
Хотя теоретически все еще будет незначительная потеря точности, это уже приемлемо.
Расчет доходов по методу Share
Uniswap должен записывать доход от комиссий ликвидности для поставщиков ликвидности LP( и ). Очевидно, что нельзя записывать комиссию для каждого LP при каждой сделке, это потребует много газа.
Структура Position в Uniswap содержит feeGrowthInside0LastX128 и feeGrowthInside1LastX128, которые фиксируют комиссионные, причитающиеся каждому ликвидному активу при последнем извлечении комиссионных.
Необходимо просто записывать общую комиссию и комиссию, которую необходимо распределить между каждым ликвидным активом. Комиссия, подлежащая извлечению LP, рассчитывается на основе удерживаемой ликвидности. Это похоже на владение акциями компании: при извлечении дохода нужно просто знать историческую доходность на акцию и доходность при последнем извлечении.
Не ключевую информацию не нужно записывать в блокчейн
Хранение на блокчейне относительно дорого, и не вся информация должна храниться в блокчейне или извлекаться из него. Например, многие интерфейсы, вызываемые фронтендом Uniswap, являются традиционными интерфейсами Web2.
Список торговых пулов, информация и т.д. могут храниться в обычной базе данных, часть из них необходимо периодически синхронизировать с блокчейном. Нет необходимости в реальном времени вызывать RPC-интерфейсы цепочки или узлов для получения соответствующих данных.
Конечно, ключевые сделки должны осуществляться в сети.
Разделение контрактов и использование стандартных контрактов
Проект может содержать несколько фактически развернутых контрактов. Даже если фактически развернут только один, его можно разделить на несколько контрактов для поддержки с помощью наследования.
Как контракт NonfungiblePositionManager Uniswap наследует несколько контрактов. В частности, ERC721Permit напрямую использует контракт ERC721 от OpenZeppelin, что упрощает управление позициями через NFT и повышает эффективность разработки.
Заключение
Практическая разработка упрощенной версии децентрализованной биржи позволит вам глубже понять реализацию кода Uniswap и узнать больше о практических аспектах проектов. Чтение множества статей не заменит практического опыта, надеюсь, что этот опыт будет полезен для новичков, желающих изучить разработку смарт-контрактов.