Consejos de desarrollo de contratos: valiosas experiencias aprendidas del código de Uniswap
Recientemente, al escribir un tutorial de desarrollo de intercambios descentralizados, aprendí muchas técnicas de desarrollo de contratos al investigar la implementación del código de Uniswap V3. Como un novato que acaba de entrar en el desarrollo de contratos DeFi, estos pequeños trucos me han inspirado mucho y creo que también serán útiles para otros principiantes que quieran aprender sobre el desarrollo de contratos.
Dirección de despliegue de contratos predecibles
Normalmente, la dirección obtenida al desplegar un contrato parece aleatoria y es difícil de predecir. Sin embargo, en ciertos escenarios, necesitamos inferir la dirección del contrato a través de pares de intercambio e información relacionada, como determinar los permisos de transacción o obtener la dirección de la piscina, entre otros.
Uniswap utiliza el método CREATE2 para crear contratos, añadiendo el parámetro "salt" para que la dirección del contrato creado sea predecible. La lógica de generación de la nueva dirección es: hash("0xFF", dirección del creador, salt, initcode). Este método es muy útil en muchos casos.
Utilizar bien las funciones de callback
En Solidity, los contratos pueden llamarse entre sí. A veces A llama al método de B, y B hace una llamada de retorno a A en el método llamado, lo cual es útil en ciertos escenarios.
Por ejemplo, en el método swap de Uniswap, el contrato UniswapV3Pool llamará a swapCallback, pasando el Token que se necesita para la transacción actual. La parte que realiza la llamada debe transferir el Token requerido al UniswapV3Pool en la callback, en lugar de dividir el método swap. Esto garantiza la seguridad y la ejecución completa del método swap, sin necesidad de registros de variables complicados.
Usar excepciones para transmitir información, implementar la estimación de transacciones con try catch
En el contrato Quoter de Uniswap, se utiliza un bloque try-catch para ejecutar el método swap del UniswapV3Pool. Esto es para simular un swap y estimar el Token necesario para la transacción. Durante la estimación no se intercambiarán realmente los Tokens, por lo que se generará un error. Uniswap lanza un error especial en la función de callback, y luego captura ese error y extrae la información necesaria.
Este método puede parecer una trampa, pero es muy práctico. No es necesario modificar el método de intercambio para estimar la demanda de transacciones, la lógica es más simple.
La gran cifra resuelve problemas de precisión
En el código de Uniswap hay mucha lógica de cálculo involucrada, como calcular los tokens intercambiados según el precio actual y la liquidez. Para evitar la pérdida de precisión en las operaciones de división, el proceso de cálculo a menudo utiliza la operación "<< FixedPoint96.RESOLUTION", que equivale a desplazar a la izquierda 96 bits, lo que equivale a multiplicar por 2^96. Después de desplazar a la izquierda, se realiza la división, garantizando la precisión en condiciones normales de transacciones sin desbordamiento.
Aunque teóricamente todavía habrá una pequeña pérdida de precisión, ya es aceptable.
Cálculo de ganancias por método de participación
Uniswap necesita registrar las ganancias por comisiones de los proveedores de liquidez LP(. Evidentemente, no se puede registrar la comisión de cada LP en cada transacción, ya que esto consumiría una gran cantidad de Gas.
La estructura Position de Uniswap incluye feeGrowthInside0LastX128 y feeGrowthInside1LastX128, que registran la tarifa que debe recibir cada liquidez la última vez que se retiraron comisiones de cada posición.
Solo necesita registrar la tarifa total y la tarifa que cada liquidez debe asignar. Al retirar LP, la tarifa que se puede retirar se calcula según la liquidez mantenida. Es similar a poseer acciones de una empresa; al retirar ganancias, solo necesita conocer el historial de ganancias por acción y las ganancias de la última extracción.
![Serie de principiantes de Web3: Consejos pequeños para el desarrollo de contratos que aprendí del código de Uniswap])https://img-cdn.gateio.im/webp-social/moments-45e66af69435e6d4412ae506e77ab893.webp(
La información no clave no necesita ser registrada en la cadena
El almacenamiento en la cadena es relativamente caro, y no toda la información necesita estar en la cadena o ser obtenida de ella. Por ejemplo, muchas de las interfaces llamadas por el frontend de Uniswap son interfaces tradicionales de Web2.
La lista de pools de transacciones, información, etc. se pueden almacenar en una base de datos normal, y parte de ella debe sincronizarse periódicamente desde la cadena. No es necesario llamar en tiempo real a la interfaz RPC de servicios de cadena o nodos para obtener datos relacionados.
Por supuesto, las transacciones clave deben realizarse en la cadena.
División de contratos y uso de contratos estándar
Un proyecto puede incluir varios contratos desplegados en la práctica. Incluso si solo hay un contrato desplegado en la realidad, se puede dividir en varios contratos para su mantenimiento mediante herencia.
El contrato NonfungiblePositionManager de Uniswap hereda de varios contratos. El ERC721Permit utiliza directamente el contrato ERC721 de OpenZeppelin, lo que facilita la gestión de posiciones a través de NFT y mejora la eficiencia del desarrollo.
Conclusión
La práctica personal de desarrollar una versión simple de un intercambio descentralizado te permitirá comprender más a fondo la implementación del código de Uniswap y aprender más sobre puntos de conocimiento en proyectos reales. Leer muchos artículos no es tan útil como poner manos a la obra, espero que estas experiencias sean útiles para los principiantes que desean aprender sobre el desarrollo de contratos.
![Serie para principiantes de Web3: Consejos pequeños de desarrollo de contratos que aprendí del código de Uniswap])https://img-cdn.gateio.im/webp-social/moments-f95ddc9d89809cf11dbe65b9bafda157.webp(
Esta página puede contener contenido de terceros, que se proporciona únicamente con fines informativos (sin garantías ni declaraciones) y no debe considerarse como un respaldo por parte de Gate a las opiniones expresadas ni como asesoramiento financiero o profesional. Consulte el Descargo de responsabilidad para obtener más detalles.
20 me gusta
Recompensa
20
10
Republicar
Compartir
Comentar
0/400
GasGuzzler
· 07-18 21:18
No juegues tan profundo con los novatos.
Ver originalesResponder0
LowCapGemHunter
· 07-17 14:17
Consejos imprescindibles para desarrolladores veteranos.
Ver originalesResponder0
SmartMoneyWallet
· 07-15 22:24
Las transacciones on-chain no se escapan de mis ojos.
Ver originalesResponder0
WalletDetective
· 07-15 22:24
¿Es tan simple v3? Después de verlo, me doy cuenta de que no entiendo nada.
Ver originalesResponder0
gas_guzzler
· 07-15 22:21
Otra vez aprovechando su habilidad para Cupones de clip
Ver originalesResponder0
AllInDaddy
· 07-15 21:55
El código de V3 es realmente sólido.
Ver originalesResponder0
SleepyValidator
· 07-15 21:55
Hablar así de detalles no es mejor que enrollar el código fuente uno mismo.
7 consejos para el desarrollo de contratos de Uniswap: mejorar la eficiencia y seguridad de los proyectos de Finanzas descentralizadas
Consejos de desarrollo de contratos: valiosas experiencias aprendidas del código de Uniswap
Recientemente, al escribir un tutorial de desarrollo de intercambios descentralizados, aprendí muchas técnicas de desarrollo de contratos al investigar la implementación del código de Uniswap V3. Como un novato que acaba de entrar en el desarrollo de contratos DeFi, estos pequeños trucos me han inspirado mucho y creo que también serán útiles para otros principiantes que quieran aprender sobre el desarrollo de contratos.
Dirección de despliegue de contratos predecibles
Normalmente, la dirección obtenida al desplegar un contrato parece aleatoria y es difícil de predecir. Sin embargo, en ciertos escenarios, necesitamos inferir la dirección del contrato a través de pares de intercambio e información relacionada, como determinar los permisos de transacción o obtener la dirección de la piscina, entre otros.
Uniswap utiliza el método CREATE2 para crear contratos, añadiendo el parámetro "salt" para que la dirección del contrato creado sea predecible. La lógica de generación de la nueva dirección es: hash("0xFF", dirección del creador, salt, initcode). Este método es muy útil en muchos casos.
Utilizar bien las funciones de callback
En Solidity, los contratos pueden llamarse entre sí. A veces A llama al método de B, y B hace una llamada de retorno a A en el método llamado, lo cual es útil en ciertos escenarios.
Por ejemplo, en el método swap de Uniswap, el contrato UniswapV3Pool llamará a swapCallback, pasando el Token que se necesita para la transacción actual. La parte que realiza la llamada debe transferir el Token requerido al UniswapV3Pool en la callback, en lugar de dividir el método swap. Esto garantiza la seguridad y la ejecución completa del método swap, sin necesidad de registros de variables complicados.
Usar excepciones para transmitir información, implementar la estimación de transacciones con try catch
En el contrato Quoter de Uniswap, se utiliza un bloque try-catch para ejecutar el método swap del UniswapV3Pool. Esto es para simular un swap y estimar el Token necesario para la transacción. Durante la estimación no se intercambiarán realmente los Tokens, por lo que se generará un error. Uniswap lanza un error especial en la función de callback, y luego captura ese error y extrae la información necesaria.
Este método puede parecer una trampa, pero es muy práctico. No es necesario modificar el método de intercambio para estimar la demanda de transacciones, la lógica es más simple.
La gran cifra resuelve problemas de precisión
En el código de Uniswap hay mucha lógica de cálculo involucrada, como calcular los tokens intercambiados según el precio actual y la liquidez. Para evitar la pérdida de precisión en las operaciones de división, el proceso de cálculo a menudo utiliza la operación "<< FixedPoint96.RESOLUTION", que equivale a desplazar a la izquierda 96 bits, lo que equivale a multiplicar por 2^96. Después de desplazar a la izquierda, se realiza la división, garantizando la precisión en condiciones normales de transacciones sin desbordamiento.
Aunque teóricamente todavía habrá una pequeña pérdida de precisión, ya es aceptable.
Cálculo de ganancias por método de participación
Uniswap necesita registrar las ganancias por comisiones de los proveedores de liquidez LP(. Evidentemente, no se puede registrar la comisión de cada LP en cada transacción, ya que esto consumiría una gran cantidad de Gas.
La estructura Position de Uniswap incluye feeGrowthInside0LastX128 y feeGrowthInside1LastX128, que registran la tarifa que debe recibir cada liquidez la última vez que se retiraron comisiones de cada posición.
Solo necesita registrar la tarifa total y la tarifa que cada liquidez debe asignar. Al retirar LP, la tarifa que se puede retirar se calcula según la liquidez mantenida. Es similar a poseer acciones de una empresa; al retirar ganancias, solo necesita conocer el historial de ganancias por acción y las ganancias de la última extracción.
![Serie de principiantes de Web3: Consejos pequeños para el desarrollo de contratos que aprendí del código de Uniswap])https://img-cdn.gateio.im/webp-social/moments-45e66af69435e6d4412ae506e77ab893.webp(
La información no clave no necesita ser registrada en la cadena
El almacenamiento en la cadena es relativamente caro, y no toda la información necesita estar en la cadena o ser obtenida de ella. Por ejemplo, muchas de las interfaces llamadas por el frontend de Uniswap son interfaces tradicionales de Web2.
La lista de pools de transacciones, información, etc. se pueden almacenar en una base de datos normal, y parte de ella debe sincronizarse periódicamente desde la cadena. No es necesario llamar en tiempo real a la interfaz RPC de servicios de cadena o nodos para obtener datos relacionados.
Por supuesto, las transacciones clave deben realizarse en la cadena.
División de contratos y uso de contratos estándar
Un proyecto puede incluir varios contratos desplegados en la práctica. Incluso si solo hay un contrato desplegado en la realidad, se puede dividir en varios contratos para su mantenimiento mediante herencia.
El contrato NonfungiblePositionManager de Uniswap hereda de varios contratos. El ERC721Permit utiliza directamente el contrato ERC721 de OpenZeppelin, lo que facilita la gestión de posiciones a través de NFT y mejora la eficiencia del desarrollo.
Conclusión
La práctica personal de desarrollar una versión simple de un intercambio descentralizado te permitirá comprender más a fondo la implementación del código de Uniswap y aprender más sobre puntos de conocimiento en proyectos reales. Leer muchos artículos no es tan útil como poner manos a la obra, espero que estas experiencias sean útiles para los principiantes que desean aprender sobre el desarrollo de contratos.
![Serie para principiantes de Web3: Consejos pequeños de desarrollo de contratos que aprendí del código de Uniswap])https://img-cdn.gateio.im/webp-social/moments-f95ddc9d89809cf11dbe65b9bafda157.webp(