# 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がコールバックされ、今回の取引で実際に必要なTokenが渡されます。呼び出し元はコールバック内で必要なTokenをUniswapV3Poolに転送する必要があり、swapメソッドを二つに分割する必要はありません。これにより、swapメソッドの安全性と完全な実行が保証され、煩雑な変数の記録が不要になります。## 例外を使用して情報を渡し、catch を試してトランザクションを推定しますUniswapのQuoterコントラクトでは、UniswapV3Poolのswapメソッドをtry catchで囲んで実行します。これは、swapメソッドが取引に必要なTokenを予測するためですが、予測時には実際にTokenの交換は行われないため、エラーが発生します。Uniswapは、取引コールバック関数内で特別なエラーを投げ、そのエラーをキャッチしてエラーメッセージから必要な情報を解析します。この方法は一見抜け道のように見えますが、実用的で、取引需要の予測のためにスワップメソッドを改造する必要がなく、ロジックもシンプルです。! [Web3ビギナーシリーズ:Uniswapコードから学んだ契約開発のヒント](https://img-cdn.gateio.im/social/moments-b0c3d4eb7e8ca88cc4cfc9476a34437a)## 大きな数を使用して精度の問題を解決するUniswapコードには、多くの計算ロジックがあります。現在の価格と流動性に基づいてトークンの交換を計算します。除算操作による精度の損失を避けるため、計算プロセスでは頻繁に「<< FixedPoint96.RESOLUTION」操作を使用します。これは、96ビット左シフトすることを意味し、2^96倍に相当します。左に移動した後に除算を行うことで、通常の取引でオーバーフローが発生しない場合に精度を保証できます。理論的には最小単位の精度が失われることがありますが、これは許容範囲内です。## シェア方式で収益を計算するUniswapは、LP(流動性提供者)の手数料収益を記録する必要があります。各取引ごとにすべてのLPの手数料を記録して大量のGasを消費しないように、Uniswapは巧妙な方法を採用しました。Position構造体にはfeeGrowthInside0LastX128とfeeGrowthInside1LastX128が含まれており、各ポジションの前回の手数料引き出し時に各流動性が受け取るべき手数料を記録しています。総手数料と各流動性に割り当てられる手数料を記録するだけで、LPが引き出す際には保有する流動性に基づいて引き出せる手数料を計算すればよいです。! [Web3ビギナーシリーズ:Uniswapコードから学んだ契約開発のヒント](https://img-cdn.gateio.im/social/moments-45e66af69435e6d4412ae506e77ab893)## オンチェーン情報取得戦略すべての情報がオンチェーンから取得される必要はありません。オンチェーンのストレージは比較的高価であり、多くの情報は通常のデータベースに保存され、定期的にオンチェーンから同期されることができます。取引プールのリストや取引プールの情報などは、通常のデータベースに保存でき、リアルタイムでチェーンやノードサービスのRPCインターフェースを呼び出す必要はありません。当然、重要な取引は依然としてチェーン上で行われます。## 契約分割と標準契約の利用率プロジェクトには、複数の実際にデプロイされた契約が含まれる場合があります。実際にデプロイされている契約が1つだけであっても、コードは継承の方法を通じて複数の契約に分割して維持することができます。例えば、UniswapのNonfungiblePositionManagerコントラクトは、複数のコントラクトを継承しています。OpenZeppelinのERC721コントラクトを使用することで、NFTを通じてポジションを管理するのが便利で、開発効率も向上します。## まとめ実践は最良の学習方法です。簡易版の分散型取引所を実装してみることで、Uniswapのコード実装を深く理解し、実際のプロジェクトにおける知識をさらに学ぶことができます。Web3やDefiプロジェクトの開発に興味がある方は、関連する実戦コースを参考にして、段階的に簡易版取引所を完成させることができます。! [Web3ビギナーシリーズ:Uniswapコードから学んだ契約開発のヒント](https://img-cdn.gateio.im/social/moments-f95ddc9d89809cf11dbe65b9bafda157)
Uniswapコードの秘密:Defi初心者を助ける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がコールバックされ、今回の取引で実際に必要なTokenが渡されます。呼び出し元はコールバック内で必要なTokenをUniswapV3Poolに転送する必要があり、swapメソッドを二つに分割する必要はありません。これにより、swapメソッドの安全性と完全な実行が保証され、煩雑な変数の記録が不要になります。
例外を使用して情報を渡し、catch を試してトランザクションを推定します
UniswapのQuoterコントラクトでは、UniswapV3Poolのswapメソッドをtry catchで囲んで実行します。これは、swapメソッドが取引に必要なTokenを予測するためですが、予測時には実際にTokenの交換は行われないため、エラーが発生します。
Uniswapは、取引コールバック関数内で特別なエラーを投げ、そのエラーをキャッチしてエラーメッセージから必要な情報を解析します。この方法は一見抜け道のように見えますが、実用的で、取引需要の予測のためにスワップメソッドを改造する必要がなく、ロジックもシンプルです。
! Web3ビギナーシリーズ:Uniswapコードから学んだ契約開発のヒント
大きな数を使用して精度の問題を解決する
Uniswapコードには、多くの計算ロジックがあります。現在の価格と流動性に基づいてトークンの交換を計算します。除算操作による精度の損失を避けるため、計算プロセスでは頻繁に「<< FixedPoint96.RESOLUTION」操作を使用します。これは、96ビット左シフトすることを意味し、2^96倍に相当します。
左に移動した後に除算を行うことで、通常の取引でオーバーフローが発生しない場合に精度を保証できます。理論的には最小単位の精度が失われることがありますが、これは許容範囲内です。
シェア方式で収益を計算する
Uniswapは、LP(流動性提供者)の手数料収益を記録する必要があります。各取引ごとにすべてのLPの手数料を記録して大量のGasを消費しないように、Uniswapは巧妙な方法を採用しました。
Position構造体にはfeeGrowthInside0LastX128とfeeGrowthInside1LastX128が含まれており、各ポジションの前回の手数料引き出し時に各流動性が受け取るべき手数料を記録しています。総手数料と各流動性に割り当てられる手数料を記録するだけで、LPが引き出す際には保有する流動性に基づいて引き出せる手数料を計算すればよいです。
! Web3ビギナーシリーズ:Uniswapコードから学んだ契約開発のヒント
オンチェーン情報取得戦略
すべての情報がオンチェーンから取得される必要はありません。オンチェーンのストレージは比較的高価であり、多くの情報は通常のデータベースに保存され、定期的にオンチェーンから同期されることができます。
取引プールのリストや取引プールの情報などは、通常のデータベースに保存でき、リアルタイムでチェーンやノードサービスのRPCインターフェースを呼び出す必要はありません。当然、重要な取引は依然としてチェーン上で行われます。
契約分割と標準契約の利用率
プロジェクトには、複数の実際にデプロイされた契約が含まれる場合があります。実際にデプロイされている契約が1つだけであっても、コードは継承の方法を通じて複数の契約に分割して維持することができます。
例えば、UniswapのNonfungiblePositionManagerコントラクトは、複数のコントラクトを継承しています。OpenZeppelinのERC721コントラクトを使用することで、NFTを通じてポジションを管理するのが便利で、開発効率も向上します。
まとめ
実践は最良の学習方法です。簡易版の分散型取引所を実装してみることで、Uniswapのコード実装を深く理解し、実際のプロジェクトにおける知識をさらに学ぶことができます。Web3やDefiプロジェクトの開発に興味がある方は、関連する実戦コースを参考にして、段階的に簡易版取引所を完成させることができます。
! Web3ビギナーシリーズ:Uniswapコードから学んだ契約開発のヒント