Análisis del código de Uniswap V3: 7 consejos prácticos para el desarrollo de contratos

Consejos de desarrollo de contratos aprendidos del código de Uniswap

Recientemente, al escribir un tutorial de desarrollo para un intercambio descentralizado, referencié la implementación de código de Uniswap V3 y aprendí muchos puntos valiosos. Como desarrollador que anteriormente solo había desarrollado contratos NFT simples, este intento de desarrollo de contratos Defi me ha brindado nuevas experiencias. Estoy seguro de que estos pequeños consejos serán de gran ayuda para los principiantes que deseen aprender sobre el desarrollo de contratos.

A continuación, echemos un vistazo a estos útiles consejos de desarrollo, algunos de los cuales incluso se pueden considerar trucos ingeniosos.

Serie para principiantes en Web3: Consejos de desarrollo de contratos que aprendí del código de Uniswap

Dirección de despliegue de contrato predecible

Generalmente, la dirección obtenida al implementar un contrato parece ser aleatoria, ya que está relacionada con el nonce, por lo que es difícil predecir la dirección del contrato. Sin embargo, en ciertos casos, necesitamos inferir la dirección del contrato a través de transacciones y información relacionada, como determinar permisos de transacción o obtener la dirección de un pool, etc.

Uniswap crea contratos utilizando el método CREATE2 al añadir el parámetro salt, lo que hace que la dirección del contrato creado sea predecible. La lógica de generación de la dirección es: nueva dirección = hash("0xFF", dirección del creador, salt, initcode).

![Serie para principiantes en Web3: Consejos de desarrollo de contratos que aprendí del código de Uniswap](https://img-cdn.gateio.im/webp-social/moments-0aaa61a4d43aba7fdeddbc55e3665305.webp01

Uso efectivo de funciones de devolución de llamada

En Solidity, los contratos pueden llamarse entre sí. En ciertos escenarios, es muy útil que A llame a un método de B y que B haga una llamada de retorno a A en el método que ha sido llamado.

En Uniswap, al llamar al método swap del contrato UniswapV3Pool para realizar una transacción, se llamará a swapCallback, el cual recibirá el Token que se calcula que se necesita para la transacción actual. La parte que llama necesita transferir el Token requerido para la transacción al UniswapV3Pool en la callback, en lugar de dividir el método swap en dos partes para que sea llamado por la parte que llama. Esto asegura la seguridad del método swap, garantizando que toda la lógica se ejecute de manera completa, sin la necesidad de tediosos registros de variables para asegurar la seguridad.

Usar excepciones para transmitir información, implementar la estimación de transacciones con try catch

En algunos contratos de Uniswap, el método swap de UniswapV3Pool se ejecuta envuelto en un try catch. Esto es para simular el método swap y estimar los tokens necesarios para la transacción. Dado que no se produce un intercambio real de tokens durante la estimación, se genera un error. Uniswap lanza un error especial en la función de callback de la transacción y luego captura ese error, extrayendo la información necesaria del mensaje de error.

Este método puede parecer un poco astuto, pero es muy práctico. No es necesario modificar el método de intercambio para estimar la demanda de transacciones, y la lógica es más simple.

![Serie para principiantes en Web3: Pequeños consejos de desarrollo de contratos que aprendí del código de Uniswap])https://img-cdn.gateio.im/webp-social/moments-b0c3d4eb7e8ca88cc4cfc9476a34437a.webp(

Resolver problemas de precisión con números grandes

El código de Uniswap tiene una gran cantidad de lógica de cálculo, como calcular el Token intercambiado según el precio actual y la liquidez. Para evitar la pérdida de precisión causada por las operaciones de división, a menudo se utiliza durante el proceso de cálculo la operación << FixedPoint96.RESOLUTION, que equivale a un desplazamiento a la izquierda de 96 bits, es decir, multiplicar por 2^96. Después del desplazamiento a la izquierda, se realiza la operación de división, garantizando la precisión en condiciones normales de transacción sin desbordamiento.

Aunque teóricamente todavía habrá una pérdida de precisión, normalmente solo es una pérdida de la unidad mínima, lo cual es aceptable.

Calcular ganancias utilizando la forma Share

En Uniswap, se necesitan registrar las ganancias por tarifas de los LP (proveedores de liquidez). Evidentemente, no se puede registrar la tarifa de cada LP en cada transacción, ya que esto consumiría una gran cantidad de Gas.

La solución de Uniswap es definir feeGrowthInside0LastX128 y feeGrowthInside1LastX128 en la estructura Position, que registran las tarifas que le corresponden a cada liquidez la última vez que se retiraron las tarifas de cada posición.

En pocas palabras, solo necesitas registrar la tarifa total y la tarifa que se debe asignar a cada liquidez. Cuando el LP retira la tarifa, se calcula la tarifa extraíble según la liquidez que posee. Esto es similar a poseer acciones de una empresa; al retirar los beneficios de las acciones, solo necesitas conocer el historial de ganancias por acción de la empresa y los beneficios de la última retirada.

![Serie para principiantes de Web3: pequeños consejos de desarrollo de contratos que aprendí del código de Uniswap])https://img-cdn.gateio.im/webp-social/moments-45e66af69435e6d4412ae506e77ab893.webp(

No toda la información necesita ser obtenida de la cadena

Almacenamiento en la cadena es relativamente caro, y no toda la información necesita estar en la cadena o ser obtenida de la misma. Por ejemplo, muchas de las interfaces llamadas por el sitio web frontal de Uniswap son interfaces tradicionales de Web2.

La lista de pools de negociación, la información de los pools de negociación, etc. se pueden almacenar en una base de datos normal, algunos pueden necesitar sincronizarse periódicamente desde la cadena, pero no es necesario llamar en tiempo real a la interfaz RPC proporcionada por la cadena o los servicios de nodo para obtener datos relacionados.

Por supuesto, las operaciones clave deben realizarse en la cadena.

Aprende a dividir contratos y utiliza contratos estándar existentes

Un proyecto puede contener múltiples contratos desplegados en la práctica. Incluso si solo hay un contrato realmente desplegado, también podemos dividir el contrato en varios contratos mediante la herencia para su mantenimiento.

Por ejemplo, algunos contratos en Uniswap heredan de múltiples contratos. Al implementarlos, se utilizó directamente el contrato @openzeppelin/contracts/token/ERC721/ERC721.sol, lo que facilita la gestión de posiciones a través de NFT y permite aprovechar los contratos estándar existentes para mejorar la eficiencia del desarrollo.

Resumen

Desarrollar por ti mismo profundiza más tu comprensión que leer artículos. Intentar implementar un intercambio descentralizado básico te permitirá entender más a fondo la implementación del código de Uniswap y aprender más sobre puntos de conocimiento en proyectos reales.

![Serie para principiantes en Web3: Consejos de desarrollo de contratos que aprendí del código de Uniswap])https://img-cdn.gateio.im/webp-social/moments-f95ddc9d89809cf11dbe65b9bafda157.webp(

Ver originales
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.
  • Recompensa
  • 4
  • Compartir
Comentar
0/400
ForumLurkervip
· hace2h
¿Puede el experto explicar en detalle esta parte de la técnica?
Ver originalesResponder0
BearMarketGardenervip
· hace23h
Pequeño novato, empieza con la alquimia.
Ver originalesResponder0
MissedAirdropAgainvip
· hace23h
¿Otra vez va a abrirse el libro? ¿No fue suficiente con el NFT que acabamos de hacer?
Ver originalesResponder0
Web3Educatorvip
· hace23h
ok estudiantes, déjame desglosar esto rápidamente...
Ver originalesResponder0
Opere con criptomonedas en cualquier momento y lugar
qrCode
Escanee para descargar la aplicación Gate
Comunidad
Español
  • 简体中文
  • English
  • Tiếng Việt
  • 繁體中文
  • Español
  • Русский
  • Français (Afrique)
  • Português (Portugal)
  • Bahasa Indonesia
  • 日本語
  • بالعربية
  • Українська
  • Português (Brasil)