---
title: "¿Qué son los binarios de Solidity?"
description: "Qué son los binarios de Solidity y cómo usarlos para optimizar el código de tu contrato inteligente"
---

# ¿Qué son los binarios de Solidity?

Los datos sin procesar publicados a través de un smart contract en la blockchain de Ethereum son bytecode, es decir, cadenas largas de caracteres hexadecimales. Aunque los desarrolladores escriben y leen smart contracts en código [Solidity](https://www.alchemy.com/overviews/solidity) legible para humanos, ese no es el texto que se publica en la blockchain.

De manera similar, cada "llamada" a un smart contract, o solicitud realizada a una de las funciones visibles externamente que publica un smart contract, tiene la forma de bytecode sin procesar, o "binarios".

Tomemos un smart contract subido a [Ethereum mainnet](https://www.alchemy.com/rpc/ethereum) con la siguiente estructura (codificada en Solidity):

Supongamos que un usuario quiere hacer una llamada a la función baz con los parámetros 69 y true.

Así es como se ve realmente la solicitud transmitida en bytecode:

`0xcdcd77c000000000000000000000000000000000000000000000000000000000000000450`...

Bastante difícil de leer, ¿no?

En este artículo veremos por qué la [Ethereum Virtual Machine](https://www.alchemy.com/overviews/what-is-the-ethereum-virtual-machine-evm) codifica todo en bytecode, aprenderemos qué es un ABI y cómo usarlo, y conoceremos algunas herramientas básicas para descompilar bytecode y convertirlo de nuevo en [Solidity](https://www.alchemy.com/dapps/solidity) legible.

**Nota:** los ejemplos de este artículo están tomados de la [documentación oficial de Solidity ABI](https://docs.soliditylang.org/en/v0.8.13/abi-spec.html).

## **¿Por qué Solidity codifica los smart contracts en binario?**

Debido a que almacenar datos en la blockchain de Ethereum es extremadamente costoso, y cada byte de datos subido debe replicarse en todos los full nodes de la blockchain, es más eficiente en términos de costo escribir y leer bytecode sin procesar que subir código Solidity.

Analizar y almacenar código legible para humanos puede costar un orden de magnitud más de datos, lo cual es un problema cuando los smart contracts ya pueden costar miles de USD cada uno en mainnet.

## **¿Qué es un ABI de Solidity y por qué se necesita uno para leer un smart contract?**

Cuando se publican los smart contracts, se transpilan automáticamente a bytecode antes de publicarse en Ethereum. Sin embargo, una vez publicados en la red, ¿cómo sabrá una persona cómo interactuar con el smart contract? Es casi imposible mirar una cadena larga de bytecode y entender qué funciones están disponibles para llamar.

Una [Application Binary Interface, o ABI](https://www.alchemy.com/overviews/what-is-an-abi-of-a-smart-contract-examples-and-usage) es la respuesta.

Un ABI es una lista pública y legible para humanos de métodos que describe las llamadas que se pueden hacer a un smart contract en particular y qué devolverá cada llamada.

Con un ABI, los usuarios de smart contracts no necesitan leer bytecode y pueden traducir sus llamadas a bytecode para interactuar con smart contracts.

Los ABI son extremadamente similares a las API (Application Programming Interfaces) en la arquitectura tradicional de Web2. Sin embargo, la principal diferencia es que **un ABI de Solidity permite al usuario acceder a métodos en smart contracts codificados en binario**, mientras que las API permiten a los usuarios acceder a métodos desde endpoints de servidores en línea.

Debido a que están pensados para ser usados y leídos por humanos, los desarrolladores de smart contracts no publican el ABI de un smart contract en la blockchain, porque eso sería extremadamente costoso.

En cambio, puedes obtener el ABI de estas formas:

1. Del código fuente disponible públicamente para el contrato, proporcionado por el desarrollador del smart contract, que se puede usar para generar un ABI.
1. Si el smart contract está verificado en Etherscan, a partir de la información del contrato en Etherscan.
1. Haciendo ingeniería inversa del ABI a partir del bytecode del smart contract (no recomendado).

Un ABI típicamente se publica como una codificación en formato JSON de las declaraciones de funciones públicas de un smart contract de Solidity.

Tomemos la siguiente definición de función de un smart contract:

La codificación JSON correspondiente se vería así:

## **Cómo interpretar binarios de call data de Solidity**

Si bien no querrás analizar binarios de Solidity a mano para invocar funciones, porque es complicado, poco intuitivo y es probable que cometas varios errores, es muy útil entender a grandes rasgos cómo se forman los binarios en Solidity, para poder revisar rápidamente el call data o verificar valores.

En la siguiente sección te enlazaremos a un par de herramientas que deberían encargarse de la mayor parte de esta transcripción por ti.

Tomemos el ejemplo anterior.

Supongamos que un usuario quiere hacer una llamada a la función **baz** en un smart contract con los parámetros 69 y true. Así es como se ve la solicitud en bytecode, que tiene 68 bytes en total:

`0xcdcd77c0000000000000000000000000000000000000000000000000000000000000004500`...

### 1. Usa los primeros 4 bytes del call data para identificar el method ID.

En este caso, 0xcdcd77c identifica el método **baz**, obtenido derivando los primeros 4 bytes del hash Keccak de la forma ASCII de la firma baz(uint32,bool).

### 2. Usa los siguientes 32 bytes para identificar el primer parámetro

`0x00000000000000000000000000000000000000000000000000000000000000045` identifica el primer parámetro **69**, que es un valor uint32 rellenado (padded) a 32 bytes. El padding simplemente significa que se agregan 0s para garantizar que toda la cadena tenga 32 bytes de longitud (en este caso), sin importar cuán grande sea el número real.

`0x00000000000000000000000000000000000000000000000000000000000000045 `

### 3. Usa **los últimos 32 bytes para identificar el segundo parámetro**

El segundo parámetro es **true**, que es un valor bool rellenado a 32 bytes:

`0x0000000000000000000000000000000000000000000000000000000000000001`

La codificación se ve ligeramente distinta para parámetros que incluyen tipos dinámicos, porque a diferencia de los tipos estáticos como address, bool o uint32, que se codifican in situ (in-place), [los tipos dinámicos se codifican en una ubicación asignada por separado](https://docs.soliditylang.org/en/v0.8.13/abi-spec.html#use-of-dynamic-types).

## **¿Cómo puedo interpretar binarios de datos de eventos de Solidity?**

Un evento es un registro (log) publicado por un smart contract al ejecutar una llamada a un método, y los eventos se publican como datos binarios.

Los eventos pueden recibir parámetros, que ayudan a especificar qué generará el evento como salida. Estos parámetros pueden indexarse, lo que significa que el evento se podrá buscar usando ese parámetro indexado como filtro. ¡Estos parámetros indexados también se conocen como topics en términos de Solidity!

A grandes rasgos, un evento de Solidity sigue esta estructura:

- address: la dirección de un contrato
- topics[n]: de 0 a 4 topics, o parámetros indexados
- datos binarios de longitud arbitraria, que se pueden analizar según el ABI.

## **¿Qué herramientas debería usar para descompilar binarios de Solidity?**

Existe una variedad de descompiladores de EVM disponibles que pueden ayudarte a obtener una versión más legible de los binarios de Solidity, incluidos [EtherVM Decompiler](https://ethervm.io/decompile) y [Panoramix decompiler](https://github.com/palkeo/panoramix).

Estos descompiladores de EVM no devolverán una recreación perfecta del código fuente original (los nombres u otra información importante pueden eliminarse para minimizar el tamaño de los binarios), pero deberían darte una comprensión de alto nivel de las solicitudes de ABI permitidas.
