La verdad oculta de las variables privadas


Actualmente Solidity es el lenguaje de programación por excelencia cuando se quiere desarrollar un smart contract. Sin embargo, uno de los conceptos que puede resultar confuso para los desarrolladores, especialmente para los nuevos en el ecosistema, es el manejo de las variables privadas. A continuación, desglosaremos qué son las variables privadas, cómo funcionan y las implicaciones de su uso.

¿Qué son las variables privadas?

Las variables en Solidity pueden tener diferentes niveles de visibilidad: public, internal, private y external. Las variables privadas son aquellas que solo pueden ser accedidas dentro del contrato en el que se definen. Esto implica que no son accesibles desde otros contratos.

contract MiContrato {
    // Variable privada
    uint private contador;

    function incrementar() public {
        contador++;
    }

    function obtenerContador() public view returns (uint) {
        return contador;
    }
}

La ilusión de la privacidad

A pesar de que las variables privadas no pueden ser accedidas directamente desde otros contratos, su información si puede ser expuesta.

Uno de los mayores beneficios de las blockchains públicas es que son transparentes. Todos los datos son visibles, lo que plantea la pregunta: ¿podemos acceder a la información de las variables? Para entender esto, primero debemos conocer los modificadores de acceso en Solidity.

Modificadores de Acceso en Solidity

  • Public: Disponible para cuentas externas (EOAs), contratos externos y el mismo contrato.
  • External: Disponible para EOAs y contratos externos, pero no para el mismo contrato.
  • Internal: Disponible para contratos que heredan el contrato con funciones internas.
  • Private: No disponible para nadie más; solo visible dentro del contrato.

Estos modificadores son específicos de Solidity y no impiden que los datos sean accesibles desde fuera de la blockchain. La transparencia de la blockchain significa que, aunque las variables estén marcadas como privadas, aún se puede acceder a ellas consultando directamente la blockchain.

Cómo acceder a datos privados

Los smart contracts son cuentas en Ethereum que pueden almacenar código de bytes y estado. La información de estado se almacena en el estado global de la cadena, que es inherentemente público.

Las variables en Solidity se almacenan en slots de almacenamiento de 32 bytes, y se organizan secuencialmente según el orden de declaración. Si conoces el slot en el que se almacena una variable privada, puedes acceder directamente a ella.

contract ContratoSecreto {
    uint256 private datoPrivado;
    uint256 public datoPublico;

    constructor(uint256 numeroSecreto, uint256 numeroPublico) {
        datoPrivado = numeroSecreto;
        datoPublico = numeroPublico;
    }
}

En este contrato, datoPrivado es privada y datoPublico es pública. Aunque no podemos acceder a datoPrivado directamente, podemos usar la función providers.getStorage() de Ethers.

Leer y decodificar variables

La función getStorageAt toma dos parámetros:

  1. Dirección del contrato.
  2. Slot desde el cual leer los bytes.

Dado que privateVariable ocupa el primer slot (slot 0), podemos acceder a él así:

const slot0Bytes = await ethers.provider.getStorage(<ContractAddress>, 0)
const decodifiedValue = ethers.AbiCoder.defaultAbiCoder().decode(['uint256'], slot0Bytes )

Este método permite leer el valor de la variable privada, confirmando que los datos en slot 0 corresponden al valor almacenado.

Conclusión

Las variables privadas en Solidity ofrecen un nivel de control sobre quién puede acceder a ellas dentro del mismo contrato. Sin embargo, este control no implica que los datos sean completamente inaccesibles. Aunque las variables privadas no pueden ser accedidas directamente desde otros contratos, su información puede ser consultada desde la blockchain, dado que esta es inherentemente pública.

Por lo tanto, si se requiere almacenar información sensible en un smart contracts, es fundamental utilizar técnicas de cifrado. De este modo, los datos se pueden proteger de accesos no autorizados, ya que, aunque la información cifrada sea visible, solo aquellos con la clave adecuada pueden descifrar y acceder a los valores originales.