Hardhat-deploy: OpenZeppelin UUPS-Proxy-Unterstützung

Erstellt am 28. Juni 2021  ·  13Kommentare  ·  Quelle: wighawag/hardhat-deploy

Ich sehe, dass OpenZeppelinTransparentProxy unterstützt wird. Gibt es Pläne, in naher Zukunft UUPS-Proxy- Unterstützung hinzuzufügen?

enhancement

Hilfreichster Kommentar

Es ist geplant, nativ zu unterstützen, aber im Moment ist es noch möglich, sie mit Hardhat-Deploy zu verwenden. der Proxy-Jist muss in seinem Konstruktor ein Dummy/unbenutztes Eigentümerargument haben, um kompatibel zu bleiben.

Alle 13 Kommentare

Es ist geplant, nativ zu unterstützen, aber im Moment ist es noch möglich, sie mit Hardhat-Deploy zu verwenden. der Proxy-Jist muss in seinem Konstruktor ein Dummy/unbenutztes Eigentümerargument haben, um kompatibel zu bleiben.

der Proxy-Jist muss in seinem Konstruktor ein Dummy/unbenutztes Eigentümerargument haben, um kompatibel zu bleiben.

Wäre die Verwendung von UUPS dadurch nicht mehr von Vorteil? Der Grund für die Verwendung von UUPS besteht darin, bei Transaktionsaufrufen Gas zu sparen, da der Proxy nicht überprüfen muss, ob es sich um den Administrator handelt, der den Anruf tätigt.

Vielleicht übersehe ich es, könnten Sie mit etwas Pseudo-Code erläutern, wie man Hardhat-Deploy mit uups-Proxys (mit dem unbenutzten Argument) verwendet?

Vielen Dank

Es wirkt sich nicht auf Gas aus, es ist nur ein Dummy-Arg, damit Hardhat-deploy es ohne Codeänderung bereitstellen kann. der Konstruktor braucht mit diesem Argument nichts zu tun.
Mal sehen, ob ich die Änderung vornehmen kann, damit es bald ohne Änderung funktioniert. Es sollte eine kleine Änderung sein, bei der Sie das Konstruktorarg für den Proxy angeben oder einfach angeben können, dass es sich um einen UUPS-Proxy handelt

Danke @wighawag ,

Für Interessierte habe ich diesen Vertrag erstellt:

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) {}
}

Und dann sehen meine Bereitstellungen ungefähr so ​​​​aus ( proxyContract: "UUPSProxy" ist der wichtige Teil):

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

@JasoonS Können Sie bitte den Zweck dieses UUPSProxy Vertragscodes klären? Ist es nur ein Dummy-Vertrag, damit hardhat-deploy die Schnittstelle des eigentlichen Proxy-Konstruktors kennt? Oder hängt es tatsächlich irgendwie mit dem Proxy-Vertrag zusammen, der bereitgestellt wird?

Was genau ist die Rolle von admin , bekomme ich eine Fehlermeldung egal ob dort das deployer (=Upgrade Admin) steht oder ob ich das Feld weglasse.

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

@marceljay Bitte

Hallo @aspiers , ich habe mich nicht Bauarbeiterhelmen beschäftigt , also korrigiert mich bitte @wighawag. Aber soweit ich weiß, weiß es, wie man transparente Proxys einsetzt. Und transparente Proxys werden mit einem Administrator bereitgestellt, der diese Proxys verwaltet. In UUPS-Verträgen haben Sie keinen externen Vertrag (Proxy-Administrator), der die Upgrades verwaltet, sondern befindet sich in der Implementierung selbst - wird also nicht an den Proxy-Konstruktor übergeben.

Damit dies mit hardhat-deploy funktioniert, implementieren wir es mit demselben Konstruktor wie einen transparenten Proxy, ignorieren jedoch einfach das Admin-Feld und erhalten den gleichen Effekt.

Scheint bei mir zu funktionieren @marceljay

Haftungsausschluss mein Code-Snippet wird nicht geprüft :sweat_smile: - Ich übernehme keine Verantwortung für schlecht konfigurierte Proxys :lacht:

@marceljay Ah, ja, ich kann dein Problem erraten. Ich habe meine ursprüngliche Antwort bearbeitet.

Der folgende Code zeigt, was in der Implementierung zu tun ist. Also habe ich eine Funktion für die Implementierung (nicht den Proxy) namens initialize, die 1 Argument (den Admin) aufnimmt.

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

@marceljay Ah, ja, ich kann dein Problem erraten. Ich habe meine ursprüngliche Antwort bearbeitet.

Der folgende Code zeigt, was in der Implementierung zu tun ist. Also habe ich eine Funktion für die Implementierung (nicht den Proxy) namens initialize, die 1 Argument (den Admin) aufnimmt.

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

Ja, jetzt macht es absolut Sinn, ich habe gesehen, dass du die Antwort bearbeitet hast :)

Wissen Sie, ob der ERC1967Proxy Vertrag derselbe ist, der vom OZ-Upgrade-Plugin verwendet wird?

@JasoonS Vielen Dank für die Erklärungen , aber ich weiß immer noch nicht voll es. Oben haben Sie einen Vertrag gepostet, der beginnt:

contract UUPSProxy is ERC1967Proxy {

Wird das tatsächlich durch den oben geposteten Beispielcode await deploy bereitgestellt , oder ist es nur ein Dummy-Vertrag, damit hardhat-deploy die Schnittstelle des tatsächlichen Proxy-Konstruktors oder etwas anderes kennt? Sie schrieben:

Wir stellen es mit demselben Konstruktor wie einen transparenten Proxy bereit

aber wenn es wirklich bereitgestellt wird, dann sehe ich nicht, wie es möglicherweise funktionieren könnte, da dieser Vertrag von ERC1967Proxy nicht von UUPSUpgradeable erbt, also woher würde die eigentliche UUPS-Funktionalität kommen?

Wird das tatsächlich durch den oben geposteten Beispiel-Await-Deploy-Code bereitgestellt?

Ja, es setzt es tatsächlich ein.

weil dieser Vertrag von ERC1967Proxy erbt, nicht UUPSUpgradeable

Es soll den ERC1967Proxy verwenden (sowohl UUPS als auch transparente Proxys von openzeppelin verwenden erc1967, https://docs.openzeppelin.com/contracts/4.x/api/proxy#transparent-vs-uups). Der UUPSUpgradeable Vertrag wird vom Implementierungsvertrag verwendet (er ist nicht Teil des Proxys).

Also woher würde die eigentliche UUPS-Funktionalität kommen?

Vom Design her enthält der Implementierungsvertrag die UUPS-Funktionalität (was gut ist, weil es gaseffizienter ist, da die Logik nicht im Proxy selbst ist, aber schlecht, weil es möglich ist, versehentlich auf einen nicht kompatiblen Vertrag zu aktualisieren und die Upgrade-Fähigkeit zu unterbrechen ).

Außerdem bin ich definitiv kein Experte für Proxys, das ist nur aus meiner eigenen Forschung.

@JasoonS kommentierte den 1. September 2021 um 21:18 Uhr :

weil dieser Vertrag von ERC1967Proxy erbt, nicht UUPSUpgradeable

Es soll den ERC1967Proxy verwenden (sowohl UUPS als auch transparente Proxys von openzeppelin verwenden erc1967, docs.openzeppelin.com/contracts/4.x/api/proxy#transparent-vs-uups ).

Rechts. Und ERC-1967 macht nicht viel, außer den Speicherort der Implementierungsadresse, der Beacon-Adresse und der Admin-Adresse anzugeben. Übrigens, eine lustige Tatsache, die mir aufgefallen ist: In Übereinstimmung mit ERC-1967 verstößt die OZ UUPS-Implementierung tatsächlich gegen EIP1822, die einen etwas anderen Speicherort für die Implementierungsadresse angibt.

Der UUPSUpgradeable Vertrag wird vom Implementierungsvertrag verwendet (er ist nicht Teil des Proxys).

D'oh, natürlich! Danke, dass du mir geholfen hast zu sehen, was ich hier dummerweise übersehen habe.

Also woher würde die eigentliche UUPS-Funktionalität kommen?

Vom Design her enthält der Implementierungsvertrag die UUPS-Funktionalität (was gut ist, weil es gaseffizienter ist, da die Logik nicht im Proxy selbst ist, aber schlecht, weil es möglich ist, versehentlich auf einen nicht kompatiblen Vertrag zu aktualisieren und die Upgrade-Fähigkeit zu unterbrechen ).

Ja, also muss die Implementierung von UUPSUpgradeable erben.

Nochmals vielen Dank für diese tolle Hilfe!

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen