Astuces pratiques pour le développement de contrats : expériences tirées du code d'Uniswap
Récemment, en développant un tutoriel sur un échange décentralisé, j'ai consulté le code d'implémentation d'Uniswap V3 et j'ai appris de nombreux points intéressants. En tant que développeur qui essaie pour la première fois de développer des contrats Defi, ces techniques seront très utiles pour les débutants qui souhaitent apprendre le développement de contrats.
Voyons maintenant ces petites astuces pratiques, certaines peuvent même être considérées comme des techniques astucieuses.
Adresse de déploiement des contrats à terme
Dans la plupart des cas, l'adresse obtenue lors du déploiement d'un contrat semble aléatoire, car elle est liée au nonce et n'est pas facile à prédire. Cependant, dans certaines situations, nous devons déduire l'adresse du contrat à partir des paires de trading et des informations connexes. Cela est utile pour déterminer les autorisations de transaction ou pour obtenir l'adresse d'un pool, par exemple.
Uniswap utilise la méthode CREATE2 pour créer des contrats, en ajoutant un paramètre salt pour rendre l'adresse du contrat générée prévisible. La logique de génération de la nouvelle adresse est : hash("0xFF", adresse du créateur, salt, initcode). Cette méthode rend l'adresse du contrat prévisible, facilitant les opérations ultérieures.
Utilisation astucieuse des fonctions de rappel
Dans Solidity, les contrats peuvent s'appeler mutuellement. Un scénario courant est la méthode A qui appelle B, et B qui rappelle A dans la méthode appelée. Cela peut être très utile dans certaines situations.
Prenons Uniswap comme exemple : lorsque la méthode swap du contrat UniswapV3Pool est appelée pour effectuer une transaction, elle rappellera swapCallback, en transmettant le Token réellement nécessaire pour cette transaction. L'appelant doit transférer le Token requis pour la transaction au UniswapV3Pool dans le rappel. Ce design garantit l'exécution complète et la sécurité de la méthode swap, sans nécessiter un enregistrement complexe des variables.
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 à l'aide d'un try catch. Cela permet de simuler la méthode swap pour estimer les tokens nécessaires à la transaction. Étant donné qu'aucun échange de tokens réel n'est effectué lors de l'estimation, une erreur est générée. Uniswap gère cela en lançant une erreur spéciale dans la fonction de rappel de la 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. Elle évite de modifier la méthode de swap pour estimer la demande de trading, rendant la logique plus simple.
Résoudre les problèmes de précision avec de grands nombres
Le code d'Uniswap implique une grande quantité 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 due aux opérations de division, Uniswap utilise souvent l'opération "<< FixedPoint96.RESOLUTION", c'est-à-dire un décalage à gauche de 96 bits, équivalent à multiplier par 2^96. Décaler à gauche avant d'effectuer l'opération de division peut garantir la précision lors des transactions normales sans débordement, utilisant généralement uint256 pour calculer (.
Bien qu'il y ait théoriquement encore une légère perte de précision, ce niveau d'erreur est généralement acceptable.
Calcul des bénéfices avec la méthode Share
Uniswap doit enregistrer les revenus de frais de transaction des fournisseurs de liquidité LP). Pour éviter de consigner les frais pour chaque LP à chaque transaction, ce qui consommerait beaucoup de Gas, Uniswap a adopté une méthode astucieuse.
Dans la structure Position, feeGrowthInside0LastX128 et feeGrowthInside1LastX128 sont définis pour enregistrer les frais de transaction que chaque liquidité devrait recevoir lors du dernier retrait de frais pour chaque position. Ainsi, il suffit d'enregistrer les frais totaux et les frais à attribuer à chaque liquidité, et lors du retrait par le LP, les frais récupérables peuvent être calculés en fonction de la liquidité détenue. Cela ressemble au mécanisme de dividende des actions, où il suffit de connaître le bénéfice par action historique de l'entreprise et le bénéfice lors du dernier retrait.
Choisir raisonnablement les voies d'acquisition d'informations
Le stockage sur la blockchain est relativement coûteux, donc toutes les informations ne doivent pas nécessairement être enregistrées sur la chaîne ou récupérées de celle-ci. 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 sur les pools de trading, etc. peuvent être stockées dans une base de données classique. Certaines données 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 chaîne ou de nœud pour obtenir les données pertinentes.
Certains fournisseurs de RPC blockchain offrent des interfaces avancées permettant d'obtenir certaines données plus rapidement et à moindres frais. Ces interfaces utilisent généralement la mise en cache pour améliorer les performances et l'efficacité.
Bien sûr, les transactions clés doivent toujours être effectuées sur la chaîne.
Apprendre à diviser les contrats et à utiliser les contrats standards existants
Un projet peut contenir plusieurs contrats réellement déployés. Même si un seul contrat est réellement déployé, nous pouvons le diviser en plusieurs parties par héritage pour le maintenir.
Par exemple, le contrat NonfungiblePositionManager d'Uniswap hérite de plusieurs contrats. Lors de la mise en œuvre du contrat ERC721Permit, le contrat @openzeppelin/contracts/token/ERC721/ERC721.sol a été utilisé directement. Cela facilite non seulement la gestion des positions via NFT, mais permet également d'améliorer l'efficacité du développement grâce à l'utilisation de contrats standards existants.
Résumé
Pratiquer le développement d'une version simplifiée d'une bourse décentralisée vous permettra de mieux comprendre l'implémentation du code d'Uniswap et d'apprendre davantage de points de connaissance issus de projets réels. Je suis convaincu que ces techniques seront très utiles pour les débutants souhaitant apprendre le développement de contrats.
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.
10 J'aime
Récompense
10
7
Partager
Commentaire
0/400
DataPickledFish
· Il y a 20h
Je suis encore en train d'étudier le code, ça me fait mal à la tête !
Voir l'originalRépondre0
PermabullPete
· Il y a 20h
Je ne comprends pas tout ça, je ne sais faire que perdre de l'argent.
Voir l'originalRépondre0
MEVSandwichVictim
· Il y a 20h
Ce CREATE2 est assez avancé, pas étonnant que ce soit uni.
Voir l'originalRépondre0
MrRightClick
· Il y a 21h
Hé create2 est vraiment incroyable !
Voir l'originalRépondre0
PanicSeller69
· Il y a 21h
Le chien de code a même pleuré.
Voir l'originalRépondre0
BearMarketBard
· Il y a 21h
La sauce Lao Gan Ma est vraiment un bull.
Voir l'originalRépondre0
Deconstructionist
· Il y a 21h
Je suis encore en train d'étudier le code de production, je n'arrive plus à apprendre.
Analyse du code Uniswap : 7 astuces pratiques pour le développement de contrats
Astuces pratiques pour le développement de contrats : expériences tirées du code d'Uniswap
Récemment, en développant un tutoriel sur un échange décentralisé, j'ai consulté le code d'implémentation d'Uniswap V3 et j'ai appris de nombreux points intéressants. En tant que développeur qui essaie pour la première fois de développer des contrats Defi, ces techniques seront très utiles pour les débutants qui souhaitent apprendre le développement de contrats.
Voyons maintenant ces petites astuces pratiques, certaines peuvent même être considérées comme des techniques astucieuses.
Adresse de déploiement des contrats à terme
Dans la plupart des cas, l'adresse obtenue lors du déploiement d'un contrat semble aléatoire, car elle est liée au nonce et n'est pas facile à prédire. Cependant, dans certaines situations, nous devons déduire l'adresse du contrat à partir des paires de trading et des informations connexes. Cela est utile pour déterminer les autorisations de transaction ou pour obtenir l'adresse d'un pool, par exemple.
Uniswap utilise la méthode CREATE2 pour créer des contrats, en ajoutant un paramètre salt pour rendre l'adresse du contrat générée prévisible. La logique de génération de la nouvelle adresse est : hash("0xFF", adresse du créateur, salt, initcode). Cette méthode rend l'adresse du contrat prévisible, facilitant les opérations ultérieures.
Utilisation astucieuse des fonctions de rappel
Dans Solidity, les contrats peuvent s'appeler mutuellement. Un scénario courant est la méthode A qui appelle B, et B qui rappelle A dans la méthode appelée. Cela peut être très utile dans certaines situations.
Prenons Uniswap comme exemple : lorsque la méthode swap du contrat UniswapV3Pool est appelée pour effectuer une transaction, elle rappellera swapCallback, en transmettant le Token réellement nécessaire pour cette transaction. L'appelant doit transférer le Token requis pour la transaction au UniswapV3Pool dans le rappel. Ce design garantit l'exécution complète et la sécurité de la méthode swap, sans nécessiter un enregistrement complexe des variables.
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 à l'aide d'un try catch. Cela permet de simuler la méthode swap pour estimer les tokens nécessaires à la transaction. Étant donné qu'aucun échange de tokens réel n'est effectué lors de l'estimation, une erreur est générée. Uniswap gère cela en lançant une erreur spéciale dans la fonction de rappel de la 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. Elle évite de modifier la méthode de swap pour estimer la demande de trading, rendant la logique plus simple.
Résoudre les problèmes de précision avec de grands nombres
Le code d'Uniswap implique une grande quantité 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 due aux opérations de division, Uniswap utilise souvent l'opération "<< FixedPoint96.RESOLUTION", c'est-à-dire un décalage à gauche de 96 bits, équivalent à multiplier par 2^96. Décaler à gauche avant d'effectuer l'opération de division peut garantir la précision lors des transactions normales sans débordement, utilisant généralement uint256 pour calculer (.
Bien qu'il y ait théoriquement encore une légère perte de précision, ce niveau d'erreur est généralement acceptable.
Calcul des bénéfices avec la méthode Share
Uniswap doit enregistrer les revenus de frais de transaction des fournisseurs de liquidité LP). Pour éviter de consigner les frais pour chaque LP à chaque transaction, ce qui consommerait beaucoup de Gas, Uniswap a adopté une méthode astucieuse.
Dans la structure Position, feeGrowthInside0LastX128 et feeGrowthInside1LastX128 sont définis pour enregistrer les frais de transaction que chaque liquidité devrait recevoir lors du dernier retrait de frais pour chaque position. Ainsi, il suffit d'enregistrer les frais totaux et les frais à attribuer à chaque liquidité, et lors du retrait par le LP, les frais récupérables peuvent être calculés en fonction de la liquidité détenue. Cela ressemble au mécanisme de dividende des actions, où il suffit de connaître le bénéfice par action historique de l'entreprise et le bénéfice lors du dernier retrait.
Choisir raisonnablement les voies d'acquisition d'informations
Le stockage sur la blockchain est relativement coûteux, donc toutes les informations ne doivent pas nécessairement être enregistrées sur la chaîne ou récupérées de celle-ci. 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 sur les pools de trading, etc. peuvent être stockées dans une base de données classique. Certaines données 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 chaîne ou de nœud pour obtenir les données pertinentes.
Certains fournisseurs de RPC blockchain offrent des interfaces avancées permettant d'obtenir certaines données plus rapidement et à moindres frais. Ces interfaces utilisent généralement la mise en cache pour améliorer les performances et l'efficacité.
Bien sûr, les transactions clés doivent toujours être effectuées sur la chaîne.
Apprendre à diviser les contrats et à utiliser les contrats standards existants
Un projet peut contenir plusieurs contrats réellement déployés. Même si un seul contrat est réellement déployé, nous pouvons le diviser en plusieurs parties par héritage pour le maintenir.
Par exemple, le contrat NonfungiblePositionManager d'Uniswap hérite de plusieurs contrats. Lors de la mise en œuvre du contrat ERC721Permit, le contrat @openzeppelin/contracts/token/ERC721/ERC721.sol a été utilisé directement. Cela facilite non seulement la gestion des positions via NFT, mais permet également d'améliorer l'efficacité du développement grâce à l'utilisation de contrats standards existants.
Résumé
Pratiquer le développement d'une version simplifiée d'une bourse décentralisée vous permettra de mieux comprendre l'implémentation du code d'Uniswap et d'apprendre davantage de points de connaissance issus de projets réels. Je suis convaincu que ces techniques seront très utiles pour les débutants souhaitant apprendre le développement de contrats.