Codemotion-WorkshopFest-Recursos01.txt TITULO DEL WORKSHOP: "Configuración y despliegue de contratos inteligentes en la blockchain de Ethereum y redes compatibles con la EVM" En este taller vamos a ver un ejemplo práctico y sencillo de cómo configurar un contrato de un token fungible, según el estandard ERC-20, sobre la red Ethereum y que es válido para desplegarlo y ejecutarlo en cualquier otra red blockchain compatible con la máquina virtual de Ethereum (EVM). Los participantes verán una forma muy fácil de conseguirlo, sin necesidad de teclear código, aunque dicho código (Solidity) estará disponible, por si se necesitara adaptar a requisitos específicos. Para ello se va a usar la cartera (wallet) Metamask y el entorno de desarrollo de contratos inteligentes en la nube Remix, así como las plantillas de contratos configurables que ofrece Open Zeppelin, todo ello sobre la red de pruebas de Ethereum. También se verá lo sencillo que es desplegarlo en otras blockchains compatibles. Una vez creado el token, se comprobará de su correcto despliegue en un buscador de bloques, como Etherscan. PUNTOS PRINCIPALES: * Contratos inteligentes (Smart Contracts) ERC-20 * Ethereum y redes compatibles con la EVM * Configuración y despliegue del token, mediante el entorno en línea Remix * Comprobación del despliegue en el buscador Etherscan * Despliegue en otras redes compatibles Juan Antonio Lleó juan.a.lleo@gmail.com Telegram: https://t.me/Juan_A_Lleo PRESENTACION: http://tmp.lleo.net/SPA23_WF-SMART_CONTRACTS-Juan_A_Lleo.pdf RECURSOS: http://tmp.lleo.net/Codemotion-WorkshopFest-Recursos01.txt CONTENIDO: 1º) ENLACES PARA EL TALLER: 2º) CONTRATOS DE EJEMPLO, CON TRANSACCIONES 3º) CODIGO DE LOS CONTRATOS 1º) ENLACES PARA EL TALLER: - ETHEREUM: https://ethereum.org/en/ - METAMASK: https://metamask.io/ - INSTALAR: Directamente desde el sitio web de Metamask, o a través del propio navegador, en la opción: Extensiones, añadir la opción Metamask https://metamask.io/download/ - TUTORIAL (EN ESPAÑOL): Comenzar con MetaMask https://support.metamask.io/hc/es/articles/360015489531 - TUTORIALES EN INGLES: https://learn.metamask.io/es-ES - CHAINLIST: - PARA AÑADIR A METAMASK REDES NUEVAS (MAINNET O TESTNET) https://chainlist.org/?testnets=true - TESTNETS: - SEPOLIA: - Sepolia PoW Faucet: https://sepolia-faucet.pk910.de/#/ - SEPOLIA ARBITRUM: - QUICKNODE SEPOLIA FAUCET: HAY QUE TENER >=0.001 ETH EN LA WALLET https://faucet.quicknode.com/arbitrum/sepolia - QUICKNODE (FAUCET PARA VARIAS BLOCKCHAINS): PERO HAY QUE TENER >=0.001 ETH (MAINNET) EN LA WALLET https://faucet.quicknode.com/drip - REMIX: https://remix.ethereum.org/ - OPEN ZEPPELIN: https://www.openzeppelin.com/contracts - ARTICULOS: https://programtheblockchain.com/posts/2018/01/30/writing-an-erc20-token-contract/ - TUTORIALES: https://solidity-by-example.org/app/erc20/ https://dev.to/abdulmaajid/how-to-create-an-erc20-token-in-solidity-1a9h DIRECCIONES DE ETHEREUM: - J A LLEO PROFESOR: 0x5A92752eD040472ECA7384BA934C4109bD09478E - Lleo Profesor Brave1: 0x393209F00aeedEF077B253Aa4553683c5C10c7b2 - COMPILACIONES Y DESPLIEGUES: - DIRECCION: J A LLEO PROFESOR 0x5a92752ed040472eca7384ba934c4109bd09478e - EN ARBITRUM GOERLI: https://goerli.arbiscan.io/address/0x5a92752ed040472eca7384ba934c4109bd09478e 2º) CONTRATOS DE EJEMPLO: ------------------------------------------------------------ HelloWorld.sol - VERSION INTERACTIVA: - EN ARBITRUM GOERLI: - CREACION DEL CONTRATO (TRANSACCION): https://goerli.arbiscan.io/tx/0xd8cc4be337542b6879677f95f33d59674181ba54048effd3d31842b145ee0fee - DIRECCION DEL CONTRATO: https://goerli.arbiscan.io/address/0xb978a1d45acde69d0292a0a040ddc65ad6ae2500 - FUNCION: NEW MESSAGE: ¡Hola Codemotion! - TRANSACCION PARA PONER UN MENSAJE: https://goerli.arbiscan.io/tx/0x20917ddfee5d8437ca815be65e5d6d8faf7e3e12cdc6ed25dc250aac92b039ac ------------------------------------------------------------ Storage.sol - EN ARBITRUM GOERLI: - CREACION DEL CONTRATO (TRANSACCION): https://goerli.arbiscan.io/tx/0x234ff1552323e85044f315b0e668f8f63e4c25a66d26928dcde45cb968206a0d - DIRECCION DEL CONTRATO: https://goerli.arbiscan.io/address/0x0f6f9683453beb218fb2c5be5ff6a3080f07deff - FUNCION: STORE - ALMACENA EL NUMERO: 123453 https://goerli.arbiscan.io/tx/0xe3d7d7e7f75e830d4c13f22edce698f20e7ec58c8e15cb0a284309576dc34711 ------------------------------------------------------------ CodemotionSimpleERC20Token.sol - EN ARBITRUM GOERLI: - CREACION DEL CONTRATO (TRANSACCION): https://goerli.arbiscan.io/tx/0x3670560b6cda1edc8b693c0fdb68d3abde8688a9caac584d6a009665fb2f25c8 - PROPIETARIO: 0x5A92752eD040472ECA7384BA934C4109bD09478E - DIRECCION DEL CONTRATO: Codemotion Simple ERC20 Token (CODSET) 0x809bF37f3B469B4267c40fb4a8c56dcB97ed118A https://goerli.arbiscan.io/address/0x809bf37f3b469b4267c40fb4a8c56dcb97ed118a - MINTEO LOS TOKENS: - EN REMIX, TENGO QUE INVOCAR LA FUNCION: SimpleERC20Token - TENGO QUE PONER LA DIRECCIÓN A LA QUE LOS QUIERO MINTEAR Y EL NÚMERO DE TOKENS QUE QUIERO GENERAR - DIRECCION: 0x5a92752ed040472eca7384ba934c4109bd09478e - Nº DE TOKENS (TOTAL SUPPLY): 1000000 (AÑADIR DOS CEROS MAS, POR LOS DECIMALES: 100000000) - CONTRATO: Token Codemotion Simple ERC20 Token (CODSET) https://goerli.arbiscan.io/token/0x809bf37f3b469b4267c40fb4a8c56dcb97ed118a#balances - PARA AÑADIR EL TOKEN A METAMASK: - SELECCIONO LA OPCION: AÑADIR UN NUEVO TOKEN - COPIO LA DIRECCION DEL CONTRATO: 0x809bf37f3b469b4267c40fb4a8c56dcb97ed118a - CUANDO PONGO LA DIRECCION, AL POCO APARECE EL SÍMBOLO Y EL Nº DE DECIMALES DEL TOKEN (EN ESTE CASO 2 DECIMALES) - TRAS AÑADIRLO, ME INDICA EL SALDO DE ESE TOKEN QUE TENGO DISPONIBLE - PARA TRANSFERIR TOKENS: - SE PUEDE HACER AL DESPLEGARLO, DESDE REMIX, O DESDE METAMASK, CON LA DIRECCIÓN QUE TIENE LOS TOKENS - TRANSFERIR: 100 CODSET A OTRA DIRECCION: 0x393209f00aeedef077b253aa4553683c5c10c7b2 - TENGO QUE AÑADIR DOS CEROS MAS AL FINAL, QUE SON LOS QUE CORRESPONDEN A LOS DECIMALES (10000) - TRANSACCION DE TRANSFERENCIA: https://goerli.arbiscan.io/tx/0x71ac8813447d566b7bf35d4e0f0981de3e3edc357c51a3e49db28dde141733f0 - HE TRANSFERIDO 200 + 100 TOKENS, EN DOS TRANSFERENCIAS: - SE PUEDE COMPROBAR QUE SE HA HECHO LA TRANSACCION EN LA PÁGINA DEL CONTRATO, EN LA PESTAÑA HOLDERS - PUEDO CONSULTAR POR LA DIRECCION DE DESTINO A LA QUE SE HAN MANDADO: https://goerli.arbiscan.io/token/0x809bf37f3b469b4267c40fb4a8c56dcb97ed118a?a=0x393209f00aeedef077b253aa4553683c5c10c7b2 ------------------------------------------------------------ OPEN ZEPPELIN: CONFIGURADOR DE SMART CONTRACTS MEDIANTE FORMULARIOS https://openzeppelin.com/contracts - CONTRATO ERC-20 (PROFESIONAL): OZ_ERC20_Mintable.sol - ERC20 MINTEABLE: - ADAPTADO COMO EJEMPLO, CAMBIO LA DESCRIPCION: NOMBRE DEL TOKEN, SIMBOLO DEL TOKEN - ERC20("OpenZeppelin ERC20 Token Mintable", "OZMINT") OZ_ERC20_Mintable.sol - NOTAS: - AL COMPILARLO, SE PUEDE VER LA LISTA DE LOS CONTRATOS ASOCIADOS - AL DESPLEGAR, HAY QUE AÑADIR LA DIRECCION DEL PROPIETARIO INICIAL - AL TRATAR DE DESPLEGARLO EN ARBITRUM GOERLI, ME DA UN ERROR - PERO EN ETHEREUM GOERLI Y EN SEPOLIA, FUNCIONA: - DESPLIEGUE: ------------------------------------------------------------ - EN GOERLI: - DIRECCION DEL PROPIETARIO (OWNER): 0x5A92752eD040472ECA7384BA934C4109bD09478E - CREACION DEL CONTRATO: - TRANSACCION: https://goerli.etherscan.io/tx/0x519b322a412e472877a7b2b5c333079e4039226492ad2a7644301fe57a5f9140 - CONTRATO DEL TOKEN: OpenZeppelin ERC20 Token Mintable (OZMINT) 0xc0BEdc03eD9838293f5Cb4edF613899c40035D1A https://goerli.etherscan.io/token/0xc0bedc03ed9838293f5cb4edf613899c40035d1a#balances - UNA VEZ DESPLEGADO, YA SE PUEDE USAR LA FUNCIÓN DE MINTEADO EN REMIX: mint - HAY QUE AÑADIR AL Nº DE TOKENS QUE QUEREMOS MINTEAR, LOS 18 CEROS CORRESPONDIENTES: - PARA 10 TOKENS: 10000000000000000000 - PARA 1000000 TOKENS: 1000000000000000000000000 - MINTEADO 1000000 TOKENS: - SE TRANSFIEREN A LA DIRECCION DEL PROPIETARIO DEL CONTRATO https://goerli.etherscan.io/tx/0x2e5574a24fa2b2aeb29d3dbb5d66f4e15840e89dd4d9eff374d73b69bdf7a48f - Y YA SE PUEDEN TRANSFERIR A OTRA DIRECCIÓN - PERO EN GOERLI ES CARO, SUELE ESTAR OCUPADA Y ES DIFICIL CONSEGUIR TOKENS DE TESTNET ------------------------------------------------------------ - EN SEPOLIA: - DIRECCION DEL PROPIETARIO (OWNER): 0x5A92752eD040472ECA7384BA934C4109bD09478E - CREACION DEL CONTRATO: OpenZeppelin ERC20 Token Mintable (OZMINT) - TRANSACCION: https://sepolia.etherscan.io/tx/0x08f1dccdaae750b0a3049abd0427a317dced40edde3a6075e2425fd768ddf762 - CONTRATO: 0x73A743dC2cC96e6021D31Dae55058fa5Ffe4672e - TOKEN: https://sepolia.etherscan.io/token/0x73a743dc2cc96e6021d31dae55058fa5ffe4672e - MINTEADO 1000000 TOKENS: https://sepolia.etherscan.io/tx/0x4c4c39079ee7479e96ad8d9a8cbc5ecaf5d0a09d0b423c523aae9ab5d8bfd813 - TRANSFERIR 100 TOKENS OZMINT (100000000000000000000, QUE TIENE 18 DECIMALES) A LA DIRECCIÓN: 0x393209F00aeedEF077B253Aa4553683c5C10c7b2 https://sepolia.etherscan.io/tx/0xb4bebb4f46ba674f8d383d4a3a95a69d49db725970eac79b2157afa10c7402bd - COMPROBACION EN LA PAGINA DEL TOKEN, FILTRADO POR LA DIRECCION DE DESTINO: https://sepolia.etherscan.io/token/0x73a743dc2cc96e6021d31dae55058fa5ffe4672e?a=0x393209f00aeedef077b253aa4553683c5c10c7b2 ------------------------------------------------------------ 3º) CODIGO DE LOS CONTRATOS: - HOLA MUNDO EN SOLIDITY: - HELLO WORLD (VERSION SENCILLA): HelloWorldSimple.sol https://solidity-by-example.org/hello-world/ -------------------------------------------------- // SPDX-License-Identifier: MIT // compiler version must be greater than or equal to 0.8.20 and less than 0.9.0 pragma solidity ^0.8.20; contract HelloWorld { string public greet = "Hello World!"; } -------------------------------------------------- - HELLO WORLD (VERSION INTERACTIVA): HelloWorld.sol -------------------------------------------------- pragma solidity ^0.5.10; // Defines a contract named `HelloWorld`. contract HelloWorld { string public message; constructor(string memory initMessage) public { message = initMessage; } function update(string memory newMessage) public { message = newMessage; } } -------------------------------------------------- -------------------------------------------------- - STORAGE: Almacena y consulta un valor numérico Storage.sol -------------------------------------------------- // SPDX-License-Identifier: GPL-3.0 pragma solidity >=0.8.2 <0.9.0; /** * @title Storage * @dev Store & retrieve value in a variable * @custom:dev-run-script ./scripts/deploy_with_ethers.ts */ contract Storage { uint256 number; /** * @dev Store value in variable * @param num value to store */ function store(uint256 num) public { number = num; } /** * @dev Return value * @return value of 'number' */ function retrieve() public view returns (uint256){ return number; } } -------------------------------------------------- -------------------------------------------------- ERC-20: - ADAPTACION A WORKSHOP DE CODEMOTION: - EJEMPLO SENCILLO ERC-20 EN UN SOLO FICHERO SOLIDITY: - NOMBRE: CodemotionSimpleERC20Token.sol - FUENTE: https://programtheblockchain.com/posts/2018/01/30/writing-an-erc20-token-contract/ -------------------------------------------------- pragma solidity ^0.4.21; contract SimpleERC20Token { // Track how many tokens are owned by each address. mapping (address => uint256) public balanceOf; string public name = "Simple ERC20 Token"; string public symbol = "SET"; uint8 public decimals = 2; uint256 public totalSupply = 1000000 * (uint256(10) ** decimals); event Transfer(address indexed from, address indexed to, uint256 value); function SimpleERC20Token() public { // Initially assign all tokens to the contract's creator. balanceOf[msg.sender] = totalSupply; emit Transfer(address(0), msg.sender, totalSupply); } function transfer(address to, uint256 value) public returns (bool success) { require(balanceOf[msg.sender] >= value); balanceOf[msg.sender] -= value; // deduct from sender's balance balanceOf[to] += value; // add to recipient's balance emit Transfer(msg.sender, to, value); return true; } event Approval(address indexed owner, address indexed spender, uint256 value); mapping(address => mapping(address => uint256)) public allowance; function approve(address spender, uint256 value) public returns (bool success) { allowance[msg.sender][spender] = value; emit Approval(msg.sender, spender, value); return true; } function transferFrom(address from, address to, uint256 value) public returns (bool success) { require(value <= balanceOf[from]); require(value <= allowance[from][msg.sender]); balanceOf[from] -= value; balanceOf[to] += value; allowance[from][msg.sender] -= value; emit Transfer(from, to, value); return true; } } -------------------------------------------------- OPEN ZEPPELIN: CONTRATO ERC-20 (PROFESIONAL) OZ_ERC20_Mintable.sol https://www.openzeppelin.com/contracts - SOLO SE MUESTRA EL CONTRATO PRINCIPAL, QUE INVOCA A OTROS CONTRATOS - EN TOTAL SE NECESITAN 9 CONTRATOS, QUE APARECEN REFLEJADOS TRAS LA COMPILACIÓN -------------------------------------------------- // SPDX-License-Identifier: MIT pragma solidity ^0.8.20; import "@openzeppelin/contracts@5.0.0/token/ERC20/ERC20.sol"; import "@openzeppelin/contracts@5.0.0/access/Ownable.sol"; contract MyToken is ERC20, Ownable { constructor(address initialOwner) ERC20("OpenZeppelin ERC20 Token Mintable", "OZMINT") Ownable(initialOwner) {} function mint(address to, uint256 amount) public onlyOwner { _mint(to, amount); } } --------------------------------------------------