Hugo Montoya Diaz
Newton Lora
Kevin Fiorentino
Abidan Triguero Calle
Alexis Lozano Terán
Yamil B. Prado
Andres Felipe Pardo Mesa
Kevin Fiorentino
Dany R
guillermo sanchez
Leonardo Jose Jimenez Ortiz
Andres Felipe Pardo Mesa
Jean Paul
Este curso es super interesante....
Es muy interesante poder desarrollar nosotros mismos el estandar ERC20. Más allá de que podemos utilizar las implementaciones ya auditadas como la de OpenZeppelin. Es muy valioso ver una aproximación a cómo se desarrolla este tipo de estándares.
RESUMEN CLASE 4: CASO PRACTICO SERVICIOS FINANCIEROS
REMIX:
Balance.sol
// SPDX-License-Identifier: GPL-3.0 pragma solidity >=0.7.0 <0.9.0; contract TokenBasic { string public constant name = "PlatziCoin"; string public constant symbol = "PZC"; uint8 public constant decimals = 18; uint256 _totalSupply; mapping(address => uint256) balances; mapping(address => mapping(address => uint256)) allowed; event Transfer(address indexed _from, address indexed _to, uint256 _value); event Approval( address indexed _owner, address indexed _spender, uint256 _value ); constructor(uint256 total) { _totalSupply = total; balances[msg.sender] = total; } function totalSupply() public view returns (uint256) { return _totalSupply; } function balanceOf(address _owner) public view returns (uint256) { return balances[_owner]; } function transfer(address _to, uint256 _value) public returns (bool success) { require( _value <= balances[msg.sender], "There are not enough funds to do the transfer" ); balances[msg.sender] = balances[msg.sender] - _value; balances[_to] = balances[_to] + _value; emit Transfer(msg.sender, _to, _value); success = true; } function approve(address _spender, uint256 _value) public returns (bool success) { allowed[msg.sender][_spender] = _value; emit Approval(msg.sender, _spender, _value); success = true; } function allowance(address _owner, address _spender) public view returns (uint256 remaining) { remaining = allowed[_owner][_spender]; } function transferFrom( address _from, address _to, uint256 _value ) public returns (bool success) { require( _value <= balances[_from], "There are not enough funds to do the transfer" ); require(_value <= allowed[_from][msg.sender], "Sender not allowed"); balances[_from] = balances[_from] - _value; allowed[_from][msg.sender] = allowed[_from][msg.sender] - _value; balances[_to] = balances[_to] + _value; emit Transfer(_from, _to, _value); success = true; } }
El total supply debe estar multiplicado por 10 elevado a la cantidad de decimales del token.
Como logras que un token genere que las personas le den valor??
Los tokens fungibles pueden representar un valor indirectamente, por ejemplo, imagina que un juego pudieras usar estos tokens para comprar en una tienda virtual, también pueden adquirir valor a medida que se intercambian con otros tokens.
Todo el concepto detrás del valor de una crypto o un token se lo denomica Tokenomics. La fructuacón del precio dependerá de varias factores a lo alrgo del tiempo.
Para el ejemplo mostrado colocar la variable decimals no cambia el funcionamiento del contrato. En el estandar ERC20 no hay una variable, sino una función llamada decimals ( ) que devuelve el numero de decimales que debe tener el token creado. Mientras que en los contratos se trabaja con la minima unidad entera soportada en solidity (wei), a los usuarios se les muestra un valor con decimales. La funcion decimals ( ) es para mejorar la usabilidad del usuario como en los exploradores de bloques o Metamask, para que no tengan que lidiar con numeros grandes.
Creee un contrato nuevo basado en el estandat ERC-20 este tiene 3 modificaciones especiales las cuales me di a la tarea de investigar y de contemplar como posibles mejoras a un token
la primera es que para usar al momento de despliegue del contrato en alguno red el monto como supply inicial con el metodo mint esto ayuda a que no se haga un llamado nuevo para ello como suele pasar con los contratos normales, esto economisa costo pero si alguien tiene un objecion esto atento a ello
constructor(uint256 _totalSupply) ERC20("Nova-platzi-Coin", "n-plc") { owner = msg.sender; _mint(msg.sender, _totalSupply); } ``` function totalSupply() public view override virtual onlyOwner returns (uint256) { return ERC20.totalSupply(); }   modifier onlyOwner { require(msg.sender == owner, "only owner can check the supply"); \_; }el segundo cambio va con ese tema es que el totalsupply es provado al owner jajaj casi como una cbdc ,jejeje no. es mas para entender los conceptos de privado y publico asi como over ride que fueron muy buenos para estudiarlos en practica. lo que hago es llaamr el valor del metodo del padre. ```js function totalSupply() public view override virtual onlyOwner returns (uint256) { return ERC20.totalSupply(); } modifier onlyOwner { require(msg.sender == owner, "only owner can check the supply"); _; } ```por ultimo pongo un update que es demaciado util pero que me llevo tiempo de estudio y es el tema del aproval. es molesto que tengamos que hacer aproval del valor y si queremos incrementarlo pues sea actualizar el mapping y no de manera incrementa, esto a mi forma de pensar funcionaria si el token es usado en una familia de manera comprartida por los hijo donde ellos pueden hacer una forma de "staking" pasivo por la asignacion del representante, una idea fumada pero linda. eso requierio crear en el contrato el mismo prop que en el padre haciendo overide? pues no! por que override solo le hacer a la publicas si es privada te jodes y tienes que crearla interna y hacerla tu mismo el overide de los metodos para que usen la local del hijo aqui les dejo mi ejemplo es drogo pero funciona // SPDX-License-Identifier: MIT// Compatible with OpenZeppelin Contracts ^5.0.0pragma solidity ^0.8.20; import "@openzeppelin/contracts/token/ERC20/ERC20.sol"; contract novaPlatziCoin is ERC20 {   mapping(address account => mapping(address spender => uint256)) private \_allowances;   address private owner; constructor(uint256 \_totalSupply) ERC20("Nova-platzi-Coin", "n-plc") { owner = msg.sender; \_mint(msg.sender, \_totalSupply); }   function totalSupply() public view override virtual onlyOwner returns (uint256) { return ERC20.totalSupply(); }   modifier onlyOwner { require(msg.sender == owner, "only owner can check the supply"); \_; }   function \_approve(address owner, address spender, uint256 value, bool emitEvent) internal override virtual { if (owner == address(0)) { revert ERC20InvalidApprover(address(0)); } if (spender == address(0)) { revert ERC20InvalidSpender(address(0)); } \_allowances\[owner]\[spender] += value; if (emitEvent) { emit Approval(owner, spender, value); } }   function allowance(address owner, address spender) public view virtual override returns (uint256) { return \_allowances\[owner]\[spender]; }   function balanceOf(address account) public view virtual override returns (uint256) { return ERC20.balanceOf(msg.sender); } }```js // SPDX-License-Identifier: MIT // Compatible with OpenZeppelin Contracts ^5.0.0 pragma solidity ^0.8.20; import "@openzeppelin/contracts/token/ERC20/ERC20.sol"; contract novaPlatziCoin is ERC20 { mapping(address account => mapping(address spender => uint256)) private _allowances; address private owner; constructor(uint256 _totalSupply) ERC20("Nova-platzi-Coin", "n-plc") { owner = msg.sender; _mint(msg.sender, _totalSupply); } function totalSupply() public view override virtual onlyOwner returns (uint256) { return ERC20.totalSupply(); } modifier onlyOwner { require(msg.sender == owner, "only owner can check the supply"); _; } function _approve(address owner, address spender, uint256 value, bool emitEvent) internal override virtual { if (owner == address(0)) { revert ERC20InvalidApprover(address(0)); } if (spender == address(0)) { revert ERC20InvalidSpender(address(0)); } _allowances[owner][spender] += value; if (emitEvent) { emit Approval(owner, spender, value); } } function allowance(address owner, address spender) public view virtual override returns (uint256) { return _allowances[owner][spender]; } function balanceOf(address account) public view virtual override returns (uint256) { return ERC20.balanceOf(msg.sender); } }
Pd: Dejo el contrato aqui y en un git me disculpan las formas. si me preguntan ando cansado, y mi pais anda en peos politicos asi que no tengo muchas capacidades para un lexico, ortografia y redaccion pulcra.
que hace el "indexed" ???
Es una palabra reservada que se usa para eventos y sirve para poder filtrar el evento por el argumento indexado, es decir, si añades indexed a un argumento _from, luego vas a poder buscar el evento y filtrarlo por cualquier valor para _from
Tomando en cuenta que es un estándar, ¿existe el peligro que un tercero genere un token sin la posibilidad que sus compradores tengan la posibilidad de vender tiempo después de adquirirlos?