ETH Kipu
  • Ethereum Developer Pack
  • Módulo 1
    • Intro a Smart Contracts
      • Fundamentos de Blockchain
        • Antecedentes
        • Bitcoin
        • Qué es Blockchain
        • Conceptos Clave en Blockchain
        • Cómo funciona la Blockchain
        • Tipos de Blockchain
        • Modelos de Consenso
      • El nuevo Internet
        • Web 3
        • Elementos Fundamentales
        • Impacto de Ethereum en Diversos Sectores
      • Wallets
        • Componentes de una wallet
        • Tipos de Wallet
        • Códigos mnemónicos
      • Ethereum 101
        • Smart Contracts
        • Cuentas
          • Tipos de cuentas
          • Contenido de cuentas
        • Transacciones
          • Componentes
          • Ciclo de vida
        • Gas
        • Solidity
        • EVM
          • La máquina de estados
          • Opcodes
          • Cómo funciona la EVM
          • Clientes de ejecución
          • DApps
      • Blockchain Explorer
        • Funciones de un blockchain explorer
        • Beneficios de utilizar un blockchain explorer
      • Remix
        • Características de Remix
        • Workspaces o espacios de trabajo
        • Cargar y compilar un contrato
        • Desplegar en la máquina virtual de Remix (Remix VM)
        • Interactuando con funciones
        • Desplegar en una red pública
      • Crea tu primer Smart Contract
  • Módulo 2
    • Fundamentos de Solidity
      • Hello World
      • Tipos de Datos
      • Funciones
      • Variables
        • Ejercicio 1
      • Operadores
        • Ejercicio 2
      • Constructor
        • Ejercicio 3
      • Convenciones de nomenclatura
      • Tipos de almacenamiento para variables
      • Estructuras de Control
        • Ejercicio 4
      • Modificadores
      • Eventos
        • Ejercicio 5
      • Tipos de Referencia
        • Arrays
          • Ejercicio 6
        • Mappings
          • Ejercicio 7
        • Structs
          • Ejercicio 8
      • Address Payable
      • Cómo reciben Ether los contratos y funciones
      • Transferencias de Ether
      • Conceptos Avanzados
        • Codificación ABI
        • Hashing
        • This
        • Herencia
        • Abstract
        • Interface
        • Llamadas entre contratos
        • EVM
        • ABI
        • Bytecode
        • Opcodes
  • Módulo 3
    • Estándares, Librerías y Patrones
      • Buenas Prácticas de Diseño
      • Patrones de Diseño
      • EIP y ERC
      • ERC-20
      • ERC-721
      • Open Zeppelin
      • Crea un Token ERC-20
      • Almacenamiento Descentralizado: IPFS
      • Crea un Token ERC-721
      • DeFi
  • Módulo 4
    • Toolkit para desarrollo en Ethereum
      • Requisitos para el módulo 4
        • Terminal
        • Git y Github
        • Node.js y npm
        • Visual Studio Code para Solidity
      • Toolkit
        • JSON-RPC
        • Ethers.js
          • Ejercicio
        • Hardhat
          • Despliegue de un contrato en Hardhat
          • Despliegue de un contrato en una red pública
        • Scaffold-ETH
          • Características
          • Cómo instalar Scaffold-ETH
  • Módulo 5
    • Seguridad, Pruebas y Auditoría
      • Pruebas
        • Importancia de realizar pruebas
        • Métodos para probar contratos inteligentes
          • Pruebas automatizadas
          • Pruebas manuales
        • Conceptos importantes en testing
        • Herramientas para testing
        • Testing con Hardhat
        • Recursos adicionales
      • Seguridad
        • Una mentalidad distinta de diseño
        • Principales vulnerabilidades en smart contracts
          • Reentrancy attack (ataque de reentrada)
          • Replay attack (ataque de repetición)
          • Price Oracle Manipulation (Manipulación de Oráculos de Precios)
          • Missing Access Control (Pérdida de Control de Acceso)
          • Reward Manipulation (Manipulación de Recompensas)
          • Failure to Initialize (Falla al Inicializar)
          • Front-running
          • Invariant Breaks (Ruptura de invariantes)
          • Mishandling of ETH (Mal manejo de ETH)
          • Denial of Service (DoS - Denegación de Servicio)
          • Integer overflow and underflow (desbordamiento y subdesbordamiento de enteros)
          • Phishing y Typosquatting
        • Recursos adicionales
      • Auditoría de smart contracts
        • Proceso de Auditoría
        • Herramientas
        • Cómo prepararse para una auditoría
        • El test Rekt
        • Retos
        • Recursos adicionales
  • Contribuye
    • Kipu Explorer
Powered by GitBook
On this page

Was this helpful?

  1. Módulo 2
  2. Fundamentos de Solidity
  3. Conceptos Avanzados

Codificación ABI

Codificación ABI

Application Binary Interface (ABI) es un componente que actúa como la capa de interacción entre dos programas binarios, en este caso, entre contratos inteligentes y el mundo exterior (como aplicaciones frontend, otras herramientas de blockchain o incluso otros contratos inteligentes). El ABI especifica cómo codificar y decodificar datos para que puedan ser leídos por la Máquina Virtual de Ethereum (EVM). Esencialmente, el ABI es un conjunto de reglas que dictan cómo convertir las llamadas de funciones y sus parámetros en una forma que el contrato inteligente puede entender, y viceversa, cómo los datos de salida deben ser convertidos de vuelta para el mundo exterior.

Solidity proporciona funciones integradas para codificar y decodificar datos según estas reglas, conocidas colectivamente como funciones abi.

Funciones abi

  1. abi.encode(...) returns (bytes memory)

    Codifica los argumentos dados en una secuencia de bytes según las reglas ABI. Es útil para preparar datos para, por ejemplo, una llamada de función de bajo nivel.

    Ejemplo

    bytes memory encodedData = abi.encode(arg1, arg2);

    En el ejemplo arg1, arg2: Son los argumentos que se pasan a la función abi.encode. Estos argumentos pueden ser de cualquier tipo soportado por Solidity, como uint, address, string, etc. La función abi.encode toma estos argumentos, los codifica en un formato binario único y devuelve este dato codificado como un arreglo de bytes.

  2. abi.encodePacked(...) returns (bytes memory)

Similar a abi.encode, pero codifica los argumentos de una manera más compacta, sin rellenar, lo que puede ser útil para ciertas operaciones criptográficas. Sin embargo, la falta de relleno puede llevar a ambigüedades en ciertas situaciones, así que debe usarse con precaución.

Ejemplo:

bytes memory packedData = abi.encodePacked(arg1, arg2);
  1. abi.encodeWithSelector(bytes4 selector, ...) returns (bytes memory)

Uso: Codifica los argumentos dados con un selector de función específico. Útil para llamadas a funciones en contratos externos cuando se conoce el selector de la función.

Ejemplo:

bytes memory dataWithSelector = abi.encodeWithSelector(selector, arg1, arg2);

El selector de función es esencialmente la firma de la función codificada en 4 bytes. Esta funcionalidad es particularmente útil cuando se realizan llamadas de bajo nivel o se interactúa con contratos cuyas interfaces pueden no estar completamente definidas en tiempo de compilación.

Incluyamos un ejemplo de cómo usar abi.encodeWithSelector en Solidity para preparar datos para una llamada de contrato de bajo nivel:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

contract Receiver {
    event Received(uint256 indexed value, address sender);

    // Una función simple que emite un evento con el valor y el remitente
    function receiveValue(uint256 value) public {
        emit Received(value, msg.sender);
    }
}

contract Caller {
    // Función que llama a `receiveValue` en el contrato Receiver usando abi.encodeWithSelector
    function callReceiveValue(address _receiver, uint256 _value) public {
        // Primero, calculamos el selector de la función.
        // La firma de la función es "receiveValue(uint256)"
        bytes4 selector = bytes4(keccak256("receiveValue(uint256)"));

        // Luego, codificamos el selector junto con los argumentos de la función.
        bytes memory data = abi.encodeWithSelector(selector, _value);

        // Realizamos la llamada de bajo nivel.
        (bool success, ) = _receiver.call(data);
        require(success, "La llamada fallo.");
    }
}

En este ejemplo:

  • Receiver: Es un contrato que tiene una función receiveValue, la cual emite un evento cuando se llama. Esta función podría ser cualquier lógica que quieras invocar en otro contrato.

  • Caller: Es un contrato que realiza una llamada al contrato Receiver. Utiliza abi.encodeWithSelector para preparar los datos de la llamada. Esto incluye el selector de la función, que identifica qué función llamar en el contrato Receiver, y los argumentos para esa función.

    • bytes4 selector = bytes4(keccak256("receiveValue(uint256)")); calcula el selector de la función basado en su firma. La firma es simplemente el nombre de la función seguido de los tipos de sus parámetros entre paréntesis, codificado en 4 bytes.

    • abi.encodeWithSelector(selector, _value) codifica estos datos en un formato que el contrato Receiver puede decodificar y ejecutar.

  1. abi.encodeWithSignature(string memory signature, ...) returns (bytes memory)

Similar a abi.encodeWithSelector, pero en lugar de proporcionar el selector de función como un valor bytes4, se proporciona la firma de la función como una cadena. Solidity calcula el selector de función correspondiente.

Ejemplo:

bytes memory dataWithSignature = abi.encodeWithSignature("functionName(uint256,address)", arg1, arg2);

En este ejemplo, functionName(uint256,address) es la signature o firma.

  1. abi.decode(bytes memory data, (type1, type2, ...)) returns (type1, type2, ...)

Decodifica los datos codificados según las reglas ABI en los tipos especificados. Es útil para interpretar los datos de salida de las llamadas a funciones de bajo nivel o las respuestas de las llamadas a otros contratos.

Ejemplo:

(type1 var1, type2 var2) = abi.decode(encodedData, (type1, type2));
PreviousConceptos AvanzadosNextHashing

Last updated 8 months ago

Was this helpful?