Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Revisar funcionamiento de proxy pattern para contratos upgradeables. #79

Open
nefera606 opened this issue Apr 20, 2020 · 1 comment
Open
Assignees

Comments

@nefera606
Copy link
Collaborator

Comptaible con versionado ya incluido.
Estudiar la inclusión de los dos patrones para un funcionamiento idoneo.

@Jiang-dxc Jiang-dxc self-assigned this Apr 20, 2020
@Jiang-dxc
Copy link

Buenas, pongo por aquí mi análisis sobre proxy pattern de open-zeppelin(Soy partidario de usar este método porque es elegante y por la experiencia que he tendido). La única duda que tengo sobre la implementación con el approach de storages propuesto por Iñigo es el problema de añadir variables nuevas. Como ha dicho Iñigo en el call, haría falta crear nuevos contratos storages y es posible convivir con otros storages antiguos, añadiría complejidad de los códigos. Si hablamos del approach de storage, propongo a mirar también el approach de "eternal storage", es como almacenar datos en redis, por key generado con el hash de nombre de variable. Con este método, se podría tener un único contrato storage para siempre, la desventaja, un poco verboso a la hora de usar y tocar cambiar muchos códigos actuales.

Cómo funciona Proxy pattern de open-zeppelin

Básicamente en este post se explica muy bien el funcionamiento de este approach.

  • Se despliega 2 contractos, un contrato proxy otro contrato de "implementación" en conjunto
  • a la hora de ejecutar una función, se llama a través del contrato proxy, el cual haciendo un delegatecall al contrato de la implementación, hace ejecutar el código de la implementación sobre el contexto del proxy, es decir, se ejecuta una función implementada en el segundo modificando las variables de estado del proxy.
  • El tema de contexto y la inferencia de variables se explica muy bien en este post, básicamente, cuando se quiere recuperar una variable "a", por debajo es buscar su declaración y traducirlo a la posición donde ubica esa variable y el tamaño en el storage de un contrato. El layout de storage del contrato proxy es un espejo del contrato lógico(de implementación) Es por eso cuando ejecuta sobre el código de implementación puede actualizar correctamente las variables de estado del proxy.
  • la librería de open-zeppelin por debajo hace estos 4 pasos para desplegar contratos actualizables:
  impl = await ContractImplementation.new()
  proxy = await Proxy.new(impl.address)
  contractImplementation = await ContractImplementation.at(proxy.address)
  await contractImplementation.initialize(…initializationParameters)

Ventajas

  • Fácil de actualizar contratos existentes, simplemente cambiar el constructor por una función initialize
  • Fácil de mantener, el contrato proxy es universal para todos los contratos que quieren ser actualizables, y estos una vez adaptado a ser actualizables se mantendrían 90% de su código original.
  • Fácil de actualizar, simplemente se despliega la nueva versión del contrato de implementación y se actualiza desde el proxy su address.
  • Como es el contrato de implementación el cual se actualiza siempre, el address del contrato proxy nunca es modificado, hace que el mantenimiento de la aplicación sea un poco más fácil todavía.

Desventajas

  • limitaciones explicados en este post
  • seguir las pautas explicadas en este post

delegatecall

Hay 2 puntos donde hay que tener cuidado sobre delegatecall

  • llamar a otro contrato externo no controlado con el delegatecall, en este caso, el contrato de implementación es gestionado por el desarrollador de la aplicación, por lo cual el riesgo es bajo.
  • las colisiones de las funciones, se evita posible colisión de funciones con tener un alto coverage de los tests unitarios.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants