Un enum type o tipo enumerado es un grupo de datos especiales a los que se les puede asignar una variable que corresponda a un conjunto de constantes predefinidas. Son implementados en muchos lenguajes de programación fuertemente tipados y Solidity los utiliza para la creación de tipos personalizados de datos y definir los valores que estos puedan tener.
Los enumerados emplean una lista de los valores que una variable puede tomar haciendo uso de un texto para visualizar el nombre a cada valor, pero guardándose un número entero por detrás. Podemos tener una máquina de estados cuyos valores sean 0, 1 y 2. Para que sea más intuitivo y fácilmente legible el significado de cada número, podemos asignarle un "pendiente" al 0, "en proceso" al 1 y "finalizado" al 2.
De esta forma, no necesitamos recortar que "finalizado" se representa por un 2, solo con utilizar el texto de cada valor del enumerado, el compilador de Solidity lo hará por nosotros. En programación, cuando necesitamos clasificar y limitar los posibles valores de una variable, podemos utilizar listas y crear nuestros propios tipos de datos con todos los valores que una variable puede tener gracias a la enumeración.
Cómo implementar enumerados en Solidity
La implementación de Solidity es muy sencilla, basta con utilizar la palabra reservada enum seguido del nombre del enumerado y sus posibles valores.
enumState{ Pendiente, EnProceso, Finalizado };
La posición de cada valor del enumerado determina el índice que le corresponde siendo Pendiente = 0, EnProceso = 1 y Finalizado = 2.Ahora puedes declarar variables de este nuevo tipo de dato personalizado.
State status;
Dentro de esta variable guardas el enumerado y puedes utilizarlo como condicionante para determinar el flujo de tu programa o asignarle nuevos valores a través del propio enumerado.
status = State.Finalizado;// 2if(status == State.Finalizado){// ...}
El simple uso del enumerado State nos ayuda a no tener que recordar el valor de cada elemento del enumerado utilizando el "Finalizado" y volviendo el código fuente mucho más legible y mantenible.
Aprovecha esta característica del lenguaje para escribir mejor código el día de mañana y que otro desarrollador o desarrolladora de software pueda entender rápidamente. Las buenas prácticas de programación hacen a la calidad del código y este tipo de característica te permitirá ser más claro con el propósito de un programa.
Las enumeraciones son la forma de crear tipos de datos definidos por el usuario, generalmente se usa para proporcionar nombres para constantes integrales, lo que hace que el contrato sea mejor para el mantenimiento y la lectura. Las enumeraciones restringen la variable con uno de los pocos valores predefinidos, estos valores de la lista enumerada se denominan enumeraciones. Las opciones de se representan con valores enteros comenzando desde cero, también se puede dar un valor predeterminado para la enumeración. Mediante el uso de enumeraciones es posible reducir los errores en el código.
enum<enumerator_name>{ element 1, elemenent 2,....,element n
}
Más información aquí
Gracias pana
Son parecidos a los enums en Java
Tengo la duda, de como se puede conectar esto del smart contract con la parte interactiva con el usuario? osea un desarrollador tradicional que desea hacer una aplicacion web, con estos servicios de smart contracts, como se vincula eso de remixide solidity con mi aplicacion web?
Los contratos generan una interfaz llamada ABI que resume todo lo que puede hacer el contrato, esto se conecta con una librería llamada web3.js que permite conectarse a un nodo de la Blockchain de Ethereum e interactuar con el Smart contract a través del ABI, de está forma se puede desde el frontend interactuar con el contrató
En el curso:
Curso de Prework para Desarrollo de Aplicaciones BlockchainDesde el recurso 15 hasta el 19, dan un ejemplo de web y contrato conectando a una wallet(Metamask).
no se por que, pero el modulo 16 no me funciona en la pc...pero si en el celular.
Este es mi avance con los estados como Enum del reto #6:
// SPDX-License-Identifier: GPL-3.0pragma solidity >=0.7.0<0.9.0;contract Proyecto_Platzi{enumState{Open,Closed} struct projectInfo{ string name; string description; string owner; address payable ownerWallet;State state; uint goal; uint currentFund;} projectInfo publicCrowFundingProject;constructor(string memory _name, string memory _owner, string memory _description, uint _goal,State _state){CrowFundingProject=projectInfo(_name, _description, _owner,payable(msg.sender), _state, _goal,0);} modifier onlyOwner(){require( msg.sender==CrowFundingProject.ownerWallet,"Only owner can change the project state");//la función es insertada en donde aparece este simbolo _;} modifier differentToTheOwner(){require( msg.sender!=CrowFundingProject.ownerWallet,"The owner can't fund the project");//la función es insertada en donde aparece este simbolo _;} event ChangeState(State previousState,State newState
); event FundValueGiven( uint fundGiven, uint valueToGoal, string greetingMessage
);functionfundProject()public payable differentToTheOwner{require(CrowFundingProject.state!=State.Closed,"Sorry, this project is closed and cannot receive funds");require(msg.value>0,"Sorry, fund value must be greater than 0, try again");CrowFundingProject.ownerWallet.transfer(msg.value);CrowFundingProject.currentFund+= msg.value; emit FundValueGiven(msg.value,(CrowFundingProject.goal- msg.value),"Thanks for your contribution");}functionchangeProjectState(State newState)public onlyOwner{require(CrowFundingProject.state!= newState,"Sorry, to change the state you must put a different state from the current one"); emit ChangeState(CrowFundingProject.state, newState);CrowFundingProject.state= newState;}}
¡Hola, Camilo!
Acabo de tomar la clase sin problema, intenta volver a cargar la pagina o puedes probar cambiando el servidor de reproducción.
En el reproductor de video en las opciones aparece una parte que dice "server" ⚙️ elige entre el A, B o C.
Los estado siempre serían números, hay alguna manera de poder ver el estado como tal, es decir "Closed" y no 1?
Si ya definiste la variable de tipo Project, porque lo referencias nuevamente? no bastaría con llamar a los atributos para llenarlos?
No entiendo muy bien tu pregunta :thinking:
definimos primero un struct llamado Project
luego definimos una variable llamada project que sea de tipo Project, el tipo que acabamos de definir
luego vamos a inicializar esta variable en el constructor pasando el valor de los atributos entre paréntesis
por ultimo modificamos las referencias a las variables para que ahora se llamen desde la variable project
No, porque esta creada la variable pero falta instanciar o crear el Struct type, definiendo sus atributos
¿Por qué la inicialización de state no se hizo en el constructor del contrato?
También se puede, sin embargo, asumo que porque no creo el constructor, era para que tenga un valor inicial.
¿Por que al meter las variables dentro del Struct se les tiene que quitar si son publicas o privadas?
El struct agrupa diferentes tipos de variables, dentro del struct no se puede modificar la visibilidad de una variable, pero a un struct si se le puede asignar una visibilidad.
Cumpliendo el reto:
// SPDX-License-Identifier: SEE LICENSE IN LICENSEpragma solidity >=0.7.0;contract crowdfunding {enumState{Opened,Closed} struct Project{ string id; string name; string description; address payable author;//who create o represent the projectState state; uint funds;// to acumulate project funds uint fundraisingGoal;// the goal of the funding}Projectpublic project;constructor(string memory _id, string memory _name, string memory _description, uint _fundraisingGoal){ project =Project( _id, _name, _description,payable(msg.sender),State.Opened,0, _fundraisingGoal
);} modifier notFundFronAuthor {require( msg.sender!= project.author,"Author don't funding his ouw project"); _;} event SendFunding( address funder, uint fund
); event RaisingFundGoal( string idProject, uint fundRaising, string mensaje
);functionfundProject()public payable notFundFronAuthor{require(msg.value>0,"Fund value must be greater then 0");//require(project.state != 1,"The project can not receive funds, it's closed"); project.author.transfer(msg.value); project.funds+= msg.value; emit SendFunding(msg.sender, msg.value);if(project.funds>= project.fundraisingGoal){ emit RaisingFundGoal( project.id, project.funds,"fundRaisingGoal reached");}} modifier onlyAuthorOrRaisingGoal {require( msg.sender== project.author|| project.funds>= project.fundraisingGoal,"Only author can change state or if the fundraidingGoal is raising"); _;// identifica desde donde se inserta la función, define cuando se continua la función} event ChangeState( string idProject,State newState
);functionchangeProjectState(State newState)public onlyAuthorOrRaisingGoal {//require(// newState == 1 || newState == 0,// "Invalid new state. It'll be 0 to Opened and 1 to Closed"//); project.state= newState; emit ChangeState(project.id, newState);}}
// SPDX-License-Identifier: GPL-3.0pragma solidity >=0.7.0<0.9.0;contract Project{ struct FundProjectData{ string id; string name; string description; address payable author; string state; uint funds; uint fundraisingGoal;}FundProjectDatapublic fundData;constructor(string memory _id, string memory _name, string memory _description, uint fundraisingGoal){ fundData =FundProjectData(_id, _name, _description,payable(msg.sender),"open",0, fundraisingGoal);} modifier difOwner(){require( fundData.author!= msg.sender,"Owner can't fund the project");// La función es insertada en donde aparece este símbolo _;} modifier onlyOwnerState(){require( fundData.author== msg.sender,"Only owner can change the project name");// La función es insertada en donde aparece este símbolo _;} error projectClosed(string message, string _state); event addFunds(string message, address donator, uint amount );functionfundProject(address payable _donator)public payable difOwner {require( msg.value>0,"Debe ingresar un monto mayor a 0");if(keccak256(abi.encodePacked(fundData.state))==keccak256(abi.encodePacked("closed"))){ string memory msgError ="El proyecto esta cerrado"; revert projectClosed(msgError, fundData.state);}else{ _donator.transfer(msg.value); uint amount = msg.value; emit addFunds("Gracias por su aporte", _donator, amount); fundData.funds+= amount;}} event changeState(string message, string oldState, string newState);functionchangeProjectState(string memory _newState)public onlyOwnerState { string memory oldState = fundData.state; fundData.state= _newState; emit changeState("El autor ha cambiado el estado", oldState, fundData.state);}}
Ahí me ven como tonto escribiento Active sin terminar de ver el video ajjajaa
Enum Types
Conjunto de valores finitos, que son creados por el propio usuario.
Son Explicitamente convertibles desde todos los tipos de entero. No permite conversion implicita.
Las conversiones explicitas revisan los valores de rango en tiempo de ejecucion y algun fallo causa una excepcion.
Los enums necesitan al menos un miembro
Codigo con el reto #6!
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.7.0 <0.9.0;
contract Crowfounding {
enum State { Open, Close }
struct Project{ string id; string name; string description; address payable owner; bool receive_funds;State state; uint funds; uint fundraisingGoal;}Projectpublic project;constructor(string memory _name, string memory _description, uint _fundraisingGoal){ project =Project("1", _name, _description,payable(msg.sender),true,State.Close,0, _fundraisingGoal
);}modifier notOwnerPay(){require( msg.sender!= project.owner,"The author can't funder the project"); _;}modifier onlyOwnerChangeState(){require( msg.sender== project.owner,"Only owner can change the state of project"); _;}modifier onlyOwnerChangeName(){require( msg.sender== project.owner,"Only owner can change the project name"); _;}event FundProject( string name, string description, address owner, bool receive_funds,State state, uint value
);event ChangeProjectState( string name, bool receive_funds,State newState
);functionfundProject()public payable notOwnerPay {require(project.state!=State.Open,"The project can not receive funds");require(msg.value>0,"Fund value must be greater than 0");if(project.receive_funds){ project.owner.transfer(msg.value); project.funds+= msg.value;} emit FundProject(project.name, project.description, project.owner, project.receive_funds, project.state, msg.value);}functionchangeFundProject()public payable {if(project.funds> project.fundraisingGoal){ project.receive_funds=false;}}functionchangeProjectState(State newState)public onlyOwnerChangeState {require(project.state!= newState,"New state must be different"); project.state= newState; emit ChangeProjectState(project.name, project.receive_funds, newState);}functionreceiveFunds()public view returns(bool){return project.receive_funds;}functionchangeProjectName(string memory _name)public onlyOwnerChangeName { project.name= _name;}
}
Hola :D les comparto mi solución para el Reto #6
// SPDX-License-Identifier: MITpragma solidity >=0.7.0<0.9.0;contract Crowfunding{enumState{Open,Closed} struct Project{ string id; string name; string description; address payable author;State state; uint funds; uint fundraisingGoal;}Projectpublic project; event FundProject(string id, uint value); event ChangeProjectState(State newState);constructor(string memory _id, string memory _name, string memory _description, uint _fundraisingGoal){ project=Project(_id, _name, _description,payable(msg.sender),State.Open,0, _fundraisingGoal);} modifier onlyOwner(){require(msg.sender== project.author,"No eres el owner"); _;} modifier projectFunders(){require(msg.sender!= project.author,"No puedes colaborar a tu propio proyecto"); _;} error StateError(State state, string message); error ValueOrStateNotValid(uint unit,State state);//Todos pueden colaborar excepto el owner functionfundProject()public payable projectFunders {if(msg.value!=0&& project.state==State.Open){ project.author.transfer(msg.value); project.funds+= msg.value; emit FundProject(project.id, msg.value);}else{ revert ValueOrStateNotValid(msg.value, project.state);}}//Solo el dueño puede cambiar el estadofunctionchangeProjectState(State newState)public onlyOwner {if(newState!=project.state){ project.state=newState;}else{ revert StateError(newState,"You cannot rewrite the same state");}}}
Tambien es util crearlos fuera del contrato e importarlos en los contratos donde es sea necesario
Aca una referencia https://solidity-by-example.org/enum/
Ain't much but its honest work:
RESUMEN CLASE 16:
ENUM TYPES
Tipos personalizados que definen estados.
Cada estado representa un entero.
enum Directions {Left, Right, Up, Down}
Directions choice;
choice = Directions.Left //0
choice = Directions.Right //1
choice = Directions.Up //2
choice = Directions.Down //3
RETO 6:
// SPDX-License-Identifier: GPL-3.0pragma solidity >=0.7.0<0.9.0;contract CrowdFunding{enumFundraisingState{Opened,Closed} struct Project{ string id; string name; string description; address payable author;FundraisingState state; uint256 funds; uint256 fundraisingGoal;}Projectpublic project; event ProjectFunded(string projectId, uint256 value); event ProjectStateChanged(string id,FundraisingState state);constructor(string memory _id, string memory _name, string memory _description, uint256 _fundraisingGoal){ project =Project( _id, _name, _description,payable(msg.sender),FundraisingState.Opened,0, _fundraisingGoal
);} modifier isAuthor(){require( project.author== msg.sender,"You need to be the project author"); _;} modifier isNotAuthor(){require( project.author!= msg.sender,"As author you can not fund your own project"); _;}functionfundProject()public payable isNotAuthor {require( project.state!=FundraisingState.Closed,"The project can not receive funds");require(msg.value>0,"Fund value must be greater than 0"); project.author.transfer(msg.value); project.funds+= msg.value; emit ProjectFunded(project.id, msg.value);}functionchangeProjectState(FundraisingState newState)public isAuthor {require(project.state!= newState,"New state must be different"); project.state= newState; emit ProjectStateChanged(project.id, newState);}}
Los Enum Types son tipos personalizados que nos permiten restringir los valores que puede tener una variable
Ejemplo: directions: Adelante, atrás, derecha, izquierda