# 契約開発の実用的なヒント:Uniswapのコードから得た経験最近、分散型取引所のチュートリアルを開発している際に、Uniswap V3のコード実装を参考にし、多くの興味深い知識を学びました。Defiコントラクトの開発に初めて挑戦する開発者として、これらのテクニックはコントラクト開発を学びたい初心者にとって非常に役立つでしょう。次に、これらの実用的な小技を見てみましょう。中には奇妙な技術やトリックと呼べるものもあります。! [Web3ビギナーシリーズ:Uniswapコードから学んだ契約開発のヒント](https://img-cdn.gateio.im/social/moments-6656285ff2f04d804ebeae1a96650aed)## 予測契約のデプロイ先アドレス通常の場合、デプロイされたコントラクトから得られるアドレスはランダムに見えます。これはnonceに関連しており、予測が難しいためです。しかし、特定のシナリオでは、取引ペアや関連情報を通じてコントラクトアドレスを推測する必要があります。これは、取引権限を判断したり、プールのアドレスを取得したりするのに非常に役立ちます。UniswapはCREATE2を使用して契約を作成し、saltパラメータを追加することで生成された契約アドレスを予測可能にします。新しいアドレスの生成ロジックは:hash("0xFF", 作成者アドレス, salt, initcode)です。この方法により、契約アドレスが予測可能になり、後続の操作が容易になります。! [Web3ビギナーシリーズ:Uniswapコードから学んだ契約開発のヒント](https://img-cdn.gateio.im/social/moments-0aaa61a4d43aba7fdeddbc55e3665305)## コールバック関数の巧妙な使い方Solidityでは、コントラクト同士が相互に呼び出すことができます。一般的なシナリオの一つは、AメソッドがBを呼び出し、Bが呼び出されたメソッド内でAをコールバックすることです。これは特定の状況で非常に便利です。Uniswapを例にとると、UniswapV3Poolコントラクトのswapメソッドを呼び出して取引を行うと、swapCallbackが呼び出され、計算された今回の取引に実際に必要なトークンが渡されます。呼び出し元はコールバック内で取引に必要なトークンをUniswapV3Poolに転送する必要があります。この設計により、swapメソッドの完全な実行と安全性が確保され、面倒な変数の記録は不要になります。## 例外を使用して情報を渡し、catch を試してトランザクションを推定しますUniswapのQuoterコントラクトでは、UniswapV3Poolのswapメソッドを実行する際にtry catchで包みます。これは、swapメソッドをシミュレートして取引に必要なTokenを予測するためです。予測時には実際にTokenの交換が行われないため、エラーが発生します。Uniswapは取引のコールバック関数内で特別なエラーを投げ、そのエラーをキャッチして必要な情報を解析します。この方法は見かけ上は近道のように見えますが、とても実用的です。これは、取引需要を予測するためにスワップ方式を改造することを避け、論理をより簡潔にします。! [Web3ビギナーシリーズ:Uniswapコードから学んだ契約開発のヒント](https://img-cdn.gateio.im/social/moments-b0c3d4eb7e8ca88cc4cfc9476a34437a)## 大数を使って精度の問題を解決するUniswapのコードには、多くの計算ロジックが関与しており、現在の価格と流動性に基づいてトークンの交換を計算します。除算操作による精度の喪失を避けるために、Uniswapは頻繁に「<< FixedPoint96.RESOLUTION」操作を使用します。これは96ビット左シフトすることで、2^96を掛けることに相当します。先に左シフトしてから除算を行うことで、通常の取引ではオーバーフローせずに(はuint256で計算され、)の精度が保証されます。理論的にはわずかな精度の損失があるものの、その程度の誤差は通常受け入れられます。## シェア方式で収益を計算するUniswapはLP(流動性提供者)の手数料収益を記録する必要があります。各取引ごとにすべてのLPの手数料を記録して大量のGasを消費するのを避けるために、Uniswapは巧妙な方法を採用しています。Position構造体では、feeGrowthInside0LastX128とfeeGrowthInside1LastX128が定義されており、各ポジションの前回の手数料引き出し時に各流動性が受け取るべき手数料を記録します。これにより、総手数料と各流動性が配分されるべき手数料を記録するだけで済み、LPが引き出す際には保有する流動性に基づいて引き出せる手数料を計算できます。これは株式の配当メカニズムに似ており、引き出す際には会社の歴史的な一株当たり利益と前回の引き出し時の利益を知っているだけで済みます。! [Web3ビギナーシリーズ:Uniswapコードから学んだ契約開発のヒント](https://img-cdn.gateio.im/social/moments-45e66af69435e6d4412ae506e77ab893)## 情報を得る正しい方法を選ぶオンチェーンストレージは比較的高価であるため、すべての情報がオンチェーンである必要はなく、オンチェーンから取得する必要もありません。例えば、Uniswapのフロントエンドウェブサイトが呼び出す多くのインターフェースは従来のWeb2インターフェースです。取引プールのリスト、取引プールの情報などは通常のデータベースに保存できますが、一部のデータは定期的にブロックチェーンから同期する必要がありますが、関連データを取得するためにリアルタイムでブロックチェーンまたはノードサービスのRPCインターフェースを呼び出す必要はありません。いくつかのブロックチェーンRPCプロバイダーは、高度なインターフェースを提供しており、特定のデータをより迅速かつ経済的に取得できます。これらのインターフェースは通常、パフォーマンスと効率を向上させるためにキャッシュを利用しています。もちろん、重要な取引は依然としてチェーン上で行う必要があります。## 既存の標準契約を分割して活用する方法を学ぶプロジェクトには、複数の実際にデプロイされたコントラクトが含まれる可能性があります。実際にデプロイされているコントラクトが1つだけであっても、継承の方法を通じてコントラクトを複数の部分に分割して維持することができます。例えば、UniswapのNonfungiblePositionManagerコントラクトは複数のコントラクトを継承しています。ERC721Permitコントラクトを実装する際に、直接@openzeppelin/contracts/token/ERC721/ERC721.solコントラクトを使用しました。これにより、NFT方式でポジションを管理することが便利になり、既存の標準コントラクトを利用して開発効率を向上させることができます。## サマリー簡易版の分散型取引所を実際に開発することで、Uniswapのコード実装をより深く理解でき、実際のプロジェクトでの知識も多く学べます。これらのテクニックは、契約開発を学びたい初心者にとって非常に役立つと信じています。! [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)です。この方法により、契約アドレスが予測可能になり、後続の操作が容易になります。
! Web3ビギナーシリーズ:Uniswapコードから学んだ契約開発のヒント
コールバック関数の巧妙な使い方
Solidityでは、コントラクト同士が相互に呼び出すことができます。一般的なシナリオの一つは、AメソッドがBを呼び出し、Bが呼び出されたメソッド内でAをコールバックすることです。これは特定の状況で非常に便利です。
Uniswapを例にとると、UniswapV3Poolコントラクトのswapメソッドを呼び出して取引を行うと、swapCallbackが呼び出され、計算された今回の取引に実際に必要なトークンが渡されます。呼び出し元はコールバック内で取引に必要なトークンをUniswapV3Poolに転送する必要があります。この設計により、swapメソッドの完全な実行と安全性が確保され、面倒な変数の記録は不要になります。
例外を使用して情報を渡し、catch を試してトランザクションを推定します
UniswapのQuoterコントラクトでは、UniswapV3Poolのswapメソッドを実行する際にtry catchで包みます。これは、swapメソッドをシミュレートして取引に必要なTokenを予測するためです。予測時には実際にTokenの交換が行われないため、エラーが発生します。Uniswapは取引のコールバック関数内で特別なエラーを投げ、そのエラーをキャッチして必要な情報を解析します。
この方法は見かけ上は近道のように見えますが、とても実用的です。これは、取引需要を予測するためにスワップ方式を改造することを避け、論理をより簡潔にします。
! Web3ビギナーシリーズ:Uniswapコードから学んだ契約開発のヒント
大数を使って精度の問題を解決する
Uniswapのコードには、多くの計算ロジックが関与しており、現在の価格と流動性に基づいてトークンの交換を計算します。除算操作による精度の喪失を避けるために、Uniswapは頻繁に「<< FixedPoint96.RESOLUTION」操作を使用します。これは96ビット左シフトすることで、2^96を掛けることに相当します。先に左シフトしてから除算を行うことで、通常の取引ではオーバーフローせずに(はuint256で計算され、)の精度が保証されます。
理論的にはわずかな精度の損失があるものの、その程度の誤差は通常受け入れられます。
シェア方式で収益を計算する
UniswapはLP(流動性提供者)の手数料収益を記録する必要があります。各取引ごとにすべてのLPの手数料を記録して大量のGasを消費するのを避けるために、Uniswapは巧妙な方法を採用しています。
Position構造体では、feeGrowthInside0LastX128とfeeGrowthInside1LastX128が定義されており、各ポジションの前回の手数料引き出し時に各流動性が受け取るべき手数料を記録します。これにより、総手数料と各流動性が配分されるべき手数料を記録するだけで済み、LPが引き出す際には保有する流動性に基づいて引き出せる手数料を計算できます。これは株式の配当メカニズムに似ており、引き出す際には会社の歴史的な一株当たり利益と前回の引き出し時の利益を知っているだけで済みます。
! Web3ビギナーシリーズ:Uniswapコードから学んだ契約開発のヒント
情報を得る正しい方法を選ぶ
オンチェーンストレージは比較的高価であるため、すべての情報がオンチェーンである必要はなく、オンチェーンから取得する必要もありません。例えば、Uniswapのフロントエンドウェブサイトが呼び出す多くのインターフェースは従来のWeb2インターフェースです。
取引プールのリスト、取引プールの情報などは通常のデータベースに保存できますが、一部のデータは定期的にブロックチェーンから同期する必要がありますが、関連データを取得するためにリアルタイムでブロックチェーンまたはノードサービスのRPCインターフェースを呼び出す必要はありません。
いくつかのブロックチェーンRPCプロバイダーは、高度なインターフェースを提供しており、特定のデータをより迅速かつ経済的に取得できます。これらのインターフェースは通常、パフォーマンスと効率を向上させるためにキャッシュを利用しています。
もちろん、重要な取引は依然としてチェーン上で行う必要があります。
既存の標準契約を分割して活用する方法を学ぶ
プロジェクトには、複数の実際にデプロイされたコントラクトが含まれる可能性があります。実際にデプロイされているコントラクトが1つだけであっても、継承の方法を通じてコントラクトを複数の部分に分割して維持することができます。
例えば、UniswapのNonfungiblePositionManagerコントラクトは複数のコントラクトを継承しています。ERC721Permitコントラクトを実装する際に、直接@openzeppelin/contracts/token/ERC721/ERC721.solコントラクトを使用しました。これにより、NFT方式でポジションを管理することが便利になり、既存の標準コントラクトを利用して開発効率を向上させることができます。
サマリー
簡易版の分散型取引所を実際に開発することで、Uniswapのコード実装をより深く理解でき、実際のプロジェクトでの知識も多く学べます。これらのテクニックは、契約開発を学びたい初心者にとって非常に役立つと信じています。
! Web3ビギナーシリーズ:Uniswapコードから学んだ契約開発のヒント