Serie para principiantes de Web3: consejos para el desarrollo de contratos que aprendí con Uniswap Code
Recientemente escribí un tutorial sobre el desarrollo de intercambios descentralizados. https://github.com/WTFAcademy/WTF-Dapp , haciendo referencia a la implementación del código de Uniswap V3, y aprendí muchos puntos de conocimiento. He desarrollado contratos NFT simples antes, y esta es la primera vez que he intentado desarrollar un contrato DeFi. Creo que estos consejos serán muy útiles para los novatos que quieran aprender a desarrollar contratos.
Los desarrolladores contratados pueden ir directamente a https://github.com/WTFAcademy/WTF-Dapp Contribuir con código y marcar la diferencia para la Web3~
A continuación, echemos un vistazo a estos pequeños trucos, algunos de los cuales incluso podrían llamarse trucos efectistas.
La dirección del contrato de implementación del contrato se puede hacer predecible
Cuando implementamos un contrato, generalmente obtenemos una dirección aparentemente aleatoria. Debido a que está relacionada con el nonce, la dirección del contrato es difícil de predecir. Sin embargo, en Uniswap, tenemos ese requisito: necesitamos inferir la dirección del contrato a través del par de transacciones y la información relacionada. Esto es muy útil en muchos casos, como determinar la autoridad de la transacción u obtener la dirección del pool.
En Uniswap, los contratos se crean utilizando un código como pool = address(new Uniswap V3 Pool{salt: keccak 256(abi.encode(token 0, token 1, fee))}());. Al agregar sal para crear un contrato utilizando CREAR 2 ( https://github.com/AmazingAng/WTF-Solidity/blob/main/25_Create2/readme.md ), la ventaja es que la dirección del contrato creado es predecible. La lógica de generación de direcciones es nueva dirección = hash(0x FF, dirección del creador, sal, código de inicio).
Puedes aprender más sobre esto en el curso WTF-DApp en https://github.com/WTFAcademy/WTF-Dapp/blob/main/P103_Factory/readme.md .
Haz un buen uso de las funciones de devolución de llamada
En Solidity, los contratos pueden llamarse entre sí. Existe un escenario en el que A llama a B en un método determinado y B llama a A en el método llamado, lo que también resulta muy útil en algunos escenarios.
En Uniswap, cuando llama al método swap del contrato Uniswap V3 Pool, llamará nuevamente a swapCallback y la devolución de llamada pasará el valor calculado. Simbólico En realidad, se requiere para esta transacción. El autor de la llamada debe transferir el token necesario para la transacción al pool de Uniswap V3 en la devolución de llamada, en lugar de dividir el método de intercambio en dos partes para que el autor de la llamada lo llame. Esto garantiza la seguridad del método de intercambio y garantiza que toda la lógica se ejecute por completo sin la necesidad de registros de variables engorrosos para garantizar la seguridad.
El fragmento de código es el siguiente:
You can learn more about the trading part of the course en https://github.com/WTFAcademy/WTF-Dapp/blob/main/P106_PoolSwap/readme.md .
Utilice excepciones para pasar información e intente capturar para implementar estimaciones de transacciones
Al referirnos al código de Uniswap, encontramos que en su https://github.com/Uniswap/v3-periphery/blob/main/contracts/lens/Quoter.sol Contrato, el método swap de Uniswap V3 Pool se envolvió en try catch y se ejecutó:
¿Por qué? Porque necesitamos simular el método de intercambio para estimar los tokens necesarios para la transacción, pero como el intercambio de tokens no se producirá realmente durante la estimación, se informará un error. En Uniswap, se genera un error especial en la función de devolución de llamada de la transacción, luego se captura el error y se analiza la información requerida del mensaje de error.
Parece un truco, pero también es muy práctico. De esta manera, no es necesario modificar el método de intercambio según las necesidades de las transacciones estimadas y la lógica es más sencilla. En nuestro curso, también hacemos referencia a esta lógica para implementar el contrato. https://github.com/WTFAcademy/WTF-Dapp/blob/main/demo-contract/contracts/wtfswap/SwapRouter.sol .
Uso de números grandes para resolver problemas de precisión
Hay muchas lógicas de cálculo en el código de Uniswap, como calcular los tokens intercambiados según el precio actual y la liquidez. En este proceso, debemos evitar perder precisión durante las operaciones de división. En Uniswap, el proceso de cálculo a menudo utiliza la
El código es el siguiente (calculando la cantidad de tokens necesarios para la transacción a través del precio y la liquidez):
Como puede ver, en primer lugar, el precio en Uniswap se multiplica por la raíz cuadrada de 2 ^ 96 (correspondiente a sqrtRatioAX 96 y sqrtRatioBX 96 en el código anterior), y luego la liquidez se desplazará hacia la izquierda para calcular el numerador 1. En el siguiente cálculo, se eliminará 2 ^ 96 en el proceso de cálculo para obtener el resultado final.
Por supuesto, pase lo que pase, todavía habrá una pérdida de precisión en teoría, pero en este caso se pierde la unidad más pequeña, lo cual es aceptable.
Para obtener más información, puede obtener más información de este curso. en https://github.com/WTFAcademy/WTF-Dapp/blob/main/P106_PoolSwap/readme.md .
Calcular ingresos usando Share
En Uniswap, necesitamos registrar los ingresos por comisiones de los proveedores de liquidez (LP). Obviamente, no podemos registrar la comisión de cada LP en cada transacción, lo que consumiría mucho gas. Entonces, ¿cómo lidiar con esto?
En Uniswap, podemos ver que la siguiente estructura es definiciónned en Posición:
Incluye feeGrowthInside0LastX128 y feeGrowthInside1LastX128, que registran la tarifa que debe recibir cada liquidez cuando cada posición (Posición) retiró la tarifa la última vez.
En pocas palabras, solo necesito registrar la tarifa total y la cantidad de tarifa que se debe asignar a cada liquidez, de modo que cuando LP retire la tarifa, pueda calcular la cantidad de tarifa que puede retirar de acuerdo con la liquidez en su poder. Es como si tuviera acciones de una empresa, cuando desea retirar los ingresos de las acciones, solo necesita saber las ganancias históricas por acción de la empresa y los ingresos cuando realizó el último retiro.
Anteriormente, presentamos el método de cálculo de ganancias de stETH en el artículo Diseño de contrato ingenioso. ¿Ves cómo stETH distribuye automáticamente las ganancias a diario? Deja que tu ETH participe en el staking para obtener un interés estable , y el principio es similar.
No es necesario obtener toda la información de la cadena
El almacenamiento en cadena es relativamente costoso, por lo que no necesitamos almacenar toda la información en la cadena ni obtenerla de la cadena. Por ejemplo, muchas de las interfaces a las que llama el sitio web front-end de Uniswap son interfaces Web2 tradicionales.
La lista de grupos de transacciones, la información sobre los grupos de transacciones, etc., se pueden almacenar en bases de datos comunes. Es posible que sea necesario sincronizar algunas de ellas desde la cadena con regularidad, pero no es necesario llamar a la interfaz RPC proporcionada por la cadena o el servicio de nodo en tiempo real para obtener los datos pertinentes.
Por supuesto, muchos proveedores de blockchain de PRC ahora ofrecen algunas interfaces avanzadas, puede obtener algunos datos de una manera más rápida y económica, que es similar. Por ejemplo, ZAN proporciona una interfaz similar para obtener todos los NFT de un determinado usuario. Obviamente, esta información se puede almacenar en caché para mejorar el rendimiento y la eficiencia. Puede visitar https://zan.top/service/advance-api para conseguir más.
Por supuesto, las transacciones clave deben realizarse en cadena.
Aprenda a dividir contratos y utilizar contratos estándar existentes como ERC 721
Un proyecto puede contener varios contratos implementados. Incluso si solo hay un contrato implementado, nuestro código puede dividir el contrato en varios contratos para realizar el mantenimiento mediante herencia.
Por ejemplo, en Uniswap, el https://github.com/Uniswap/v3-periphery/blob/main/contracts/NonfungiblePositionManager.sol El contrato hereda muchos contratos y el código es el siguiente:
Y cuando observas la implementación del contrato de permiso ERC 721, verás que utiliza directamente el contrato @openzeppelin/contracts/token/ERC 721/ERC 721.sol. Esto hace que sea conveniente administrar posiciones a través de NFT y, por otro lado, también puede utilizar contratos estándar existentes para mejorar la eficiencia del desarrollo de contratos.
En nuestro curso podrás aprender https://github.com/WTFAcademy/WTF-Dapp/blob/main/P108_PositionManager/readme.md y tratar de desarrollar un contrato ERC 721 simple para gestionar posiciones.
Resumir
No importa cuántos artículos lea, no es tan práctico como desarrollarlo usted mismo. En el proceso de intentar implementar una versión simplificada de un intercambio descentralizado usted mismo, puede tener una comprensión más profunda de la implementación del código de Uniswap y aprender más puntos de conocimiento que experimentará en proyectos reales.
El curso WTF-DApp es un curso de código abierto realizado conjuntamente por la comunidad de desarrolladores de ZAN y la comunidad de desarrolladores de WTF Academy. Si también te interesa el desarrollo de proyectos Web3 y DeFi, puedes consultar nuestro curso práctico https://github.com/WTFAcademy/WTF-Dapp y completa una versión sencilla del intercambio paso a paso. Creo que definitivamente te ayudará~
Este artículo fue escrito por Fisher (cuenta X) @Yudao 1024 ) del equipo ZAN (cuenta X @zan_team ).
Este artículo proviene de Internet: Serie para principiantes de Web3: Consejos de desarrollo de contratos que aprendí de Uniswap Code
Relacionado: Cómo encontrar la próxima gema 100x: cómo ganar dinero en Pump.fun con ChatGPT
Autor original: CMed Nota del editor: En el mercado de Pump, se lanzan nuevos tokens a cada momento. Mientras que otros en el mercado siguen buscando una aguja en un pajar para encontrar una memecoin que pueda generar retornos excesivos, @AlphaBatcher ya ha utilizado Chatgpt para lograr un trading de precisión automatizado. Esta metodología no requiere una gran cantidad de capital ni habilidades de programación sólidas. Podemos utilizar la IA para potenciar nuestras inversiones en memecoin. El siguiente es el texto original (para una lectura y comprensión más sencillas, se ha eliminado y reorganizado el contenido original): Acabo de ganar $2300 en 1 minuto usando ChatGPT y PumpFun. Mientras otros seguían buscando oportunidades en memecoins, yo ya estaba automatizando el trading preciso. Solo necesitas 0,2 SOL para comenzar, y no se requieren habilidades de programación…