Hardhat-deploy: Suporte de proxy OpenZeppelin UUPS

Criado em 28 jun. 2021  ·  13Comentários  ·  Fonte: wighawag/hardhat-deploy

Vejo que OpenZeppelinTransparentProxy é compatível. Existem planos para adicionar suporte de proxy UUPS em um futuro próximo?

enhancement

Comentários muito úteis

Planejando oferecer suporte nativo, mas por enquanto ainda é possível usá-los com o implante de hardhat. o proxy precisa ter um argumento de proprietário fictício / não utilizado em seu construtor para permanecer compatível.

Todos 13 comentários

Planejando oferecer suporte nativo, mas por enquanto ainda é possível usá-los com o implante de hardhat. o proxy precisa ter um argumento de proprietário fictício / não utilizado em seu construtor para permanecer compatível.

o proxy precisa ter um argumento de proprietário fictício / não utilizado em seu construtor para permanecer compatível.

Isso não faria com que o uso do UUPS deixasse de ser benéfico? O motivo de usar o UUPS é economizar gás nas chamadas de transação, porque o proxy não precisa verificar se é o administrador que está fazendo a chamada.

Talvez eu esteja perdendo, você poderia explicar com algum pseudocódigo como usar o hardhat-deploy com uups proxies (com o argumento não utilizado)?

Obrigado

Não afetará o gás, é apenas um argumento fictício para que o hardhat-deploy possa implantá-lo sem mudança de código. o construtor não precisa fazer nada com esse argumento.
Vou ver se consigo fazer a alteração para que funcione sem qualquer alteração em breve. deve ser uma pequena mudança onde você pode especificar o argumento do construtor para o proxy ou talvez simplesmente especificar que é um proxy UUPS

Obrigado @wighawag , finalmente

Para os interessados ​​criei este contrato:

pragma solidity ^0.8.0;

import "@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol";

// Kept for backwards compatibility with older versions of Hardhat and Truffle plugins.
contract UUPSProxy is ERC1967Proxy {
  constructor(
    address _logic,
    address, // This is completely unused by the uups proxy, required to remain compatible with hardhat deploy: https://github.com/wighawag/hardhat-deploy/issues/146
    bytes memory _data
  ) payable ERC1967Proxy(_logic, _data) {}
}

E então minhas implantações se parecem com isto ( proxyContract: "UUPSProxy" sendo a parte importante):

  await deploy(CONTRACT, {
    from: deployer,
    proxy: {
      proxyContract: "UUPSProxy",
      // ... your other config, initializers etc
    },
    log: true,
  });

@JasoonS Por favor, você pode esclarecer o propósito desse código de contrato UUPSProxy ? É apenas um contrato fictício para que o hardhat-deploy conheça a interface do construtor do proxy real? Ou ele realmente se relaciona de alguma forma com o contrato de proxy que é implantado?

Qual é exatamente a função de admin , eu obtenho um erro não importa se está lá, o deployer (= upgrade admin) ou se omito o campo.

proxy: {
      proxyContract: "UUPSProxy",
      execute: {
        methodName: "initialize",
        args: [admin],
      },
    },

@marceljay Por favor (sempre) cole o (s) erro (s) que você obtiver :-)

Olá @aspiers , Não cavei profundamente no hardhat-deploy, então corrija-me @wighawag. Mas pelo que entendi sabe como implantar proxies transparentes. E os proxies transparentes são implantados com um administrador que gerencia esses proxies. Em contratos UUPS, você não tem um contrato externo (proxy admin) gerenciando as atualizações, ele está na própria implementação - portanto, não é passado para o construtor de proxy.

Então, para fazer isso funcionar com o hardhat-deploy, nós o implantamos com o mesmo construtor de um proxy transparente, mas apenas ignoramos o campo admin e obtemos o mesmo efeito.

Parece estar funcionando para mim @marceljay

Isenção de responsabilidade meu snippet de código não foi auditado: sweat_smile: - Não me responsabilizo por proxies mal configurados: rindo:

@marceljay Ah, sim, posso adivinhar o seu problema. Eu editei minha resposta original.

O código a seguir é o que fazer na implementação. Portanto, tenho uma função na implementação (não o proxy) chamada initialize que leva em 1 argumento (o admin).

execute: {
  methodName: "initialize",
  args: [admin],
},

@marceljay Ah, sim, posso adivinhar o seu problema. Eu editei minha resposta original.

O código a seguir é o que fazer na implementação. Portanto, tenho uma função na implementação (não o proxy) chamada initialize que leva em 1 argumento (o admin).

execute: {
  methodName: "initialize",
  args: [admin],
},

Sim, agora faz todo o sentido, vi que você editou a resposta :)

Você sabe se o contrato ERC1967Proxy é o mesmo que é usado pelo plug-in de atualizações OZ?

@JasoonS Graças um lote para as explicações, mas eu ainda não entendo completamente. Acima, você postou um contrato começando:

contract UUPSProxy is ERC1967Proxy {

Isso realmente é implantado de verdade pelo código de amostra await deploy que você postou acima ou é apenas um contrato fictício para que o hardhat-deploy conheça a interface do construtor do proxy real ou algo mais? Você escreveu:

nós o implantamos com o mesmo construtor de um proxy transparente

mas se estiver realmente implantando isso, não vejo como poderia funcionar, porque esse contrato herda de ERC1967Proxy não UUPSUpgradeable , então de onde viria a funcionalidade UUPS real?

Isso realmente é implantado de verdade pelo código de amostra, aguarda implantação que você postou acima?

Sim, ele realmente o implanta.

porque esse contrato herda de ERC1967Proxy e não UUPSUpgradeable

Ele deve usar o ERC1967Proxy (UUPS e proxies transparentes do openzeppelin usam erc1967, https://docs.openzeppelin.com/contracts/4.x/api/proxy#transparent-vs-uups). O contrato UUPSUpgradeable é usado pelo contrato de implementação (não faz parte do proxy).

então, de onde viria a funcionalidade UUPS real?

Por design, o contrato de implementação mantém a funcionalidade UUPS, (o que é bom porque é mais eficiente em termos de gás, uma vez que a lógica não está no próprio proxy, mas ruim porque é possível atualizar para um contrato não compatível por engano e interromper a capacidade de atualização )

Além disso, definitivamente não sou um especialista em proxies, isso veio apenas de minha própria pesquisa.

@JasoonS comentou em 1º de setembro de 2021 21:18 :

porque esse contrato herda de ERC1967Proxy e não UUPSUpgradeable

Ele deve usar o ERC1967Proxy (UUPS e proxies transparentes do openzeppelin usam erc1967, docs.openzeppelin.com/contracts/4.x/api/proxy#transparent-vs-uups ).

Direito. E o ERC-1967 não faz muito, exceto especificar o local de armazenamento do endereço de implementação, endereço de beacon e endereço de administrador. BTW fato engraçado que notei: em conformidade com ERC-1967, a implementação OZ UUPS na verdade viola EIP1822 que especifica um local de armazenamento ligeiramente diferente para o endereço de implementação.

O contrato UUPSUpgradeable é usado pelo contrato de implementação (não faz parte do proxy).

D'oh, é claro! Obrigado por me ajudar a ver o que eu estava perdendo estupidamente aqui.

então, de onde viria a funcionalidade UUPS real?

Por design, o contrato de implementação mantém a funcionalidade UUPS, (o que é bom porque é mais eficiente em termos de gás, uma vez que a lógica não está no próprio proxy, mas ruim porque é possível atualizar para um contrato não compatível por engano e interromper a capacidade de atualização )

Sim, então a implementação deve herdar de UUPSUpgradeable .

Muito obrigado novamente por esta grande ajuda!

Esta página foi útil?
0 / 5 - 0 avaliações