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