Partage de techniques de développement de contrats : apprendre du code source d'Uniswap
Récemment, en rédigeant un tutoriel sur le développement d'un échange décentralisé, j'ai référencé l'implémentation du code d'Uniswap V3 et appris de nombreux points de connaissance précieux. En tant que développeur qui essaie de développer un contrat Defi pour la première fois, ces techniques seront très utiles pour les débutants qui souhaitent apprendre le développement de contrats.
Voici quelques astuces que j'ai apprises, certaines peuvent même être qualifiées de techniques astucieuses.
Adresse de déploiement de contrat prévisible
Lors du déploiement d'un contrat, on obtient généralement une adresse apparemment aléatoire, car elle est liée au nonce, rendant l'adresse du contrat difficile à prédire. Cependant, dans certains scénarios, nous pouvons déduire l'adresse du contrat à partir de la paire de transactions et des informations pertinentes. Cela est très utile pour évaluer les droits de transaction ou pour obtenir l'adresse d'un pool, entre autres.
Uniswap crée des contrats en utilisant le paramètre salt et la méthode CREATE2, ce qui rend l'adresse du contrat créée prévisible. La logique de génération d'adresse est la suivante : nouvelle adresse = hash("0xFF", adresse du créateur, salt, initcode).
Utilisation astucieuse des fonctions de rappel
Dans certaines situations, le contrat A appelle la méthode du contrat B, et B rappelle A dans la méthode appelée, cette méthode est très pratique.
Par exemple, dans Uniswap, lors de l'appel de la méthode swap du contrat UniswapV3Pool pour effectuer une transaction, elle rappellera swapCallback, en passant le Token requis pour cette transaction calculé. L'appelant doit transférer le Token nécessaire à la transaction dans UniswapV3Pool lors du rappel, plutôt que de diviser la méthode swap en deux parties pour que l'appelant les appelle. Cela garantit la sécurité de la méthode swap, assurant que l'ensemble de la logique est exécutée intégralement, sans avoir besoin d'enregistrements de variables compliqués pour garantir la sécurité.
Utiliser la transmission d'informations par exception, 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 en l'enveloppant dans un try catch. Cela permet de simuler la méthode swap pour estimer le Token requis pour la transaction. Étant donné qu'aucun échange de Token réel n'est effectué lors de l'estimation, une erreur se produit. Uniswap lance une erreur spéciale dans la fonction de rappel de la transaction, puis capture cette erreur pour extraire les informations nécessaires à partir du message d'erreur.
Cette méthode semble être une astuce, mais elle est très pratique. Il n'est pas nécessaire de modifier la méthode swap pour estimer la demande de transaction, la logique est plus simple.
Utiliser de grands nombres pour résoudre les problèmes de précision
Dans le code Uniswap, il y a une quantité importante de logique de calcul, comme 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", c'est-à-dire un décalage à gauche de 96 bits, équivalent à multiplier par 2^96. Après le décalage à gauche, les opérations de division sont effectuées, garantissant la précision en cas de transactions normales sans débordement.
Calcul des bénéfices avec la méthode Share
Dans Uniswap, il est nécessaire d'enregistrer les revenus de frais de transaction des fournisseurs de liquidités LP(. Évidemment, il n'est pas possible d'enregistrer les frais pour chaque LP à chaque transaction, cela consommerait beaucoup de Gas.
La solution d'Uniswap consiste à enregistrer feeGrowthInside0LastX128 et feeGrowthInside1LastX128 dans la structure Position, représentant les frais que chaque liquidité devrait recevoir lors du dernier retrait de frais pour chaque position. Il suffit d'enregistrer les frais totaux et les frais à allouer à chaque liquidité, et lors du retrait par le LP, les frais récupérables sont calculés en fonction de la liquidité détenue. Cela ressemble à détenir des actions d'une entreprise, où il suffit de connaître le bénéfice par action historique de l'entreprise et les bénéfices lors du dernier retrait.
![Web3 débutant : les astuces de développement de contrats que j'ai apprises du code Uniswap])https://img-cdn.gateio.im/webp-social/moments-45e66af69435e6d4412ae506e77ab893.webp(
Aucune information non nécessaire ne doit être obtenue sur la chaîne.
Le stockage sur la chaîne est relativement coûteux, et toutes les informations n'ont pas besoin d'être mises sur la chaîne ou récupérées depuis la chaîne. Par exemple, de nombreuses interfaces appelées par le site Web frontal d'Uniswap sont des interfaces Web2 traditionnelles.
La liste des pools de trading, les informations des pools de trading, etc. peuvent être stockées dans une base de données ordinaire, certaines peuvent nécessiter une synchronisation régulière depuis la chaîne, mais il n'est pas nécessaire d'appeler en temps réel l'interface RPC des services de la chaîne ou des nœuds pour obtenir les données connexes.
Bien sûr, les transactions clés doivent être effectuées sur la chaîne.
Division raisonnable des contrats, utilisation des contrats standard existants
Un projet peut contenir plusieurs contrats déployés en réalité. 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 examinant la mise en œuvre du contrat ERC721Permit, on constate qu'il utilise directement le contrat @openzeppelin/contracts/token/ERC721/ERC721.sol. Cela permet non seulement de gérer les positions via le biais de NFT, mais également d'améliorer l'efficacité du développement en utilisant des contrats standard existants.
Résumé
La pratique est le meilleur moyen d'apprendre. Essayer de créer une version simplifiée d'un échange décentralisé permet de comprendre plus en profondeur l'implémentation du code de Uniswap et d'apprendre davantage de points de connaissance dans des projets réels.
![Web3 Nouveaux venus : 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(
This page may contain third-party content, which is provided for information purposes only (not representations/warranties) and should not be considered as an endorsement of its views by Gate, nor as financial or professional advice. See Disclaimer for details.
9 J'aime
Récompense
9
8
Partager
Commentaire
0/400
SchrodingerWallet
· 07-09 09:07
C'est trop basique, je me casse~
Voir l'originalRépondre0
LiquidityWizard
· 07-08 13:06
C'est tout ce qu'il y a à faire.
Voir l'originalRépondre0
PoolJumper
· 07-07 22:21
Contrat pro sauve-moi canard
Voir l'originalRépondre0
IntrovertMetaverse
· 07-06 09:37
Encore une fois, des contrats à terme.
Voir l'originalRépondre0
SerumSurfer
· 07-06 09:37
Ce code source v3 est vraiment impressionnant.
Voir l'originalRépondre0
FlyingLeek
· 07-06 09:36
Ça a l'air bien, j'attends d'être pris pour un idiot.
Uniswap source code révélé : 7 techniques de développement de contrats pour aider les Débutants Defi à To the moon
Partage de techniques de développement de contrats : apprendre du code source d'Uniswap
Récemment, en rédigeant un tutoriel sur le développement d'un échange décentralisé, j'ai référencé l'implémentation du code d'Uniswap V3 et appris de nombreux points de connaissance précieux. En tant que développeur qui essaie de développer un contrat Defi pour la première fois, ces techniques seront très utiles pour les débutants qui souhaitent apprendre le développement de contrats.
Voici quelques astuces que j'ai apprises, certaines peuvent même être qualifiées de techniques astucieuses.
Adresse de déploiement de contrat prévisible
Lors du déploiement d'un contrat, on obtient généralement une adresse apparemment aléatoire, car elle est liée au nonce, rendant l'adresse du contrat difficile à prédire. Cependant, dans certains scénarios, nous pouvons déduire l'adresse du contrat à partir de la paire de transactions et des informations pertinentes. Cela est très utile pour évaluer les droits de transaction ou pour obtenir l'adresse d'un pool, entre autres.
Uniswap crée des contrats en utilisant le paramètre salt et la méthode CREATE2, ce qui rend l'adresse du contrat créée prévisible. La logique de génération d'adresse est la suivante : nouvelle adresse = hash("0xFF", adresse du créateur, salt, initcode).
Utilisation astucieuse des fonctions de rappel
Dans certaines situations, le contrat A appelle la méthode du contrat B, et B rappelle A dans la méthode appelée, cette méthode est très pratique.
Par exemple, dans Uniswap, lors de l'appel de la méthode swap du contrat UniswapV3Pool pour effectuer une transaction, elle rappellera swapCallback, en passant le Token requis pour cette transaction calculé. L'appelant doit transférer le Token nécessaire à la transaction dans UniswapV3Pool lors du rappel, plutôt que de diviser la méthode swap en deux parties pour que l'appelant les appelle. Cela garantit la sécurité de la méthode swap, assurant que l'ensemble de la logique est exécutée intégralement, sans avoir besoin d'enregistrements de variables compliqués pour garantir la sécurité.
Utiliser la transmission d'informations par exception, 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 en l'enveloppant dans un try catch. Cela permet de simuler la méthode swap pour estimer le Token requis pour la transaction. Étant donné qu'aucun échange de Token réel n'est effectué lors de l'estimation, une erreur se produit. Uniswap lance une erreur spéciale dans la fonction de rappel de la transaction, puis capture cette erreur pour extraire les informations nécessaires à partir du message d'erreur.
Cette méthode semble être une astuce, mais elle est très pratique. Il n'est pas nécessaire de modifier la méthode swap pour estimer la demande de transaction, la logique est plus simple.
Utiliser de grands nombres pour résoudre les problèmes de précision
Dans le code Uniswap, il y a une quantité importante de logique de calcul, comme 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", c'est-à-dire un décalage à gauche de 96 bits, équivalent à multiplier par 2^96. Après le décalage à gauche, les opérations de division sont effectuées, garantissant la précision en cas de transactions normales sans débordement.
Calcul des bénéfices avec la méthode Share
Dans Uniswap, il est nécessaire d'enregistrer les revenus de frais de transaction des fournisseurs de liquidités LP(. Évidemment, il n'est pas possible d'enregistrer les frais pour chaque LP à chaque transaction, cela consommerait beaucoup de Gas.
La solution d'Uniswap consiste à enregistrer feeGrowthInside0LastX128 et feeGrowthInside1LastX128 dans la structure Position, représentant les frais que chaque liquidité devrait recevoir lors du dernier retrait de frais pour chaque position. Il suffit d'enregistrer les frais totaux et les frais à allouer à chaque liquidité, et lors du retrait par le LP, les frais récupérables sont calculés en fonction de la liquidité détenue. Cela ressemble à détenir des actions d'une entreprise, où il suffit de connaître le bénéfice par action historique de l'entreprise et les bénéfices lors du dernier retrait.
![Web3 débutant : les astuces de développement de contrats que j'ai apprises du code Uniswap])https://img-cdn.gateio.im/webp-social/moments-45e66af69435e6d4412ae506e77ab893.webp(
Aucune information non nécessaire ne doit être obtenue sur la chaîne.
Le stockage sur la chaîne est relativement coûteux, et toutes les informations n'ont pas besoin d'être mises sur la chaîne ou récupérées depuis la chaîne. Par exemple, de nombreuses interfaces appelées par le site Web frontal d'Uniswap sont des interfaces Web2 traditionnelles.
La liste des pools de trading, les informations des pools de trading, etc. peuvent être stockées dans une base de données ordinaire, certaines peuvent nécessiter une synchronisation régulière depuis la chaîne, mais il n'est pas nécessaire d'appeler en temps réel l'interface RPC des services de la chaîne ou des nœuds pour obtenir les données connexes.
Bien sûr, les transactions clés doivent être effectuées sur la chaîne.
Division raisonnable des contrats, utilisation des contrats standard existants
Un projet peut contenir plusieurs contrats déployés en réalité. 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 examinant la mise en œuvre du contrat ERC721Permit, on constate qu'il utilise directement le contrat @openzeppelin/contracts/token/ERC721/ERC721.sol. Cela permet non seulement de gérer les positions via le biais de NFT, mais également d'améliorer l'efficacité du développement en utilisant des contrats standard existants.
Résumé
La pratique est le meilleur moyen d'apprendre. Essayer de créer une version simplifiée d'un échange décentralisé permet de comprendre plus en profondeur l'implémentation du code de Uniswap et d'apprendre davantage de points de connaissance dans des projets réels.
![Web3 Nouveaux venus : 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(