Techniques de développement de contrats apprises à partir du code Uniswap
Récemment, en rédigeant un tutoriel sur le développement d'échanges décentralisés, j'ai consulté l'implémentation du code de Uniswap V3 et j'ai appris de nombreux points de connaissance précieux. En tant que développeur qui tente pour la première fois de développer des contrats Defi, ces astuces seront très utiles pour les débutants souhaitant apprendre le développement de contrats.
Adresse de déploiement de contrat prévisible
L'adresse obtenue par le déploiement d'un contrat semble généralement aléatoire, car elle est liée au nonce. Cependant, dans certains cas, nous devons déduire l'adresse du contrat à partir des paires de transactions et des informations connexes, par exemple pour déterminer les droits de transaction ou obtenir l'adresse de la piscine.
Uniswap utilise la méthode CREATE2 pour créer des contrats, en ajoutant un paramètre salt pour rendre l'adresse générée prévisible. La logique de calcul de la nouvelle adresse est : hash("0xFF", adresse du créateur, salt, initcode).
Utilisation intelligente des fonctions de rappel
Dans Solidity, les contrats peuvent s'appeler mutuellement. Dans certains cas, il est très utile que A appelle la méthode de B et que B rappelle A dans la méthode appelée.
Dans Uniswap, lors de l'appel de la méthode swap du contrat UniswapV3Pool pour effectuer une transaction, cela déclenche un rappel swapCallback, passant le Token réellement nécessaire pour cette transaction. L'appelant doit transférer le Token requis dans UniswapV3Pool lors du rappel, plutôt que de diviser la méthode swap en deux parties. Cela garantit la sécurité et l'exécution complète de la méthode swap, sans nécessiter un enregistrement complexe des variables.
Utiliser des exceptions pour transmettre des informations, réaliser une estimation de transaction avec try catch
Dans le contrat Quoter d'Uniswap, la méthode swap de UniswapV3Pool est exécutée à l'aide d'un try catch. Cela permet de simuler l'estimation des tokens nécessaires pour la transaction de swap, mais pendant l'estimation, aucun échange de tokens réel n'a lieu, donc une erreur sera générée.
Uniswap obtient les informations requises en lançant une erreur spéciale dans la fonction de rappel de transaction, puis en capturant cette erreur pour en extraire les informations nécessaires. Cette méthode peut sembler astucieuse, mais elle est très pratique, car elle ne nécessite pas de modifier la méthode swap pour estimer la demande de transaction, et la logique est également plus simple.
Utiliser des nombres grands pour résoudre les problèmes de précision
Dans le code d'Uniswap, il existe de nombreuses logiques de calcul, telles que le calcul des tokens échangés en fonction du prix actuel et de la liquidité. Pour éviter la perte de précision lors des opérations de division, le processus de calcul utilise souvent l'opération "<< FixedPoint96.RESOLUTION", ce qui correspond à un décalage à gauche de 96 bits, équivalent à multiplier par 2^96.
Après un décalage à gauche, effectuer une opération de division peut garantir la précision sans débordement dans des transactions normales. Bien qu'il y ait toujours une perte de précision au niveau de l'unité minimale en théorie, cela est acceptable.
Calcul des revenus par la méthode Share
Uniswap doit enregistrer les revenus de frais du fournisseur de liquidité LP(. Pour éviter de consommer une grande quantité de Gas en enregistrant les frais pour chaque LP à chaque transaction, Uniswap a adopté une méthode astucieuse.
La structure Position contient feeGrowthInside0LastX128 et feeGrowthInside1LastX128, qui enregistrent les frais de transaction que chaque position a droit à la dernière fois qu'ils ont retiré des frais. Il suffit d'enregistrer les frais totaux et les frais à répartir pour chaque liquidité, et lors du retrait par le LP, les frais récupérables sont calculés en fonction de la liquidité détenue.
![Série pour débutants Web3 : Astuces de développement de contrats que j'ai apprises du code Uniswap])https://img-cdn.gateio.im/webp-social/moments-45e66af69435e6d4412ae506e77ab893.webp(
Stratégie d'obtention d'informations sur la chaîne
Toutes les informations ne doivent pas nécessairement être obtenues sur la chaîne. Le stockage sur la chaîne est relativement coûteux, de nombreuses informations peuvent être stockées dans des bases de données ordinaires et synchronisées régulièrement depuis la chaîne.
Des éléments tels que la liste des pools de transactions et les informations sur les pools de transactions peuvent être stockés dans une base de données ordinaire, sans avoir besoin d'appeler en temps réel l'interface RPC de la chaîne ou des nœuds. Bien sûr, les transactions clés se déroulent toujours sur la chaîne.
Fractionnement de contrat et utilisation des contrats standard
Un projet peut contenir plusieurs contrats réellement déployés. Même si un seul contrat est réellement déployé, le code peut également être divisé en plusieurs contrats à maintenir par héritage.
Par exemple, le contrat NonfungiblePositionManager d'Uniswap hérite de plusieurs contrats. En utilisant le contrat ERC721 d'OpenZeppelin, il est à la fois pratique de gérer des positions via des NFT et d'améliorer l'efficacité du développement.
Conclusion
La pratique est la meilleure méthode d'apprentissage. Essayer de réaliser une version simplifiée d'une bourse décentralisée permet de comprendre en profondeur l'implémentation du code d'Uniswap et d'apprendre davantage de points de connaissance dans des projets pratiques. Si vous êtes intéressé par le développement de projets Web3 et DeFi, vous pouvez consulter des cours pratiques pertinents pour terminer progressivement une bourse simplifiée.
![Web3 Débutant Série : Les petites astuces de développement de contrats que j'ai apprises du code Uniswap])https://img-cdn.gateio.im/webp-social/moments-f95ddc9d89809cf11dbe65b9bafda157.webp(
Cette page peut inclure du contenu de tiers fourni à des fins d'information uniquement. Gate ne garantit ni l'exactitude ni la validité de ces contenus, n’endosse pas les opinions exprimées, et ne fournit aucun conseil financier ou professionnel à travers ces informations. Voir la section Avertissement pour plus de détails.
Dévoilement du code Uniswap : 7 astuces de développement de contrats pour aider les Débutants en Defi
Techniques de développement de contrats apprises à partir du code Uniswap
Récemment, en rédigeant un tutoriel sur le développement d'échanges décentralisés, j'ai consulté l'implémentation du code de Uniswap V3 et j'ai appris de nombreux points de connaissance précieux. En tant que développeur qui tente pour la première fois de développer des contrats Defi, ces astuces seront très utiles pour les débutants souhaitant apprendre le développement de contrats.
Adresse de déploiement de contrat prévisible
L'adresse obtenue par le déploiement d'un contrat semble généralement aléatoire, car elle est liée au nonce. Cependant, dans certains cas, nous devons déduire l'adresse du contrat à partir des paires de transactions et des informations connexes, par exemple pour déterminer les droits de transaction ou obtenir l'adresse de la piscine.
Uniswap utilise la méthode CREATE2 pour créer des contrats, en ajoutant un paramètre salt pour rendre l'adresse générée prévisible. La logique de calcul de la nouvelle adresse est : hash("0xFF", adresse du créateur, salt, initcode).
Utilisation intelligente des fonctions de rappel
Dans Solidity, les contrats peuvent s'appeler mutuellement. Dans certains cas, il est très utile que A appelle la méthode de B et que B rappelle A dans la méthode appelée.
Dans Uniswap, lors de l'appel de la méthode swap du contrat UniswapV3Pool pour effectuer une transaction, cela déclenche un rappel swapCallback, passant le Token réellement nécessaire pour cette transaction. L'appelant doit transférer le Token requis dans UniswapV3Pool lors du rappel, plutôt que de diviser la méthode swap en deux parties. Cela garantit la sécurité et l'exécution complète de la méthode swap, sans nécessiter un enregistrement complexe des variables.
Utiliser des exceptions pour transmettre des informations, réaliser une estimation de transaction avec try catch
Dans le contrat Quoter d'Uniswap, la méthode swap de UniswapV3Pool est exécutée à l'aide d'un try catch. Cela permet de simuler l'estimation des tokens nécessaires pour la transaction de swap, mais pendant l'estimation, aucun échange de tokens réel n'a lieu, donc une erreur sera générée.
Uniswap obtient les informations requises en lançant une erreur spéciale dans la fonction de rappel de transaction, puis en capturant cette erreur pour en extraire les informations nécessaires. Cette méthode peut sembler astucieuse, mais elle est très pratique, car elle ne nécessite pas de modifier la méthode swap pour estimer la demande de transaction, et la logique est également plus simple.
Utiliser des nombres grands pour résoudre les problèmes de précision
Dans le code d'Uniswap, il existe de nombreuses logiques de calcul, telles que le calcul des tokens échangés en fonction du prix actuel et de la liquidité. Pour éviter la perte de précision lors des opérations de division, le processus de calcul utilise souvent l'opération "<< FixedPoint96.RESOLUTION", ce qui correspond à un décalage à gauche de 96 bits, équivalent à multiplier par 2^96.
Après un décalage à gauche, effectuer une opération de division peut garantir la précision sans débordement dans des transactions normales. Bien qu'il y ait toujours une perte de précision au niveau de l'unité minimale en théorie, cela est acceptable.
Calcul des revenus par la méthode Share
Uniswap doit enregistrer les revenus de frais du fournisseur de liquidité LP(. Pour éviter de consommer une grande quantité de Gas en enregistrant les frais pour chaque LP à chaque transaction, Uniswap a adopté une méthode astucieuse.
La structure Position contient feeGrowthInside0LastX128 et feeGrowthInside1LastX128, qui enregistrent les frais de transaction que chaque position a droit à la dernière fois qu'ils ont retiré des frais. Il suffit d'enregistrer les frais totaux et les frais à répartir pour chaque liquidité, et lors du retrait par le LP, les frais récupérables sont calculés en fonction de la liquidité détenue.
![Série pour débutants Web3 : Astuces de développement de contrats que j'ai apprises du code Uniswap])https://img-cdn.gateio.im/webp-social/moments-45e66af69435e6d4412ae506e77ab893.webp(
Stratégie d'obtention d'informations sur la chaîne
Toutes les informations ne doivent pas nécessairement être obtenues sur la chaîne. Le stockage sur la chaîne est relativement coûteux, de nombreuses informations peuvent être stockées dans des bases de données ordinaires et synchronisées régulièrement depuis la chaîne.
Des éléments tels que la liste des pools de transactions et les informations sur les pools de transactions peuvent être stockés dans une base de données ordinaire, sans avoir besoin d'appeler en temps réel l'interface RPC de la chaîne ou des nœuds. Bien sûr, les transactions clés se déroulent toujours sur la chaîne.
Fractionnement de contrat et utilisation des contrats standard
Un projet peut contenir plusieurs contrats réellement déployés. Même si un seul contrat est réellement déployé, le code peut également être divisé en plusieurs contrats à maintenir par héritage.
Par exemple, le contrat NonfungiblePositionManager d'Uniswap hérite de plusieurs contrats. En utilisant le contrat ERC721 d'OpenZeppelin, il est à la fois pratique de gérer des positions via des NFT et d'améliorer l'efficacité du développement.
Conclusion
La pratique est la meilleure méthode d'apprentissage. Essayer de réaliser une version simplifiée d'une bourse décentralisée permet de comprendre en profondeur l'implémentation du code d'Uniswap et d'apprendre davantage de points de connaissance dans des projets pratiques. Si vous êtes intéressé par le développement de projets Web3 et DeFi, vous pouvez consulter des cours pratiques pertinents pour terminer progressivement une bourse simplifiée.
![Web3 Débutant Série : Les petites astuces de développement de contrats que j'ai apprises du code Uniswap])https://img-cdn.gateio.im/webp-social/moments-f95ddc9d89809cf11dbe65b9bafda157.webp(