¿Cómo el contrato cuesta menos estructuras de gas?

Tengo un par de preguntas.

  1. tenemos tipos int como uint8, uint16, uint32, etc.leí eso:

Normalmente, no hay ningún beneficio en el uso de estos subtipos porque Solidity reserva 256 bits de almacenamiento, independientemente del tamaño de la unidad. Por ejemplo, usar uint8 en lugar de uint (uint256) no le ahorrará gasolina.

Entonces, si escribo directamente en el contrato como variable de estado algo como esto:

  • uint8 prueba1;
  • uint32 prueba2;
  • uint prueba3;

¿Por qué no uint8 testtendré menos consumo de gas donde lo use que uint32 test2? Lo pregunto porque con uint8 test1, uso menos espacio de almacenamiento.

  1. Digamos que uso struct de manera diferente.
// way1
struct Person {
  uint8 test1;
  uint32 test2;
  uint8 test3;
}


// way2
struct Person {
  uint8 test1;
  uint8 test2;
  uint32 test3;
}

¿Por qué la segunda forma consumiría menos gasolina que la primera? Si observamos ambas estructuras, ambas consumen la misma cantidad de almacenamiento, pero aun así se dice que way2 será mucho mejor con menos consumo de gas. Por qué ?

Respuestas (1)

Se trata de cómo se empaquetan las variables y de qué tan inteligente es el compilador (pista: no muy inteligente). El compilador solo intenta empaquetar las variables subsiguientes, pero no puede empaquetar variables que tengan algo más entre ellas.

En su primer caso, todas las variables podrían caber dentro de una sola ranura de 32 bytes, pero si no me equivoco, el compilador no hace eso porque son de diferentes tipos. En su segundo caso, las dos primeras variables son del mismo tipo y se pueden empaquetar estrechamente dentro de una ranura, por lo tanto, se ahorra gasolina.

Puede leer más sobre el empaquetado de variables, por ejemplo, aquí: https://fravoll.github.io/solidity-patterns/tight_variable_packing.html

Entonces, si no uso struct, y solo tengo uint8 test1; uint8 prueba2; como las variables de estado (globales) en contrato, ellas (cada una de ellas) usan ranuras de 32 bytes por separado a pesar de que podrían haber usado la misma ranura, pero aún así no, usan otras separadas y en el caso de uint8 (8 bits), 256-8 = 248 bits simplemente no hacen nada, ¿correcto? entonces, para las variables de estado, no tengo que pensar en nada y puedo escribir uint todo el tiempo. si es estructura, ahí es donde tengo que pensar. aceptar ?
Este patrón también funciona para variables de estado. Cita del enlace: "Como se insinuó en la sección de Aplicabilidad, este patrón se puede usar para variables de estado, estructuras internas y matrices de tamaño estático"