Contratos Inteligentes 📜

para Devs

JavaScript code using Hardhat
Otros idiomas =>
English

Hola mundo,

Soy J.D. Nicholls 👋

- Fundador Ingeniero Full-Stack 👷

- Contribuidor Open Source 👨‍💻

- Desarrollador de juegos (Hobby) 🎮
- Apasionado por UX 💫

- Amante del Chocolate 🍫

- Creador de Proyecto26 🧚

Agradecimientos 🙏

Se puede hacer de todo con Blockchain y Smart Contracts?

Qué es Blockchain? 🤔

Es una estructura de datos que permite crear una red segura, fiable y descentralizada que almacena datos, intercambia valores y registra la actividad de las transacciones en un libro de contabilidad público que no está controlado por ninguna autoridad central, sino que es mantenido por todo los participantes.

Las transacciones son realizadas por medio de una red descentralizada de ordenadores y no existe ente gubernamental o intermediario entre los participantes 🎭

Por qué Blockchain? 🤷

Proponemos una solución al problema del doble gasto utilizando una red peer-to-peer.

Blockchain permite la emisión controlada de las monedas digitales, además de funcionar como un libro público que registra cada una de las transacciones realizadas, lo que asegura que cada moneda solo pueda ocuparse una vez. De esa forma, el esquema de seguridad está garantizado, pues cada una de estas transacciones son realizadas por medio de una red descentralizada de ordenadores y no existe ente gubernamental o intermediario entre los participantes.

Descentralización 🌐

Tiers:

- Arquitectura: cantidad de ordenadores, cuántos puede tolerar? cómo se comporta el sistema (Monolítico o distribuido)? Es resistente a fallos (componentes que funcionen de manera independiente)? Es resistente a ataques (no hay un punto central que afecte su funcionamiento)? Es capaz de resistir a la colusión (algún usuario no se puedan beneficiar a costa de otros)?

- Política: Cómo se organizan los usuarios involucrados, cómo se gobierna el sistema? cuántos individuos se compone el sistema?
- Lógica: ¿Son los interfaces y estructuras de datos del sistema un único ente o son un enjambre no identificable? ¿Qué pasaría si pudiéramos cortar el sistema por la mitad, entre proveedores y usuarios? ¿Seguirán operando como unidades independientes?

Beneficios de la Descentralización ⚖️

- Tolerancia a fallos: es menos propenso a fallar, mientras haya un nodo operando el sistema seguirá funcionando. 

- Resistente a ataques: es más costoso a ataques, ser destruido o manipulado al carecer de un punto central.

- Resistente a la colusión: evita que ciertos usuarios se beneficien sobre los demás, ya sea porque tiene más poder de computo, mayor participación, etc

Descentralización

Hash en la Blockchain #️⃣

Es un método de criptografía que convierte cualquier forma de dato en un resultado único. En la Blockchain cada transacción tiene un hash único, y el conjunto de transacciones se considera un Bloque, el cual a su vez es representado por un hash único generado por el conjunto de hashes de todas las transacciones (Merkle Tree).

Merkle Tree

Cada Bloque hace referencia al hash del Bloque anterior, generando una Cadena de Bloques.

Nonce en un Bloque 🧱

El Nonce es un número que solo puede usarse una vez:

 

Un número aleatorio usado una sola vez destinado a la autenticación de transferencia de datos entre dos o más partes.

 

Este número aleatorio garantiza que los hash antiguos no se pueden volver a utilizar en lo que se denominan ataques de repetición. En una red blockchain el nonce funciona en combinación con el hash como un elemento de control para evitar la manipulación de la información de los bloques.

Normalmente el nonce implementa también un timestamp o marca de tiempo para que se impida su repetición.

Blockchain 🔗

Una blockchain es esencialmente una lista enlazada; cada bloque tiene una referencia al anterior. ejemplo: demo

Si alguien cambia la información de un Bloque, el Bloque siguiente sería invalidado automáticamente porque se rompe la cadena...

Cuando hay varios Nodos participando (Peers), ganan aquellos que tengan la mayor Cadena de Bloques.

Enlaces

Cursos

Qué es DeFi? 💱

A diferencia de CeFi 🏦; donde los productos financieros solo funcionan correctamente en escenarios predecibles (condiciones adecuadas) y donde se benefician unos cuantos:

Por qué DeFi? 💱

DeFi está diseñado para solucionar problemas como:

- Ineficiencia: costoso, lento e inseguro 🐌

- Acceso limitado: no es inclusivo 💳

- Opacidad: necesitas confiar en los reguladores y sus registros mixtos para monitorear bancos 🧐

- Control centralizado: sistema financiero oligopólico que impone tarifas más altas que en un mercado competitivo 📈

- Falta de interoperabilidad: dificultad para mover fondos de una institución financiera a otra 💸

CeFi vs DeFi

Por qué no un Arbitro de Confianza? 👮

- Single point of failure: El sistema deja de funcionar si hay un punto de fallo.

- Concentración de poder: "El que controla el pasado controla el futuro". Se presta para censurar transacciones, imponer nuevas condiciones para obtener transacciones incluidas en el historial, etc.

- Don't be Evil: No deberíamos tener que depender de "Promesas" para proteger la información sensible de intermediarios (no hay que confiar en nadie).

DeFi redefine la relación entre los usuarios y el mercado

Qué es una DAO? 🏢

Son organizaciones o grupos sin un cuerpo central, una unidad de personas que toman decisiones por el futuro de la comunidad de manera descentralizada, es un intento de resolver el problema de legitimidad de la gobernanza:

El agente prioriza sus intereses personales por encima de los del colectivo. El reto es la gobernanza.

A medida que surgieron los protocolos DeFi (Uniswap, etc), las DAO se han convertido en una parte integral de las finanzas descentralizadas. Las DAO cuentan la capacidad de ejecutar acciones de forma autónoma por medio de reglas de gobernanza complejas con el uso de "Smart contracts".

Enlaces

Qué es un Smart Contract? 🤝

Un contrato es un acuerdo vinculante entre 2 o más partes.

A diferencia de un acuerdo centralizado con cláusulas en letra pequeña las cuales beneficien a participantes por encima de otros, los Contratos Digitales buscan brindar total transparencia en el cumplimiento de las partes y seguridad al no depender de los posibles riesgos y disponibilidad de un sistema centralizado 🏛️

Smart Contract 📋

Es un contrato auto-ejecutable en el que los términos del acuerdo se definen directamente por medio de código (script) el cual no se puede cambiar (inmutable).

Implementa de forma programada una serie de reglas (condiciones) sin necesidad de interacción humana y/o de terceros.

Acuerdo Digital 🆚 Contrato Inteligente

El contrato inteligente tiene la peculiaridad de que se ejecuta en una infraestructura descentralizada como es la Blockchain, para que la ejecución y cumplimiento del contrato no dependan de una entidad, logrando que nadie tenga influencia sobre el mismo 🕵️

Acuerdos Digitales VS Smart Contracts

Can't Be Evil 😈

Los Smart Contracts solucionan una problemática social;

La confianza ("Don't Trust. Verify").

Cryptographic Truth > "Just Trust Us" (Promises)

Los individuos por tanto no pueden ser malvados al reducir el riesgo de contraparte (probabilidad de que un involucrado en una transacción pueda incumplir con su obligación contractual) y la transparencia que es inevitable por defecto, además de permitir que los rendimientos por intereses sean consistentemente altos (garantizado por la criptografía y la base matemática).

Truth-based Society 🙋 

Web 3

Real World Problem 🧐

Riesgos ⚠️

Operadores Random son un riesgo

Un número random se genera tomando un montón de números diferentes de una computadora como fuente de aleatoriedad, lo cual es difícil de controlar.

Hybrid Smart Contracts ✍️

Este tipo de contratos tiene como finalidad conectar múltiples fuentes de datos externas con redes de Blockchain, de manera justa e imparcial, para que los Smart Contracts puedan interactuar con datos del mundo real, por medio de Oráculos.

 

Los Oráculos crean una oportunidad de construir nuevos tipos de Sistemas garantizados criptográficamente que puedan interactuar con información del mundo real y aprovechar la seguridad que brindan las redes descentralizadas. Ejemplo:

- Conectarse a servicios existentes.

- Crear valor al interoperar con el mercado global.

- Verificar identidad (Autenticación, etc).

2-way data binding ⚛️

Blockchain logra comunicarse de manera bidireccional con sistemas externos.

Consistencia 🛡️

Chainlink provee un Random verificable

Random Verificable ✔️

Se logra solucionar el problema del Blockchain donde no existe una fuente de aleatoriedad; porque todo lo que puede ver un contrato es público.

Enlaces

Qué es Ethereum? 🪙

Es una Blockchain pública, de código abierto, la cual soporta múltiples protocolos como Smart Contracts (ERC-20, ERC-777) y NFTs (ERC-721). Su moneda nativa se llama ETHER (ETH).

 

Características

- Transacciones basadas en estados: Se puede considerar como una máquina de estados, recibe entradas como el hash del bloque anterior (parentHash) y como salidas genera Bloques.

- Mecanismos de consenso: PoW (Potencia infórmatica, competencia computacional) y migrando a PoS (Consenso distribuido mediante validadores).

- Nodos y Clientes: un cliente se encarga de verificar las transacciones en cada bloque, los tipos de nodos son ligero, completo y de almacenamiento.

- Cuentas: tokens controlados por usuarios con un par criptográfico de claves y contratos inteligentes controlados por código.

- Transacciones: acciones (operaciones atómicas) iniciadas por una cuenta mediante una firma criptográfica las cuales modifican el estado de la red al ser minadas, requieren un gas para su ejecución.

- Bloques: conformados por un timestamp, un número de la longitud, la dificultad, un id único (mixHash), el id del bloque anterior, lista de transacciones, el estado del sistema (state root) y un nonce, además de un tamaño limitado.

Ethereum 📒

Límite de Bloques

- Los Bloques se minan aproximadamente cada 15 segundos.

- Cada Bloque tiene un tamaño objetivo de 15 millones de "Gas", con un límite de 30 millones (2 veces el tamaño objetivo). Si el tamaño de un bloque supera el objetivo, el protocolo incrementa el "base fee" del siguiente bloque.

- Un bloque normalmente se compone de 150-200 transacciones, pero este tamaño es variable dependiendo de la demanda de la red. 📈

La Máquina Virtual de Ethereum 🖥️

Es una entidad sustentada por computadoras conectadas ejecutando un cliente de Ethereum con el propósito de mantener el funcionamiento continuo, ininterrumpido e inmutable de esta máquina de estado especial; por tanto la EVM es la que define las reglas de cálculo de un nuevo estado válido de bloque a bloque.

Y(S, T)= S'

La EVM se comporta como una función matemática: dada una entrada, esta produce una salida determinista. Por tanto, es bastante útil para describir formalmente a Ethereum como una función de transición de estado.

EVM

- Turing-complete 256 bits.
- Entorno de ejecución para Smart Contracts de Ethereum.

- Arquitectura basada en un pila (Stack) para cálculos y usa bytecode para codificar instrucciones.

- Determina el resultado de la lógica del contrato ejecutado.

Ether (ETH)

Es la criptomoneda nativa de esta red usada para las tarifas de las transacciones y reconocer la computación realizada por los mineros al ejecutar el código del contrato inteligente y realizar las validaciones (encontrar un nonce válido, etc).

Tokens

Son contratos inteligentes que representan cualquier bien o servicio intercambiable, como una unidad de cuenta:

- ERC-20: mismo tipo-valor, usado con monedas virtuales.

- ERC-721: token no fungible, único, usado como utilidad.

- ERC-677: transferir tokens a contratos con la lógica de activación que describa su comportamiento (Chainlink).

Compilar código 🚧

Al compilar el contrato se genera bytecode (Instrucciones EVM de bajo nivel para una ejecución eficiente) y la definición de la ABI (Interfaz que específica como interactuar con el contrato).

 

Application Binary Interface incluye:

- Métodos públicos

- Parámetros

- Constantes

- Estructuras de datos

- Tipos de evento (logs)

- Entradas/Salidas

[
  {
    "inputs": [],
    "name": "getCount",
    "outputs": [
      {
        "internalType": "uint256",
        "name": "",
        "type": "uint256"
      }
    ],
    "stateMutability": "view",
    "type": "function"
  },
  {
    "inputs": [],
    "name": "increment",
    "outputs": [],
    "stateMutability": "nonpayable",
    "type": "function"
  }
]

Ejecutar el contrato 🎬

El bytecode del contrato se publica a la Blockchain y para interactuar con este se necesita el ABI, para conocer las entradas y salidas con las que se trabaja el contrato.

Pago del Gas 💸

La ejecución de funciones en un contrato puede costar un gas (unidad que mide la cantidad de esfuerzo computacional requerida) para mantener la red de Ethereum segura, e.g:
- Cada instrucción de CPU en la EVM (ejecución del contrato).

- Cada escritura de datos (memoria y almacenamiento).

- Velocidad de ejecución y tamaño del contrato.

Los precios están indicados en Gwei
1 gwei === 0.000000001 ETH (10-9 ETH)

Gas Fees ⛽

El gas es el costo de la ejecución de las transacciones. Los mineros realizan la confirmación de las transacciones y por tanto reciben un pago como recompensa. El gas es la unidad que mide el trabajo computacional requerido para correr transacciones o smart contracts en la EVM:

- La lectura de datos de la Blockchain es gratuita 🆓

- El gas se mide/paga en cada ejecución del contrato.

- Cuando más bajo sea el límite, más demorada es la transacción.

- El límite evita ejecuciones largas (revierte la ejecución de la transacción sí se alcanza) y establece un monto máximo.

- Existen calculadoras de gas como ETH Gas Station.

Gas units (limit) * (Base fee + Tip) (in gwei) = Gas fee

Enlaces

- Learn by coding

- Ethereum Wiki

- Ethereum Mainnet Statistics - distribución de la red.

- Cuentas de la red - contratos/usuarios que participan en la red.

- Transacciones en la red - visualizador del estado de la red.

- Transacciones pendientes (Mempool) - aún no han sido validadas.

- Estado de Ethereum - estructura de datos que mantiene todas las cuentas enlazadas mediante hashes.

- Turing completo - usado para un state-machine distribuido.
- What is Ethereum Gas? - Ethereum Gas Explained.

- Introducción al Stack de Ethereum

Qué es NFT? 🖼️

display: blockchain

Por qué NFTs? 🎨

Derechos de autor y Regalías. Los NFTs crean una solución infalible para garantizar a través de criptografía la autenticidad de una obra; dibujos, fotos, vídeos, audios, modelos 3d, código, etc.

Al mismo tiempo permiten que los autores puedan definir porcentajes de regalías, número de copias para crear ediciones limitadas, contenido exclusivo, etc desde la publicación de la obra (mintear).
Las ganancias de las regalías no dependen de confiar en un tercero para obtener el porcentaje definido por cada nueva venta de la obra, funciona de manera automática y transparente por medio del contrato.

Mintear NFTs 🧑‍🎨

Recomendaciones iniciales:

  • Inicia creando pequeñas series, NFTs con copias de 3 unidades, para que puedas ofrecerlos de una forma más accesible al público en general e ir creciendo gradualmente.
  • Ten cuidado de no mientear la misma obra en diferentes Blockchains.
  • Crea un perfil (twitter, instagram, biolink).
  • El proceso de venta consta de dos pasos; mintear y listar la obra, tú eliges cuantas copias poner a la venta y su precio.
  • Anuncia cada drop que hagas incluyendo; nombre de la obra, precio más bajo (floor price), red donde lo minteaste y la imagen/enlace, las rarezas de las obras son muy valiosas.

NFT & Oracles 🔮

Derechos de autor 🗽

  • Artículo 4 Decisión Andina 351 de 1993: Protección sobre obras artísticas; pueden ser reproducidas y divulgarse por cualquier forma o medio conocido o por conocer.
  • Arte digital: Cuentan con la misma protección que obras producidas en un soporte físico/analógico, por tanto el autor podrá ejercer los actos de explotación de su creación en los términos que establece la ley.
  • Registro de NFTs: Es una pieza única que no se puede intercambiar como una criptomoneda (activos fungibles).
    El NFT representa técnicamente cualquier tipo de activo, tanto digital como físico, y no se debe confundir con el activo en sí mismo (siendo un contrato que estipula quien es el owner de la obra, una certificación). Pero el soporte digital no se aplica a esta porque no es la obra en sí misma (Se necesita transferencia de derechos patrimoniales).

Enlaces

- NFT Nerds - Grupo enfocado en temas técnicos relacionados al mundo Blockchain y arte NFT.

- Cryptocositas - Grupo de Platzi sobre el cripto arte.

- ¿Arte del futuro? ¿Burbuja? ¿Oportunidad? Todos los secretos del Criptoarte.
- El CRIPTOARTE y los NFTs EXPLICADOS.

Ideas 💡

  • Decentralized exchange; DEXT, etc.
  • Juegos competitivos; racing.
  • Traductor de idiomas.
  • Crowdfunding; soportar a creadores y artistas (membresías, etc).
  • Cadenas de suministro, logística (cadenas de valor).
  • NFTs para cupones de descuento.
  • Desperdicio de alimentos.
  • Encuestas/votaciones públicas.
  • Donaciones, ayudas sociales (Iglesias, Unicef, etc).
  • Rastrear fabricación/distribución de medicamentos.
  • Despachadores/transportes de carga.
  • Mercados en línea.
  • Juegos de cartas coleccionables.
  • Verificación de identidad.
  • Eventos deportivos.
  • Regalías para artistas/músicos.
  • Inversión inmobiliaria.
  • Entradas para eventos.

Qué es Solidity? 👨‍💻

Es un lenguaje de Programación de alto nivel, orientado a objetos, diseñado para la creación de contratos en la EVM; siendo estos una colección de código con funciones y datos con estado que reside en una dirección de la Blockchain.

// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.4.16 <0.9.0;

contract Storage {
    uint storedData;

    function set(uint x) public {
        storedData = x;
    }

    function get() public view returns (uint) {
        return storedData;
    }
}

- Store (calculations, caching, persistent)

- Memory (message call, instance)

- Stack (computations)

Optimizado para el almacenamiento de datos y seguridad.

Visibilidad de las Variables 🔎

// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.7.0 <0.9.0;

contract Marketplace {
    // only other contracts and accounts can call
    string external data1 = "external data";
    
    // any contract and account can call
    string public data2   = "public data";
    
    // only inside the contract that defines the varibale
    string private data3  = "private data";
    
    // only inside contract that inherits an internal variable
    string internal data4 = "internal data";
}

Los modificadores de visibilidad se encargan de restringir el acceso a las variables.

Visibilidad de las Funciones 🔎

- Pública:

  Puede ser llamada desde cualquier parte. En las variables se define un "Getter" por defecto.

- Externa:

  No puede ser llamado internamente, esta diseñado para ser llamado por otros contratos.
- Interna:

   Solo pueden ser usadas internamente.

- Privada:
   Accesible solo en el contrato.

Párametros y Tipos de datos 🔎

// Función con parámetro uint de 256 bytes y sin valor de retorno
function setNumber(uint256 _number) public {
  number = _number;
}

// Función sin parámetros que retorna un uint
function getNumber() public view returns (uint256) {
  return number;
}
  • Integers & unsigned integers (Sin punto flotante/decimales)

  • Booleans

  • Strings (UTF8 encoded)

  • Address (encoded with checksum)

  • Bytes/8/32 (string data as bytes)

  • Enums

Arrays 🔎

// fixed size
uint[3] memory numbers = [1, 2, 3];
numbers[0] = 100;

Compile-time fixed size

// dynamic size
uint[] numbers = [];

function addNum(uint _num) public returns (uint) {
  numbers.push(_num);
  return numbers.length;
}

Dynamic size

Los arreglos pueden ser fijos o dinámicos, y pueden almacenar tipos de datos arbitrarios.
// SPDX-License-Identifier: MIT
pragma solidity >=0.7.0 <0.9.0;

contract Marketplace {
  // Persist key-value data
  mapping (uint => string) internal products;

  function addProduct(uint _key, string memory _product) public {
    products[_key] = _product;
  }

  function getProduct(uint _key) public view returns (string memory) {
    return products[_key];
  }
}

Mappings (key-value) 🔎

Similar a un Diccionario en algunos lenguajes, o el objeto Map en JavaScript, permite almacenar llave-valor.

Objetos (struct) 🔎

// SPDX-License-Identifier: MIT
pragma solidity >=0.7.0 <0.9.0;

contract Marketplace {

  struct Product {
    address payable owner;
    string name;
    string image;
    string description;
    uint price;
    uint sold;
  }
  
  mapping (uint => Product) internal products;
}
  function addProduct(
    uint _key,
    string memory _name,
    string memory _description,
    uint _price
  ) public {
    uint _sold = 0;
    products[_key] = Product(
      parable(msg.sender),
      _name,
      _description,
      _price,
      _sold
    )
  }
  function getProduct(uint _key) public view returns (Product memory) {
    return products[_key];
  }
Son una colección de tipos primitivos, estas se pueden almacenar en mappings y arrays.

Crear tokens 🔎

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

contract Token {
  string public name = "Open Source Token";
  string public symbol = "OST";
  uint public totalSupply = 26000000;
  mapping(address => uint) balances;

  constructor() {
    balances[msg.sender] = totalSupply;
  }

  function transfer(address to, uint amount) external {
    require(balances[msg.sender] >= amount, "Not enough tokens");
    balances[msg.sender] -= amount;
    balances[to] += amount;
  }

  function balanceOf(address account) external view returns (uint) {
    return balances[account];
  }
}

No cumple con la especificación ERC-20
(propósitos de demostración)

Crear token ERC20 🔎

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

import "@openzeppelin/contracts/token/ERC20/ERC20.sol";

contract OSToken is ERC20 {
  constructor(string memory name, string memory symbol) ERC20(name, symbol) {
    _mint(msg.sender, 26000000 * (10 ** 18));
  }
}
// Deploy a new token
const tokenFactory = await hre.ethers.getContractFactory("OSToken");
const osToken = await tokenFactory.deploy("Open Source Token", "OST");

Ejemplo de un script para publicar el nuevo token a una red Blockchain:

// SPDX-License-Identifier: MIT
pragma solidity >=0.7.0 <0.9.0;

contract Marketplace {
  string internal customTokenAddress = "0x...";
  
  function buyProduct(uint _key) public payable {
    require(
      IERC20Token(customTokenAddress).transferFrom(
        msg.sender,
        products[_key].owner,
        products[_key].price
      ),
      "Transfer failed."
    );
    products[_key].sold++;
  }
}

Transferir tokens 🔎

"payable" es una palabra reservada que nos indica que vamos a transferir tokens.

Mintear NFTs 🔎

// SPDX-License-Identifier: MIT
pragma solidity >=0.6.0;

import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
import "@openzeppelin/contracts/utils/Counters.sol";

contract MyNFTToken is ERC721 {
  using Counters for Counters.Counter;
  Counter.Counter private _tokenIds;

  constructor() ERC721("MyAwesomeToken", "TokenName") {}

  function mintNFT(address receiver, string memory tokenURI) public returns (uint256) {
    _tokenIds.increment();
    uint256 tokenId = _tokenIds.current();

    _mint(receiver, tokenId);
    _setTokenURI(tokenId, tokenURI);

    return tokenId;
  }
}

"tokenURI" representa un recurso JSON con una estructura { name, description, image }.

Enlaces

DEMO

Otros recursos 🎁

Storage

SDKs

Platforms

Hardware 👛

Ledger

Bootcamps ⛺

Alchemy University

Contratos Inteligentes

By J.D Nicholls

Contratos Inteligentes

Una presentación sobre Contratos Inteligentes y Blockchain

  • 2,005