Presentación del proyecto

1

Desarrollo de Aplicaciones Descentralizadas en Blockchain

2

Desarrollo de NFTs con Solidity y Contratos Inteligentes

Arquitectura de DApps

3

Características de Aplicaciones Descentralizadas (dApps)

4

Componentes Descentralizables en Aplicaciones Descentralizadas

5

Evaluación de Descentralización en Aplicaciones Blockchain

6

Autenticación en Aplicaciones Descentralizadas y Firma Digital

Setup del proyecto

7

Setup de Proyectos Blockchain con Node.js y Yarn

8

Instalación y configuración de Hard Hat para contratos inteligentes

9

Compilación y despliegue de contratos inteligentes con Hard Hat

10

Actualización de Testnets en Ethereum: Goerli y Sepolia

11

Despliegue de Contratos Inteligentes en Redes de Prueba con Hard Hat

12

Manejo seguro de llaves privadas en proyectos blockchain con .env

13

Alternativas a Hard Hat para Desplegar Contratos Inteligentes

Desarrollo del contrato inteligente

14

Implementación de OpenZeppelin en Smart Contracts Ethereum

15

Extensión de Funcionalidad en Contratos ERC721 con OpenZeppelin

16

Funciones de Metadata en NFTs y OpenSepaline

17

Cálculo y Diseño del ADN en PlatziPong NFTs

18

Implementación de contratos inteligentes en Solidity para NFTs

19

Generación de ADN Pseudoaleatorio en Contratos Solidity

20

Asignación de ADN y URL de imagen en NFTs con Solidity

Probando nuestro Smart Contract

21

Pruebas de Smart Contracts en Hardhat con Chai y Ethers.js

22

Despliegue y Verificación de Smart Contracts en Etherscan

23

Prueba de Contratos Inteligentes en OpenSea Testnet

Conclusión

24

Desarrollo de Aplicaciones Descentralizadas con Solidity y Node.js

No tienes acceso a esta clase

¡Continúa aprendiendo! Únete y comienza a potenciar tu carrera

Implementación de OpenZeppelin en Smart Contracts Ethereum

14/24
Recursos

¿Qué es OpenZeppelin y por qué es importante en Ethereum?

OpenZeppelin es una colección valiosa de contratos inteligentes dentro del ecosistema de Ethereum. Proporciona una librería de contratos auditados y de código abierto que permite a los desarrolladores de blockchain crear aplicaciones seguras y eficientes. La seguridad es crucial porque los smart contracts suelen manejar grandes cantidades de dinero digital que no se pueden actualizar una vez implementados en la red principal.

La librería OpenZeppelin se ha convertido en un estándar abierto, ayudando a los desarrolladores a no partir de cero y contando con contratos ya auditados como base. Además, OpenZeppelin está acompañado de herramientas para auditar y monitorear la seguridad de los smart contracts.

¿Cómo facilita OpenZeppelin la creación de contratos inteligentes?

OpenZeppelin ofrece contratos pre-implementados para distintos estándares, como ERC20 para tokens fungibles y ERC721 para tokens no fungibles (NFTs). Estos contratos sirven como bloques iniciales a los que se les puede agregar funcionalidad personalizada.

Algunos ejemplos de funcionalidades adicionales son:

  • Control de acceso: como el tipo 'ownable', que permite definir cuentas privilegiadas para ciertas funciones.
  • Firma digital: mediante la implementación de librerías de curvas elípticas.

La librería también ofrece interfaces que definen los métodos principales de un contrato, lo que permite personalizar la lógica del contrato encontrando un balance entre aprovechar las técnicas seguras ya establecidas y añadir personalizaciones.

¿Cómo instalar y configurar OpenZeppelin?

Para usar OpenZeppelin, primero se necesita instalar el paquete de desarrollo. Esto puede hacerse mediante herramientas como NPM o Yarn. Una vez instalado, las dependencias de contratos están listas para ser utilizadas en el proyecto.

yarn add @openzeppelin/contracts

Al iniciar un contrato en Solidity, asegúrate de usar un compilador compatible. Por ejemplo, para trabajar con los contratos de OpenZeppelin, se recomienda un compilador desde la versión 0.8.0.

¿Cómo implementar un contrato ERC721 con OpenZeppelin?

Para crear un NFT con OpenZeppelin usando el estándar ERC721, sigue los siguientes pasos básicos:

  1. Configura el proyecto: Instalar las dependencias mencionadas y preparar el entorno de desarrollo.
  2. Crear el contrato base: Define un contrato que herede de ERC721.
  3. Añadir un constructor: Este asegura que las propiedades básicas del token, como su nombre y símbolo, estén establecidas.
pragma solidity ^0.8.0;

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

contract PlatziPunks is ERC721 {
    constructor() ERC721("PlatziPunks", "PLPKS") {}
}
  1. Desplegar el contrato: Configura un script de despliegue para que este pueda ser implementado en una red seleccionada.
async function main() {
  const [deployer] = await ethers.getSigners();
  console.log("Deploying contracts with the account:", deployer.address);

  const PlatziPunks = await ethers.getContractFactory("PlatziPunks");
  const platziPunks = await PlatziPunks.deploy();

  console.log("PlatziPunks deployed to:", platziPunks.address);
}

Herramientas de despliegue

Para implementar un contrato inteligente, como PlatziPunks, la herramienta 'hardhat' se utiliza para facilitarnos los procesos. Con ella, podemos acceder a funcionalidades a través de 'ethers' y procesar todo desde la línea de comandos.

Finalmente, OpenZeppelin no solo proporciona una base sólida y auditada, sino que también ofrece la flexibilidad necesaria para personalizar la funcionalidad de los contratos al gusto del desarrollador. Esto no solo ahorra tiempo, sino que también garantiza la construcción sobre cimientos seguros.

Aportes 14

Preguntas 18

Ordenar por:

¿Quieres ver más aportes, preguntas y respuestas de la comunidad?

scripts/deploy.js

Script comentado

// deplaoy es una función asincrona
const deploy = async () => {
  // getSigners() trae la información que traemos desde nuestra llave privada
  // deployer es un objeto que nos permite desplegar contratos a la red que tengamos configurada
  const [deployer] = await ethers.getSigners();

  console.log("Deploying contract with the account:", deployer.address);

  // Definimos PlatziPunks en el contexto
  const PlatziPunks = await ethers.getContractFactory("PlatziPunks");
  // Instancia del contracto desplegado
  const deployed = await PlatziPunks.deploy();

  console.log("Platzi Punks is deployed at:", deployed.address);
};

// Llamando la función deploy()
deploy()
  .then(() => process.exit(0))
  .catch((error) => {
    console.log(error);
    process.exit(1);
  });

Tenia un error el cual me decia que la funcion getSigners no es una funcion

cambie el require de ethers a hardhat y funciono !!!

{ethers} = require("hardhat)

Un pequeño test para la instancia de Platzi Punks, lo que no pude lograr fue testear que la
instancia efectivamente sea de tipo ERC721

const { expect } = require("chai");
const { ethers } = require("hardhat");

describe("PlatziPunks", function () {
  it("Should init contract with name and symbol", async function () {
    const PlatziPunks = await ethers.getContractFactory("PlatziPunks");
    const platzi_punks = await PlatziPunks.deploy();
    await platzi_punks.deployed();

    expect(await platzi_punks.name()).to.equal("PlatziPunks");
    expect(await platzi_punks.symbol()).to.equal("PLPKS");
  });
});

Junio 2023:

Ahora para mostrar la dirección del contrato se tiene que hacer con target en vez de address

console.log("PlatziPunks deployed to:", deployed.target);

En caso les de un error HH702 a mi me funcionó borrar la cache escribiéndo ésto en la consola:

npx hardhat clean ; npx hardhat compile

Si te da undefined el address usa:

const [account] = await ethers.getSigners();
console.log(
  "Deploying contract with the account", 
  account.address
);

si alguien esta cursando este curso en 2023 hay ciertas actualizaciones al curso que deben hacer con respecto a esta clase, en la linea 11 donde se hace le console.log para indicar la direcion de la constante “deployed” en vez de hacer referencia al deployed.addres para obtener la direccion deben hacer deployed.target, pues la propiedad address que tiene el objeto “deploed” esta dentro de runner y hace referencia es la cuenta de despliega

0:35 Es muy importante que estos no puedan se Hackeados.

Creo que eso aplica en general en el desarrollo de soluciones de software y sistemas.

PlatziPunks.sol

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

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

contract PlatziPunks is ERC721 {
  // El constructor necesita dos parámetros, el nombre y la sigla del NFT.
  constructor() ERC721("PlatziPunks", "PLPKS") {}
}

Hice una pequeña refactorización del script deploy.js:

(async function deploy() {
    const contractName = "PlatziPunks";
    try {
        const [account] = await ethers.getSigners();
        console.log("Deploying contract with the account:", account.address);
        const contractFactor = await ethers.getContractFactory(contractName);
        const contract = await contractFactory.deploy();
        console.log(`${contractName} has been deployed at: ${contract.address}`)
        process.exit(0);
    } catch (error) {
        console.log("Error: ",`An error occurred, the contract ${contractName} could not be deployed \n ${error.stack}`);
        process.exit(1);
    }
})()
Aca les dejo algo un poco mas actualizado: ```js const hre = require("hardhat"); const deploy = async () => { const [deployer] = await hre.ethers.getSigners(); console.log("Deploying contracts with the account:", deployer.address); const Mik3sPunks = await hre.ethers.getContractFactory("Mik3sPunks"); const deployedMik3sPunks = await Mik3sPunks.deploy(); const address = await deployedMik3sPunks.getAddress(); console.log("Mik3sPunks deployed to:", address); }; deploy() .then(() => { console.log("Deploy complete"); process.exit(0); }) .catch((error) => { console.error(error); process.exit(1); }); ```const hre = require("hardhat"); const deploy = async () => { const \[deployer] = await hre.ethers.getSigners(); console.log("Deploying contracts with the account:", deployer.address); const Mik3sPunks = await hre.ethers.getContractFactory("Mik3sPunks"); const deployedMik3sPunks = await Mik3sPunks.deploy(); const address = await deployedMik3sPunks.getAddress(); console.log("Mik3sPunks deployed to:", address);}; deploy() .then(() => { console.log("Deploy complete"); process.exit(0); }) .catch((*error*) => { console.error(*error*); process.exit(1); });

Para hacer el deploy tienen que abrir primero una terminal corriendo hardhat

npx hardhat node

Y en otra terminal correr:

npx hardhat run --network sepolia scripts/deploy.ts

Si les da error H700 revisen que dentro del contrato tambien tenga el mismo nombre.

Documentación para profundizar en los scripts usados en deploy.js 1.- process.exit(0) & process.exit(1) 2.- la función hh.ethers.getSigners() 3.- la función hh.ethers.getContractFactory('cotractFileName') 4.- el metodo X.getContractFactory('contracto').deploy()