# コントラクト開発のヒント:Uniswapから学んだ教訓最近、分散型取引所プロジェクトを開発する際に、ある有名なDEXのコード実装を参考にし、多くの有用な知識を学びました。Defi契約開発に初めて触れた新米として、これらのテクニックは私にとって非常に刺激的であり、スマートコントラクト開発を学びたい他の友人にも役立つと信じています。! [Web3ビギナーシリーズ:Uniswapコードから学んだ契約開発のヒント](https://img-cdn.gateio.im/social/moments-6656285ff2f04d804ebeae1a96650aed)## 予測可能な契約アドレス通常、デプロイされたコントラクトのアドレスはノンスに関連しているため、ランダムに見えます。しかし、特定のシナリオでは、トランザクションの情報を通じてコントラクトのアドレスを推測する必要があります。例えば、トランザクション権限を判断したり、流動性プールのアドレスを取得したりする場合です。これは、CREATE2方式を使用してコントラクトを作成することによって実現できます。具体的には、コントラクトを作成する際にsaltパラメータを追加します:ソリディティプール= address(new UniswapV3Pool {塩:keccak256(abi.encode(token0、token1、 fee))}());このように生成される契約アドレスは予測可能であり、以下のロジックに従います:新しいアドレス = hash("0xFF", 作成者アドレス、ソルト、initcode)! [Web3ビギナーシリーズ:Uniswapコードから学んだ契約開発のヒント](https://img-cdn.gateio.im/social/moments-0aaa61a4d43aba7fdeddbc55e3665305)## コールバック関数の合理的な使用あるシーンでは、契約間の相互呼び出しが非常に便利です。例えば、AメソッドがBを呼び出し、Bが呼び出されたメソッド内でAをコールバックします。あるDEXでswapメソッドを呼び出して取引する際、swapCallbackが呼び出され、計算された今回の取引に実際に必要なTokenが渡されます。呼び出し元はコールバック内で必要なTokenを取引プールに転送する必要があり、swapメソッドを分割する必要はありません。これにより、swapメソッドの完全な実行が保証され、セキュリティを保証するための煩雑な変数の記録は不要になります。## 異常を利用して情報を伝達する取引の予測を行う際、私たちはswapメソッドをシミュレーションする必要がありますが、実際にはTokenを交換しないため、エラーが発生します。あるDEXは、取引コールバック関数内で特別なエラーをスローし、その後、そのエラーをキャッチして必要な情報を解析することで予測を実現しています。この方法は一見手抜きのように見えますが、とても実用的です。需要の予測のためにスワップ方法を改造する必要がなく、論理がよりシンプルです。! [Web3ビギナーシリーズ:Uniswapコードから学んだ契約開発のヒント](https://img-cdn.gateio.im/social/moments-b0c3d4eb7e8ca88cc4cfc9476a34437a)## 大数を使用して精度の問題を解決する計算に関わるコードでは、除算操作で精度を失わないようにする必要があります。あるDEXでは、"<< FixedPoint96.RESOLUTION" 操作が頻繁に使用され、これは2^96を掛けることに相当します。左シフトしてから除算を行うことで、オーバーフローせずに精度を保証できます。ソリディティuint256 分子 1 = uint256(liquidity) << FixedPoint96.RESOLUTION;uint256 分子 2 = sqrtRatioBX96 - sqrtRatioAX96;amount0 = 分子1 * 分子2 / (sqrtRatioBX96 * sqrtRatioAX96);理論的には依然として精度の損失がある可能性がありますが、通常は最小単位の損失に過ぎず、許容範囲です。## シェア方式による収益計算流動性提供者(LP)の手数料収益計算について、毎回の取引を記録することはできず、大量のガスを消費します。あるDEXは、総手数料を記録し、各流動性が分配される手数料の方法を採用しています。LPの手数料を引き出す際、保有している流動性に基づいて引き出せる金額が計算されます。会社の株式を保有しているのと似ており、収益を引き出す際には、各株の過去の収益と前回の引き出し時の収益を知っていれば十分です。! [Web3ビギナーシリーズ:Uniswapコードから学んだ契約開発のヒント](https://img-cdn.gateio.im/social/moments-45e66af69435e6d4412ae506e77ab893)## 情報の入手方法を選択するオンチェーンストレージは相対的に高価であり、すべての情報がオンチェーンである必要はなく、またオンチェーンから取得する必要もありません。取引プールのリストや情報などは、通常のデータベースに保存し、定期的にオンチェーンから同期することができます。いくつかのブロックチェーンRPCプロバイダーは、高度なインターフェースを提供し、データをより迅速に取得できます。しかし、重要な取引は依然としてチェーン上で行う必要があります。## コントラクトの分割と標準契約の再利用プロジェクトは複数のコントラクトを含む可能性があり、実際に単一のコントラクトをデプロイしても、継承を通じて複数のコントラクトに分割して管理することができます。あるDEXのNFTポジション管理コントラクトは、複数のコントラクトを継承しています:ソリディティcontract NonfungiblePositionManager は INonfungiblePositionManager、 マルチコール, パリフェリーイミュータブルステート、 プールイニシャライザー、 流動性管理、 PeripheryValidation、 セルフパーミット, ERC721パーミット{...}同時に、OpenZeppelinのERC721標準契約を使用しており、ポジションの管理が容易で、開発効率も向上しています。## サマリー簡易版の分散型取引所を自分で開発することで、成熟したプロジェクトのコード実装をより深く理解し、実際の知識を多く学ぶことができます。これらの小さなヒントがあなたのインスピレーションになれば幸いです。開発が順調に進むことを願っています!! [Web3ビギナーシリーズ:Uniswapコードから学んだ契約開発のヒント](https://img-cdn.gateio.im/social/moments-f95ddc9d89809cf11dbe65b9bafda157)
主流DEX契約開発のための7つの実用的なヒント
コントラクト開発のヒント:Uniswapから学んだ教訓
最近、分散型取引所プロジェクトを開発する際に、ある有名なDEXのコード実装を参考にし、多くの有用な知識を学びました。Defi契約開発に初めて触れた新米として、これらのテクニックは私にとって非常に刺激的であり、スマートコントラクト開発を学びたい他の友人にも役立つと信じています。
! Web3ビギナーシリーズ:Uniswapコードから学んだ契約開発のヒント
予測可能な契約アドレス
通常、デプロイされたコントラクトのアドレスはノンスに関連しているため、ランダムに見えます。しかし、特定のシナリオでは、トランザクションの情報を通じてコントラクトのアドレスを推測する必要があります。例えば、トランザクション権限を判断したり、流動性プールのアドレスを取得したりする場合です。
これは、CREATE2方式を使用してコントラクトを作成することによって実現できます。具体的には、コントラクトを作成する際にsaltパラメータを追加します:
ソリディティ プール= address(new UniswapV3Pool {塩:keccak256(abi.encode(token0、token1、 fee))}());
このように生成される契約アドレスは予測可能であり、以下のロジックに従います:
新しいアドレス = hash("0xFF", 作成者アドレス、ソルト、initcode)
! Web3ビギナーシリーズ:Uniswapコードから学んだ契約開発のヒント
コールバック関数の合理的な使用
あるシーンでは、契約間の相互呼び出しが非常に便利です。例えば、AメソッドがBを呼び出し、Bが呼び出されたメソッド内でAをコールバックします。
あるDEXでswapメソッドを呼び出して取引する際、swapCallbackが呼び出され、計算された今回の取引に実際に必要なTokenが渡されます。呼び出し元はコールバック内で必要なTokenを取引プールに転送する必要があり、swapメソッドを分割する必要はありません。これにより、swapメソッドの完全な実行が保証され、セキュリティを保証するための煩雑な変数の記録は不要になります。
異常を利用して情報を伝達する
取引の予測を行う際、私たちはswapメソッドをシミュレーションする必要がありますが、実際にはTokenを交換しないため、エラーが発生します。あるDEXは、取引コールバック関数内で特別なエラーをスローし、その後、そのエラーをキャッチして必要な情報を解析することで予測を実現しています。
この方法は一見手抜きのように見えますが、とても実用的です。需要の予測のためにスワップ方法を改造する必要がなく、論理がよりシンプルです。
! Web3ビギナーシリーズ:Uniswapコードから学んだ契約開発のヒント
大数を使用して精度の問題を解決する
計算に関わるコードでは、除算操作で精度を失わないようにする必要があります。あるDEXでは、"<< FixedPoint96.RESOLUTION" 操作が頻繁に使用され、これは2^96を掛けることに相当します。左シフトしてから除算を行うことで、オーバーフローせずに精度を保証できます。
ソリディティ uint256 分子 1 = uint256(liquidity) << FixedPoint96.RESOLUTION; uint256 分子 2 = sqrtRatioBX96 - sqrtRatioAX96; amount0 = 分子1 * 分子2 / (sqrtRatioBX96 * sqrtRatioAX96);
理論的には依然として精度の損失がある可能性がありますが、通常は最小単位の損失に過ぎず、許容範囲です。
シェア方式による収益計算
流動性提供者(LP)の手数料収益計算について、毎回の取引を記録することはできず、大量のガスを消費します。あるDEXは、総手数料を記録し、各流動性が分配される手数料の方法を採用しています。
LPの手数料を引き出す際、保有している流動性に基づいて引き出せる金額が計算されます。会社の株式を保有しているのと似ており、収益を引き出す際には、各株の過去の収益と前回の引き出し時の収益を知っていれば十分です。
! Web3ビギナーシリーズ:Uniswapコードから学んだ契約開発のヒント
情報の入手方法を選択する
オンチェーンストレージは相対的に高価であり、すべての情報がオンチェーンである必要はなく、またオンチェーンから取得する必要もありません。取引プールのリストや情報などは、通常のデータベースに保存し、定期的にオンチェーンから同期することができます。
いくつかのブロックチェーンRPCプロバイダーは、高度なインターフェースを提供し、データをより迅速に取得できます。しかし、重要な取引は依然としてチェーン上で行う必要があります。
コントラクトの分割と標準契約の再利用
プロジェクトは複数のコントラクトを含む可能性があり、実際に単一のコントラクトをデプロイしても、継承を通じて複数のコントラクトに分割して管理することができます。
あるDEXのNFTポジション管理コントラクトは、複数のコントラクトを継承しています:
ソリディティ contract NonfungiblePositionManager は INonfungiblePositionManager、 マルチコール, パリフェリーイミュータブルステート、 プールイニシャライザー、 流動性管理、 PeripheryValidation、 セルフパーミット, ERC721パーミット {...}
同時に、OpenZeppelinのERC721標準契約を使用しており、ポジションの管理が容易で、開発効率も向上しています。
サマリー
簡易版の分散型取引所を自分で開発することで、成熟したプロジェクトのコード実装をより深く理解し、実際の知識を多く学ぶことができます。これらの小さなヒントがあなたのインスピレーションになれば幸いです。開発が順調に進むことを願っています!
! Web3ビギナーシリーズ:Uniswapコードから学んだ契約開発のヒント