# 受託開発のヒント:Uniswapコードから学んだ教訓最近、分散型取引所のチュートリアルを作成しているときに、Uniswap V3の実装を参考にし、多くの興味深い知識を学びました。DeFi契約開発に初めて触れる初心者として、これらのテクニックは私にとって非常に刺激的であり、スマートコントラクト開発を学びたい他の友人たちにも役立つと信じています。! [Web3ビギナーシリーズ:Uniswapコードから学んだ契約開発のヒント](https://img-cdn.gateio.im/social/moments-6656285ff2f04d804ebeae1a96650aed)## 予測可能な契約アドレス通常デプロイされたコントラクトアドレスはランダムに見えますが、nonce に関連しています。しかし、特定のシナリオでは、取引ペア情報を通じてコントラクトアドレスを推測する必要があります。たとえば、取引権限を判断したり、プールのアドレスを取得したりするためです。UniswapはCREATE2を使用してコントラクトを作成し、saltパラメータを追加しました。このように生成されたコントラクトアドレスは予測可能で、"新しいアドレス = hash('0xFF',作成者のアドレス,salt,initcode)"のロジックに従います。## コールバック関数を巧みに使用するSolidity では、契約間で相互に呼び出すことができます。場合によっては、A 契約が B 契約のメソッドを呼び出し、B が A のメソッドをコールバックすることがあり、これは特定のシナリオで非常に便利です。例えば、Uniswapの取引プロセスでは、UniswapV3Pool契約のswapメソッドを呼び出すと、swapCallbackが呼び出され、実際に必要なTokenの数量が渡されます。呼び出し元はコールバック内で必要なTokenを転送する必要があり、これにより取引ロジック全体の完全性と安全性が確保されます。! [Web3ビギナーシリーズ:Uniswapコードから学んだ契約開発のヒント](https://img-cdn.gateio.im/social/moments-0aaa61a4d43aba7fdeddbc55e3665305)## 異常を使って情報を伝え、try catchを使用して取引の予測を実現するUniswapのQuoterコントラクトでは、UniswapV3Poolのswapメソッドをtry catchで囲んでいます。これは、取引見積もりに必要なトークンをシミュレートするためですが、見積もり時にはトークンを実際に交換しないため、エラーが発生します。Uniswapは、取引コールバック関数内で特殊なエラーをスローし、そのエラーをキャッチして情報を解析することによって機能します。この方法は一見すると回避策のように見えますが、非常に実用的で、需要を予測するためにswapメソッドを特別に改造する必要がありません。## 大きな数値の精度の問題の処理Uniswapのコードには、多くの計算が含まれています。たとえば、現在の価格と流動性に基づいて交換されるTokenの数量を計算します。除算操作による精度の喪失を避けるために、計算プロセスでは"<< FixedPoint96.RESOLUTION"操作が頻繁に使用され、これは2^96を掛けることに相当します。この方法は、通常 uint256 で計算される正常な取引がオーバーフローしないことを保証しつつ、精度も確保できます。理論的には最小単位の精度損失がまだ可能ですが、受け入れ可能な範囲です。! [Web3ビギナーシリーズ:Uniswapコードから学んだ契約開発のヒント](https://img-cdn.gateio.im/social/moments-b0c3d4eb7e8ca88cc4cfc9476a34437a)## シェア方式での収益計算Uniswapでは、流動性提供者(LP)の手数料収益を記録する必要があります。各取引ごとにすべてのLPに手数料を記録するのを避けるため(大量のガスを消費するため)、Uniswapは巧妙な方法を採用しています。Position 構造体には feeGrowthInside0LastX128 と feeGrowthInside1LastX128 が定義されており、各ポジションの前回手数料を引き出した際に、各単位流動性が得るべき手数料が記録されています。これにより、総手数料と各単位流動性の配分額を記録するだけで済み、LP が引き出す際には保有する流動性に基づいて引き出せる手数料が計算されます。! [Web3ビギナーシリーズ:Uniswapコードから学んだ契約開発のヒント](https://img-cdn.gateio.im/social/moments-45e66af69435e6d4412ae506e77ab893)## オンチェーンとオフチェーンの情報取得のバランスオンチェーンストレージは相対的に高価であり、すべての情報がオンチェーンにする必要はなく、またはオンチェーンから取得する必要もありません。たとえば、Uniswapのフロントエンドが呼び出す多くのインターフェースは、従来のWeb2インターフェースです。取引プールのリスト、取引プールの情報などは通常のデータベースに保存でき、定期的にオンチェーンから同期されます。関連データを取得するために、リアルタイムでチェーンやノードサービスのRPCインターフェースを呼び出す必要はありません。一部のブロックチェーンRPCプロバイダーは、高度なインターフェースを提供しており、データをより迅速かつ安価に取得できます。これらのインターフェースは通常、パフォーマンスと効率を向上させるためにキャッシュを使用します。## コントラクト分割と標準コントラクトの利用1つのプロジェクトには、複数の実際に展開された契約が含まれる場合があります。たとえ1つの契約だけが展開されていても、コードは継承を通じて複数の契約に分割して管理することができます。例えば、Uniswap の NonfungiblePositionManager コントラクトは複数のコントラクトを継承しています。その中で ERC721Permit コントラクトは直接 OpenZeppelin の標準 ERC721 コントラクトを使用して実装されており、NFT の方式でポジションを管理するのを便利にし、開発効率も向上させています。## まとめ実践は最良の学習方法です。簡易版の分散型取引所を実装することを試みることで、Uniswap のコード実装をより深く理解し、実際のプロジェクトにおける知識も多く学ぶことができます。これらの経験が Web3 や Defi プロジェクトの開発を志す友人たちに役立つことを願っています。! [Web3ビギナーシリーズ:Uniswapコードから学んだ契約開発のヒント](https://img-cdn.gateio.im/social/moments-f95ddc9d89809cf11dbe65b9bafda157)
Uniswap契約開発7つのテクニック:予測可能なアドレスからオンチェーンオフチェーンのバランスまで
受託開発のヒント:Uniswapコードから学んだ教訓
最近、分散型取引所のチュートリアルを作成しているときに、Uniswap V3の実装を参考にし、多くの興味深い知識を学びました。DeFi契約開発に初めて触れる初心者として、これらのテクニックは私にとって非常に刺激的であり、スマートコントラクト開発を学びたい他の友人たちにも役立つと信じています。
! Web3ビギナーシリーズ:Uniswapコードから学んだ契約開発のヒント
予測可能な契約アドレス
通常デプロイされたコントラクトアドレスはランダムに見えますが、nonce に関連しています。しかし、特定のシナリオでは、取引ペア情報を通じてコントラクトアドレスを推測する必要があります。たとえば、取引権限を判断したり、プールのアドレスを取得したりするためです。
UniswapはCREATE2を使用してコントラクトを作成し、saltパラメータを追加しました。このように生成されたコントラクトアドレスは予測可能で、"新しいアドレス = hash('0xFF',作成者のアドレス,salt,initcode)"のロジックに従います。
コールバック関数を巧みに使用する
Solidity では、契約間で相互に呼び出すことができます。場合によっては、A 契約が B 契約のメソッドを呼び出し、B が A のメソッドをコールバックすることがあり、これは特定のシナリオで非常に便利です。
例えば、Uniswapの取引プロセスでは、UniswapV3Pool契約のswapメソッドを呼び出すと、swapCallbackが呼び出され、実際に必要なTokenの数量が渡されます。呼び出し元はコールバック内で必要なTokenを転送する必要があり、これにより取引ロジック全体の完全性と安全性が確保されます。
! Web3ビギナーシリーズ:Uniswapコードから学んだ契約開発のヒント
異常を使って情報を伝え、try catchを使用して取引の予測を実現する
UniswapのQuoterコントラクトでは、UniswapV3Poolのswapメソッドをtry catchで囲んでいます。これは、取引見積もりに必要なトークンをシミュレートするためですが、見積もり時にはトークンを実際に交換しないため、エラーが発生します。
Uniswapは、取引コールバック関数内で特殊なエラーをスローし、そのエラーをキャッチして情報を解析することによって機能します。この方法は一見すると回避策のように見えますが、非常に実用的で、需要を予測するためにswapメソッドを特別に改造する必要がありません。
大きな数値の精度の問題の処理
Uniswapのコードには、多くの計算が含まれています。たとえば、現在の価格と流動性に基づいて交換されるTokenの数量を計算します。除算操作による精度の喪失を避けるために、計算プロセスでは"<< FixedPoint96.RESOLUTION"操作が頻繁に使用され、これは2^96を掛けることに相当します。
この方法は、通常 uint256 で計算される正常な取引がオーバーフローしないことを保証しつつ、精度も確保できます。理論的には最小単位の精度損失がまだ可能ですが、受け入れ可能な範囲です。
! Web3ビギナーシリーズ:Uniswapコードから学んだ契約開発のヒント
シェア方式での収益計算
Uniswapでは、流動性提供者(LP)の手数料収益を記録する必要があります。各取引ごとにすべてのLPに手数料を記録するのを避けるため(大量のガスを消費するため)、Uniswapは巧妙な方法を採用しています。
Position 構造体には feeGrowthInside0LastX128 と feeGrowthInside1LastX128 が定義されており、各ポジションの前回手数料を引き出した際に、各単位流動性が得るべき手数料が記録されています。これにより、総手数料と各単位流動性の配分額を記録するだけで済み、LP が引き出す際には保有する流動性に基づいて引き出せる手数料が計算されます。
! Web3ビギナーシリーズ:Uniswapコードから学んだ契約開発のヒント
オンチェーンとオフチェーンの情報取得のバランス
オンチェーンストレージは相対的に高価であり、すべての情報がオンチェーンにする必要はなく、またはオンチェーンから取得する必要もありません。たとえば、Uniswapのフロントエンドが呼び出す多くのインターフェースは、従来のWeb2インターフェースです。
取引プールのリスト、取引プールの情報などは通常のデータベースに保存でき、定期的にオンチェーンから同期されます。関連データを取得するために、リアルタイムでチェーンやノードサービスのRPCインターフェースを呼び出す必要はありません。
一部のブロックチェーンRPCプロバイダーは、高度なインターフェースを提供しており、データをより迅速かつ安価に取得できます。これらのインターフェースは通常、パフォーマンスと効率を向上させるためにキャッシュを使用します。
コントラクト分割と標準コントラクトの利用
1つのプロジェクトには、複数の実際に展開された契約が含まれる場合があります。たとえ1つの契約だけが展開されていても、コードは継承を通じて複数の契約に分割して管理することができます。
例えば、Uniswap の NonfungiblePositionManager コントラクトは複数のコントラクトを継承しています。その中で ERC721Permit コントラクトは直接 OpenZeppelin の標準 ERC721 コントラクトを使用して実装されており、NFT の方式でポジションを管理するのを便利にし、開発効率も向上させています。
まとめ
実践は最良の学習方法です。簡易版の分散型取引所を実装することを試みることで、Uniswap のコード実装をより深く理解し、実際のプロジェクトにおける知識も多く学ぶことができます。これらの経験が Web3 や Defi プロジェクトの開発を志す友人たちに役立つことを願っています。
! Web3ビギナーシリーズ:Uniswapコードから学んだ契約開発のヒント