WEB3DEV

Cover image for Uma maneira melhor de inicializar os contratos atualizáveis
Dimitris Carvalho Calixto
Dimitris Carvalho Calixto

Posted on

Uma maneira melhor de inicializar os contratos atualizáveis

Visão geral

O código de contrato inteligente é imutável, o que significa que o código não pode ser alterado após a implantação. Isto apresenta desafios ao se desenvolver na blockchain, pois impede a capacidade de realizar manutenção ou atualizações. Os contratos inteligentes também enfrentam um limite de tamanho de contrato de 24KB, introduzindo dilemas de escalabilidade. O padrão EIP-2535 oferece um padrão proxy sofisticado que permite a adição, substituição e remoção de funções, ao mesmo tempo em que praticamente elimina qualquer restrição ao tamanho do código.

Embora os contratos inteligentes sejam imutáveis, eles podem adicionar e remover referências a funções externas em outros contratos inteligentes e ainda preservar o contexto de armazenamento, utilizando chamadas de delegados. Esta é a arquitetura padrão para sistemas de proxy.

Example: Proxy Contract

O padrão EIP-2535 Diamond introduz um contrato de proxy genérico, o Diamond, que inclui uma função interna DiamondCut() e expõe uma função fallback, que despacha dinamicamente chamadas de função para as facetas chamadas do Diamond.

Example: fallback() function

A função de fallback permite que as funções facetadas sejam executadas como se o Diamond as tivesse implementado. Os valores msg.sender e msg.value permanecem os mesmos, e o armazenamento do Diamond é lido e escrito para.

Um contrato de proxy do Diamond é uma fonte única para todos os dados variáveis do estado. As facetas fornecem o código e as definições de variáveis de estado usadas para ler e escrever no armazenamento de um contrato do proxy diamond.

Example: Diamond Contract with AppStorage

Um diamond contém dentro dele um mapeamento de seletores de funções para os endereços de faceta. As funções são adicionadas/substituídas/removidas modificando este mapeamento.

DiamondCut

A função DiamondCut é usada para adicionar/substituir/remover qualquer número de facetas e funções a um diamond em uma única transação, evitando um estado inconsistente no Diamond.

Example: IDiamondCut

A função diamondCut()pode executar uma função externa comdelegatecall` durante uma atualização. Isto é usado para inicializar variáveis de estado e fazer quaisquer mudanças necessárias para uma atualização.

Inicializando o Estado

O segundo e terceiro argumentos da função diamondCut() são usados para inicializar o estado após uma atualização. O argumento _init detém o endereço contratual de uma função a ser chamada para inicializar o estado do Diamond. O argumento _calldata tem uma chamada de função a ser enviada ao contrato em _init.

Exemplo - se um ERC20 Facet é adicionado ao Diamond usando um DiamondCut(), o argumento _calldata fornece a chamada de função para definir o nome do token e os valores do símbolo, e o argumento _init fornece o endereço do Facet com a função init. A função init é executada na mesma transação que a diamondCut().

A execução do _calldata é pulada se o valor _init for o endereço(0), portanto,o _calldata pode conter 0 bytes ou informações personalizadas.

DiamondInit

Depois de adicionar/substituir/remover funções, o argumento _calldata é executado com delegatecall em _init. Esta execução é feita para inicializar os dados, configurar ou remover qualquer coisa que não seja mais necessária. As funções DiamondInit podem ter parâmetros e podem ser reutilizadas conforme necessário, uma vez implantadas.

Example: DiamondInit

O EIP-2535 também define uma função DiamondMultiInit que executa múltiplas funções inicializadoras para uma única atualização. Isto pode ser útil quando os usuários quiserem suportar uma função de inicialização única por corte. DiamondMultiInit existe como uma biblioteca para evitar que ela seja apagada como resultado de uma delegatecall para selfdestruct .

DiamondMultiInit

Image description

Durante a execução de uma atualização, utilizando os argumentos _init e _calldata eles permitem que a inicialização do estado ocorra na mesma transação. Isto é importante porque impede que o Diamond caia em um estado inconsistente, que poderia surgir se as variáveis de estado não fossem inicializadas em sincronia com as funções que estão sendo adicionadas.

Conclusão

O EIP-2535 Diamonds introduz uma nova e melhor abordagem para a iniciação de contratos atualizáveis. O padrão fornece uma função para inicializações de uma e múltiplas funções após a função diamondCut(). A abordagem sincroniza a possibilidade de atualização e inicialização do estado na mesma transação, ajudando a garantir que o Diamond mantenha sempre um estado consistente.

Artigo escrito por John Reynolds. A versão original pode ser encontrada aqui. Traduzido e adaptado por Dimitris Calixto.

Latest comments (0)