Поради щодо розробки контрактів: безцінний досвід, отриманий з коду 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, метод swap UniswapV3Pool обгорнутий у блок try catch. Це робиться для моделювання свопу для оцінки необхідних токенів для угоди. При оцінці токени насправді не обмінюються, тому виникає помилка. Uniswap викликає спеціальну помилку в зворотному виклику, а потім ловить цю помилку і витягує необхідну інформацію.
Цей метод здається хитрим, але дуже практичний. Не потрібно модифікувати метод swap для оцінки торгових потреб, логіка простіша.
Вирішення проблеми точності великими числами
В коді Uniswap міститься безліч обчислювальної логіки, наприклад, обчислення токенів для обміну на основі поточної ціни та ліквідності. Щоб уникнути втрати точності під час операцій ділення, під час обчислень часто використовують операцію "<< FixedPoint96.RESOLUTION", тобто зсув вліво на 96 біт, що еквівалентно множенню на 2^96. Після зсуву проводиться ділення, що забезпечує точність за умов нормальної торгівлі без переповнення.
Хоча теоретично все ще можуть бути незначні втрати точності, це вже прийнятно.
Розрахунок доходу за допомогою Share
Uniswap повинен записувати дохід від комісії ліквідності LP( для постачальника ліквідності ). Очевидно, що не можна кожного разу під час угоди записувати комісію для кожного LP, це споживе багато Gas.
Структура 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, метод swap UniswapV3Pool обгорнутий у блок try catch. Це робиться для моделювання свопу для оцінки необхідних токенів для угоди. При оцінці токени насправді не обмінюються, тому виникає помилка. Uniswap викликає спеціальну помилку в зворотному виклику, а потім ловить цю помилку і витягує необхідну інформацію.
Цей метод здається хитрим, але дуже практичний. Не потрібно модифікувати метод swap для оцінки торгових потреб, логіка простіша.
Вирішення проблеми точності великими числами
В коді Uniswap міститься безліч обчислювальної логіки, наприклад, обчислення токенів для обміну на основі поточної ціни та ліквідності. Щоб уникнути втрати точності під час операцій ділення, під час обчислень часто використовують операцію "<< FixedPoint96.RESOLUTION", тобто зсув вліво на 96 біт, що еквівалентно множенню на 2^96. Після зсуву проводиться ділення, що забезпечує точність за умов нормальної торгівлі без переповнення.
Хоча теоретично все ще можуть бути незначні втрати точності, це вже прийнятно.
Розрахунок доходу за допомогою Share
Uniswap повинен записувати дохід від комісії ліквідності LP( для постачальника ліквідності ). Очевидно, що не можна кожного разу під час угоди записувати комісію для кожного LP, це споживе багато Gas.
Структура Position в Uniswap містить feeGrowthInside0LastX128 та feeGrowthInside1LastX128, які фіксують комісійні збори, які має отримати кожна ліквідність під час останнього їх вилучення.
Необхідно лише зафіксувати загальні комісії та комісії, які слід розподілити між кожним ліквідним активом. Під час виведення LP комісії можуть бути розраховані на основі утримуваних ліквідних активів. Це схоже на володіння акціями компанії, під час виведення прибутку потрібно знати лише історичний прибуток на акцію та прибуток під час останнього виведення.
Неключова інформація не потребує запису в блокчейн
Зберігання в мережі коштує相对昂贵, і не вся інформація повинна бути в мережі або отримуватись з мережі. Наприклад, багато інтерфейсів, які викликає фронтальний інтерфейс Uniswap, є традиційними інтерфейсами Web2.
Список торгових пулів, інформація тощо можуть зберігатися в звичайній базі даних, частина з них повинна періодично синхронізуватися з блокчейном. Немає необхідності в реальному часі викликати RPC-інтерфейси ланцюга або вузлів для отримання відповідних даних.
Звичайно, ключові угоди повинні проводитися в мережі.
Розділення контракту та використання стандартного контракту
Проект може містити кілька реально розгорнутого контракту. Навіть якщо насправді розгорнуто лише один, його можна розділити на кілька контрактів через успадкування.
Як контракт NonfungiblePositionManager Uniswap успадкував кілька контрактів. Серед них ERC721Permit безпосередньо використовує контракт ERC721 від OpenZeppelin, що полегшує управління позиціями через NFT і підвищує ефективність розробки.
Висновок
Особисте практичне розроблення спрощеної версії децентралізованої біржі дозволить вам глибше зрозуміти реалізацію коду Uniswap та навчитися більше практичних аспектів. Читати багато статей не зрівняється з практичною роботою, сподіваюся, що цей досвід буде корисним для новачків, які хочуть навчитися розробці контрактів.