Dicas de desenvolvimento de contratos: lições aprendidas com o Uniswap
Recentemente, ao desenvolver um projeto de troca descentralizada, consultei a implementação de código de um conhecido DEX e aprendi muitos pontos úteis. Como um novato que acaba de entrar no desenvolvimento de contratos DeFi, essas técnicas foram muito inspiradoras para mim, e acredito que também serão úteis para outros amigos que desejam aprender sobre desenvolvimento de contratos inteligentes.
Endereço de contrato previsível
Normalmente, o endereço obtido ao implantar um contrato parece aleatório, pois está relacionado ao nonce. No entanto, em certos cenários, precisamos inferir o endereço do contrato a partir das informações da transação, como determinar as permissões de transação ou obter o endereço do pool de liquidez.
Isto pode ser alcançado criando um contrato usando o método CREATE2. A maneira específica de fazer isso é adicionar o parâmetro salt ao criar o contrato:
solidez
pool = address(new UniswapV3Pool{salt: keccak256(abi.encode(token0, token1, fee))}());
O endereço do contrato gerado dessa forma é previsível e segue a seguinte lógica:
Novo endereço = hash("0xFF", endereço do criador, salt, initcode)
https://img-cdn.gateio.im/webp-social/moments-b0c3d4eb7e8ca88cc4cfc9476a34437a.webp(
Usando números grandes para resolver problemas de precisão
Ao lidar com códigos que envolvem cálculos, deve-se evitar a perda de precisão durante operações de divisão. Certos DEX costumam utilizar a operação "<< FixedPoint96.RESOLUTION", que equivale a multiplicar por 2^96. Após o deslocamento à esquerda, realizar a divisão pode garantir precisão sem transbordo.
Embora teoricamente ainda possa haver perda de precisão, geralmente é apenas uma perda da unidade mínima, o que é aceitável.
Cálculo de rendimento pelo método Share
Para o cálculo da receita de taxas dos provedores de liquidez )LP(, não é possível registrar cada transação, pois isso consumiria uma quantidade enorme de Gas. Um certo DEX adota a abordagem de registrar a taxa total e a taxa que deve ser atribuída a cada liquidez.
Ao retirar a taxa de serviço de LP, o montante que pode ser retirado é calculado com base na liquidez detida. Semelhante a possuir ações de uma empresa, ao retirar os lucros, é suficiente conhecer o histórico de lucros por ação e os lucros da última retirada.
![Web3 Novato Série: Dicas de desenvolvimento de contratos que aprendi com o código do Uniswap])https://img-cdn.gateio.im/webp-social/moments-45e66af69435e6d4412ae506e77ab893.webp(
Escolher de forma razoável o método de obtenção de informações
O armazenamento em cadeia é relativamente caro, nem todas as informações precisam ser armazenadas na cadeia ou obtidas da cadeia. Por exemplo, listas de pools de transações e informações podem ser armazenadas em um banco de dados comum, sincronizando-se periodicamente com a cadeia.
Alguns fornecedores de RPC de blockchain oferecem interfaces avançadas, permitindo obter dados de forma mais rápida. Mas as transações-chave ainda precisam ser realizadas na cadeia.
Divisão de contratos e reutilização de contratos padrão
Um projeto pode conter vários contratos, mesmo que um único contrato seja realmente implantado, ele pode ser dividido em vários contratos para manutenção através de herança.
O contrato de gestão de posição NFT de um certo DEX herda vários contratos:
Ao mesmo tempo, também utiliza o contrato padrão ERC721 da OpenZeppelin, facilitando a gestão de posições e aumentando a eficiência de desenvolvimento.
Resumo
Desenvolver manualmente uma versão simplificada de uma exchange descentralizada permitirá que você compreenda melhor a implementação do código de projetos maduros e aprenda mais pontos de conhecimento práticos. Espero que essas dicas o inspirem, desejo sucesso no desenvolvimento!
![Série para iniciantes em Web3: Dicas de desenvolvimento de contratos que aprendi com o código do Uniswap])https://img-cdn.gateio.im/webp-social/moments-f95ddc9d89809cf11dbe65b9bafda157.webp(
Esta página pode conter conteúdos de terceiros, que são fornecidos apenas para fins informativos (sem representações/garantias) e não devem ser considerados como uma aprovação dos seus pontos de vista pela Gate, nem como aconselhamento financeiro ou profissional. Consulte a Declaração de exoneração de responsabilidade para obter mais informações.
7 dicas práticas para aprender o desenvolvimento de contratos DEX populares
Dicas de desenvolvimento de contratos: lições aprendidas com o Uniswap
Recentemente, ao desenvolver um projeto de troca descentralizada, consultei a implementação de código de um conhecido DEX e aprendi muitos pontos úteis. Como um novato que acaba de entrar no desenvolvimento de contratos DeFi, essas técnicas foram muito inspiradoras para mim, e acredito que também serão úteis para outros amigos que desejam aprender sobre desenvolvimento de contratos inteligentes.
Endereço de contrato previsível
Normalmente, o endereço obtido ao implantar um contrato parece aleatório, pois está relacionado ao nonce. No entanto, em certos cenários, precisamos inferir o endereço do contrato a partir das informações da transação, como determinar as permissões de transação ou obter o endereço do pool de liquidez.
Isto pode ser alcançado criando um contrato usando o método CREATE2. A maneira específica de fazer isso é adicionar o parâmetro salt ao criar o contrato:
solidez pool = address(new UniswapV3Pool{salt: keccak256(abi.encode(token0, token1, fee))}());
O endereço do contrato gerado dessa forma é previsível e segue a seguinte lógica:
Novo endereço = hash("0xFF", endereço do criador, salt, initcode)
https://img-cdn.gateio.im/webp-social/moments-b0c3d4eb7e8ca88cc4cfc9476a34437a.webp(
Usando números grandes para resolver problemas de precisão
Ao lidar com códigos que envolvem cálculos, deve-se evitar a perda de precisão durante operações de divisão. Certos DEX costumam utilizar a operação "<< FixedPoint96.RESOLUTION", que equivale a multiplicar por 2^96. Após o deslocamento à esquerda, realizar a divisão pode garantir precisão sem transbordo.
solidity uint256 numerator1 = uint256)liquidity( << FixedPoint96.RESOLUTION; uint256 numerator2 = sqrtRatioBX96 - sqrtRatioAX96; amount0 = numerator1 * numerator2 / )sqrtRatioBX96 * sqrtRatioAX96(;
Embora teoricamente ainda possa haver perda de precisão, geralmente é apenas uma perda da unidade mínima, o que é aceitável.
Cálculo de rendimento pelo método Share
Para o cálculo da receita de taxas dos provedores de liquidez )LP(, não é possível registrar cada transação, pois isso consumiria uma quantidade enorme de Gas. Um certo DEX adota a abordagem de registrar a taxa total e a taxa que deve ser atribuída a cada liquidez.
Ao retirar a taxa de serviço de LP, o montante que pode ser retirado é calculado com base na liquidez detida. Semelhante a possuir ações de uma empresa, ao retirar os lucros, é suficiente conhecer o histórico de lucros por ação e os lucros da última retirada.
![Web3 Novato Série: Dicas de desenvolvimento de contratos que aprendi com o código do Uniswap])https://img-cdn.gateio.im/webp-social/moments-45e66af69435e6d4412ae506e77ab893.webp(
Escolher de forma razoável o método de obtenção de informações
O armazenamento em cadeia é relativamente caro, nem todas as informações precisam ser armazenadas na cadeia ou obtidas da cadeia. Por exemplo, listas de pools de transações e informações podem ser armazenadas em um banco de dados comum, sincronizando-se periodicamente com a cadeia.
Alguns fornecedores de RPC de blockchain oferecem interfaces avançadas, permitindo obter dados de forma mais rápida. Mas as transações-chave ainda precisam ser realizadas na cadeia.
Divisão de contratos e reutilização de contratos padrão
Um projeto pode conter vários contratos, mesmo que um único contrato seja realmente implantado, ele pode ser dividido em vários contratos para manutenção através de herança.
O contrato de gestão de posição NFT de um certo DEX herda vários contratos:
solidez contrato NonfungiblePositionManager é INonfungiblePositionManager, Multicall, PeripheryImmutableState, PoolInitializer, GestãoDeLiquidez, PeripheryValidation, SelfPermit, ERC721Permit {...}
Ao mesmo tempo, também utiliza o contrato padrão ERC721 da OpenZeppelin, facilitando a gestão de posições e aumentando a eficiência de desenvolvimento.
Resumo
Desenvolver manualmente uma versão simplificada de uma exchange descentralizada permitirá que você compreenda melhor a implementação do código de projetos maduros e aprenda mais pontos de conhecimento práticos. Espero que essas dicas o inspirem, desejo sucesso no desenvolvimento!
![Série para iniciantes em Web3: Dicas de desenvolvimento de contratos que aprendi com o código do Uniswap])https://img-cdn.gateio.im/webp-social/moments-f95ddc9d89809cf11dbe65b9bafda157.webp(