Dicas de desenvolvimento de contratos aprendidas com o código Uniswap
Recentemente, ao escrever um tutorial de desenvolvimento de exchanges descentralizadas, consultei o código do Uniswap V3 e aprendi muitos pontos de conhecimento valiosos. Como desenvolvedor que está a fazer a sua primeira tentativa de desenvolver contratos DeFi, essas dicas serão muito úteis para iniciantes que desejam aprender sobre o desenvolvimento de contratos.
Endereço de implantação de contrato previsível
Normalmente, o endereço obtido ao implantar um contrato parece aleatório, pois está relacionado ao nonce. Mas em certas situações, precisamos inferir o endereço do contrato através de pares de negociação e informações relacionadas, como determinar permissões de negociação ou obter o endereço do pool.
A Uniswap utiliza o método CREATE2 para criar contratos, tornando o endereço gerado previsível ao adicionar o parâmetro salt. A lógica de cálculo do novo endereço é: hash("0xFF", endereço do criador, salt, initcode).
https://img-cdn.gateio.im/webp-social/moments-b0c3d4eb7e8ca88cc4cfc9476a34437a.webp(
Usando grandes números para resolver problemas de precisão
No código do Uniswap, existem muitas lógicas de cálculo, como calcular os tokens a serem trocados com base no preço atual e na liquidez. Para evitar a perda de precisão nas operações de divisão, o processo de cálculo frequentemente utiliza a operação "<< FixedPoint96.RESOLUTION", ou seja, desloca-se à esquerda 96 bits, equivalente a multiplicar por 2^96.
Após o deslocamento à esquerda, a operação de divisão pode ser realizada, garantindo a precisão em transações normais sem estouro. Embora teoricamente ainda haja perda mínima de precisão, isso é aceitável.
Calcular rendimentos com o modo Share
Uniswap precisa registrar os ganhos de taxas dos provedores de liquidez LP). Para evitar o consumo excessivo de Gas ao registrar as taxas para cada LP em cada transação, Uniswap adotou um método engenhoso.
A estrutura Position contém feeGrowthInside0LastX128 e feeGrowthInside1LastX128, que registram a taxa de juros que cada liquidez deveria receber na última retirada de taxas de cada posição. Basta registrar a taxa total e a taxa que cada liquidez deve receber, e a taxa que pode ser retirada pelo LP é calculada com base na liquidez detida.
Estratégia de obtenção de informações na blockchain
Nem toda a informação precisa ser obtida da cadeia. O armazenamento na cadeia é relativamente caro, e muitas informações podem ser armazenadas em bases de dados comuns, sincronizando-se periodicamente com a cadeia.
Como a lista de pools de negociação, informações do pool de negociação, etc., podem ser armazenadas em um banco de dados comum, sem a necessidade de chamar em tempo real a interface RPC de serviços de cadeia ou nós. Claro, transações chave ainda ocorrem na cadeia.
Divisão de Contratos e Utilização de Contratos Padrão
Um projeto pode conter múltiplos contratos realmente implementados. Mesmo que haja apenas um contrato realmente implementado, o código pode ser dividido e mantido em vários contratos através de herança.
Por exemplo, o contrato NonfungiblePositionManager da Uniswap herda vários contratos. Usando o contrato ERC721 da OpenZeppelin, é conveniente gerenciar posições através de NFTs e aumentar a eficiência do desenvolvimento.
Conclusão
A prática é o melhor método de aprendizagem. Tentar implementar uma versão simples de uma exchange descentralizada pode ajudar a entender profundamente a implementação do código do Uniswap, aprendendo mais sobre pontos de conhecimento em projetos práticos. Se estiver interessado no desenvolvimento de projetos Web3 e DeFi, pode consultar cursos práticos relacionados e completar gradualmente uma exchange simples.
Esta página pode conter conteúdo de terceiros, que é fornecido apenas para fins informativos (não para representações/garantias) e não deve ser considerada como um endosso de suas opiniões pela Gate nem como aconselhamento financeiro ou profissional. Consulte a Isenção de responsabilidade para obter detalhes.
Desvendando o código Uniswap: 7 dicas de desenvolvimento de contratos para ajudar novatos em DeFi
Dicas de desenvolvimento de contratos aprendidas com o código Uniswap
Recentemente, ao escrever um tutorial de desenvolvimento de exchanges descentralizadas, consultei o código do Uniswap V3 e aprendi muitos pontos de conhecimento valiosos. Como desenvolvedor que está a fazer a sua primeira tentativa de desenvolver contratos DeFi, essas dicas serão muito úteis para iniciantes que desejam aprender sobre o desenvolvimento de contratos.
Endereço de implantação de contrato previsível
Normalmente, o endereço obtido ao implantar um contrato parece aleatório, pois está relacionado ao nonce. Mas em certas situações, precisamos inferir o endereço do contrato através de pares de negociação e informações relacionadas, como determinar permissões de negociação ou obter o endereço do pool.
A Uniswap utiliza o método CREATE2 para criar contratos, tornando o endereço gerado previsível ao adicionar o parâmetro salt. A lógica de cálculo do novo endereço é: hash("0xFF", endereço do criador, salt, initcode).
https://img-cdn.gateio.im/webp-social/moments-b0c3d4eb7e8ca88cc4cfc9476a34437a.webp(
Usando grandes números para resolver problemas de precisão
No código do Uniswap, existem muitas lógicas de cálculo, como calcular os tokens a serem trocados com base no preço atual e na liquidez. Para evitar a perda de precisão nas operações de divisão, o processo de cálculo frequentemente utiliza a operação "<< FixedPoint96.RESOLUTION", ou seja, desloca-se à esquerda 96 bits, equivalente a multiplicar por 2^96.
Após o deslocamento à esquerda, a operação de divisão pode ser realizada, garantindo a precisão em transações normais sem estouro. Embora teoricamente ainda haja perda mínima de precisão, isso é aceitável.
Calcular rendimentos com o modo Share
Uniswap precisa registrar os ganhos de taxas dos provedores de liquidez LP). Para evitar o consumo excessivo de Gas ao registrar as taxas para cada LP em cada transação, Uniswap adotou um método engenhoso.
A estrutura Position contém feeGrowthInside0LastX128 e feeGrowthInside1LastX128, que registram a taxa de juros que cada liquidez deveria receber na última retirada de taxas de cada posição. Basta registrar a taxa total e a taxa que cada liquidez deve receber, e a taxa que pode ser retirada pelo LP é calculada com base na liquidez detida.
Estratégia de obtenção de informações na blockchain
Nem toda a informação precisa ser obtida da cadeia. O armazenamento na cadeia é relativamente caro, e muitas informações podem ser armazenadas em bases de dados comuns, sincronizando-se periodicamente com a cadeia.
Como a lista de pools de negociação, informações do pool de negociação, etc., podem ser armazenadas em um banco de dados comum, sem a necessidade de chamar em tempo real a interface RPC de serviços de cadeia ou nós. Claro, transações chave ainda ocorrem na cadeia.
Divisão de Contratos e Utilização de Contratos Padrão
Um projeto pode conter múltiplos contratos realmente implementados. Mesmo que haja apenas um contrato realmente implementado, o código pode ser dividido e mantido em vários contratos através de herança.
Por exemplo, o contrato NonfungiblePositionManager da Uniswap herda vários contratos. Usando o contrato ERC721 da OpenZeppelin, é conveniente gerenciar posições através de NFTs e aumentar a eficiência do desenvolvimento.
Conclusão
A prática é o melhor método de aprendizagem. Tentar implementar uma versão simples de uma exchange descentralizada pode ajudar a entender profundamente a implementação do código do Uniswap, aprendendo mais sobre pontos de conhecimento em projetos práticos. Se estiver interessado no desenvolvimento de projetos Web3 e DeFi, pode consultar cursos práticos relacionados e completar gradualmente uma exchange simples.