Interfaz binaria de aplicación (ABI) en la máquina virtual Ethereum

Los contratos inteligentes son fragmentos de código que se almacenan en la string de bloques y son ejecutados por la máquina virtual Ethereum (EVM). El EVM también proporciona un conjunto completo de instrucciones llamado códigos de operación que ejecutan ciertas instrucciones. Los códigos de operación son códigos de bajo nivel similares al conjunto de instrucciones del procesador. Se puede acceder a los códigos de operación comunes de Ethereum desde. Todo el programa se compila y almacena en forma de bytes o representación binaria en la string de bloques de Ethereum como una forma de dirección. Para Ethereum y EVM, un contrato es solo un programa único que se ejecuta en esta secuencia de bytes. Solo el lenguaje de nivel superior como Solidity, Viper o Bamboo define cómo se llega desde el punto de entrada del programa al punto de entrada de una función en particular. Cuando una aplicación externa u otro contrato inteligente quiere interactuar con la string de bloques, necesita tener algún conocimiento de la interfaz de un contrato inteligente, como una forma de identificar un método y sus parámetros. Esto es facilitado por la interfaz binaria de aplicaciones (ABI) de Ethereum.  

Es similar a la interfaz de programación de aplicaciones (API), que es esencialmente una representación de la interfaz del código en forma legible por humanos o en un lenguaje de alto nivel. En el EVM, el código compilado se almacena como datos binarios y las interfaces legibles por humanos desaparecen y las interacciones de contratos inteligentes deben traducirse a un formato binario que pueda ser interpretado por el EVM. ABI define los métodos y estructuras que simplemente puede usar para interactuar con ese contrato binario (tal como lo hace la API), solo que en un nivel inferior. La ABI indica a la persona que llama la información necesaria (firmas de funciones y declaraciones de variables) para codificar de manera que la máquina virtual la entienda al código de bytes (contrato). Este proceso se denomina codificación ABI .

ABI es la interfaz entre dos módulos de programa, uno de los cuales se encuentra principalmente en el nivel de código de máquina. La interfaz es el método predeterminado para codificar/descodificar datos dentro o fuera del código de máquina. En Ethereum, es básicamente cómo codifica un idioma para tener llamadas de contrato al EVM o cómo leer los datos de las transacciones. La codificación ABI en la mayoría de los casos está automatizada por herramientas que forman parte del compilador como REMIX o carteras que pueden interactuar con la string de bloques. El codificador ABI requiere una descripción de la interfaz del contrato, como el nombre de la función y los parámetros, que normalmente se proporciona como JSON.

Ejemplo de codificación ABI

Un contrato inteligente de Ethereum es un código de bytes implementado en la string de bloques de Ethereum. Puede haber varias funciones en un contrato. Se necesita una ABI para que pueda señalar la llamada de función específica que desea evocar y también obtener una garantía de que la función devolverá datos en el formato que espera. 
Los primeros cuatro bytes de la carga útil de una transacción enviada a un contrato generalmente se usan para distinguir qué función en el contrato llamar.

1) Contrato GeeksForGeeks tiene ciertas funciones. Llamemos a la función baz(…) .

 contract GeeksForGeeks {
  function empty() {}
  function baz(uint32 x, bool y) returns (bool r) 
 { if(x>0) 
     r = true;
   else
       r =false;
 }
  function Ritu(bytes _name, bool _x) {}
}

Llamada a la función baz con los parámetros 69 y true, pasaríamos 68 bytes en total. 

Method ID. 
This is derived as the first 4 bytes of the Keccak-256 hash of the ASCII form of the signature baz(uint32,bool)
0xcdcd77c0 

First parameter
uint32 value 69 padded to 32 bytes 
0x0000000000000000000000000000000000000000000000000000000000000045:

Second parameter 
boolean true, padded to 32 bytes
0x0000000000000000000000000000000000000000000000000000000000000001: 

2) balanceOf es una función utilizada para obtener el saldo. La firma de la función es la siguiente:

balanceOf(address)

Calcular el hash keccak256 de esta string de firma produce:

0x70a08231b98ef4ca268c9cc3f6b4590e4bfec28280db06bb5d45e689f2a360be

Tomar los cuatro bytes superiores nos da el siguiente selector de función o ID de método como también se obtuvo anteriormente:

0x70a08231

La codificación ABI no forma parte del protocolo central de Ethereum porque no se requiere que los datos de carga útil en las transacciones tengan ninguna estructura, es solo una secuencia de bytes. De manera similar, la máquina virtual de Ethereum también procesa los datos como una secuencia de bytes. Por ejemplo, una transacción contiene la secuencia de bytes. La forma en que estos bytes se interpretan en datos estructurados depende del programa y depende del lenguaje de programación utilizado. Para hacer posible que dos programas escritos en diferentes lenguajes de programación se llamen entre sí, los compiladores de dichos lenguajes deben implementar la serialización y deserialización de datos de la misma manera, es decir, aunque deben implementar la ABI, no están obligados a hacerlo.

Ejemplo: en el siguiente ejemplo, se crea un contrato para almacenar un número y se devuelve el número almacenado. Debajo del ejemplo, hay dos salidas: una es la salida ABI y la segunda es la salida de la ejecución del código, es decir, la salida simple de implementación y ejecución del código Solidity.

Solidity

// Solidity program to
// demonstrate abi encoding
pragma solidity >=0.4.22 <0.7.0;
  
// Creating a contract
contract Storage 
{
    // Declaring a state variable
    uint256 number; 
  
    // Defining a function
    // to store the number  
    function store(uint256 num) public 
    {
        number = num;
    }
  
    // Defining a function to 
    // send back or return the 
    // stored number
    function retrieve() public 
             view returns (uint256)
    {
        return number;
    }
}

Salida ABI: 

[
    {
        "inputs": [],
        "name": "retrieve",
        "outputs": [
            {
                "internalType": "uint256",
                "name": "",
                "type": "uint256"
            }
        ],
        "stateMutability": "view",
        "type": "function"
    },
    {
        "inputs": [
            {
                "internalType": "uint256",
                "name": "num",
                "type": "uint256"
            }
        ],
        "name": "store",
        "outputs": [],
        "stateMutability": "nonpayable",
        "type": "function"
    }
]

Producción:

abi output

Publicación traducida automáticamente

Artículo escrito por ciberexplosion y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *