Estructura de smart contract
Last updated
Was this helpful?
Last updated
Was this helpful?
Tecnicamente un smart contract se compone por variables constructoras y funciones que cuentas con varias facetas, constructores de tipo:
Variables de estado
Definiciones de estructura
Definiciones de modificador
Declaración de eventos
Definición de enumeradores
Definición de funciones
Un constructor puede ser compuesto por otro constructor, a continuación un ejemplo de un archivo .sol usando algunos de los constructores mencionados:
Variables donde se pueden almacenar valores, se pueden remplazar su valor y también se puede usar en multiples partes dentro del código del smart contract.
Todas las variables que declaradas que no están dentro de una función se denominan variables de estado.
La memoria asignada para las variables de estado es estática lo que quiere decir que no puede cambiar su tamaño (del tipo de variable) durante el tiempo de vida del smart contract, el compilador de solidity debe determinar los detalles de asignación incluyendo el tamaño en memoria usado partiendo del tipo de la variable de estado.
Las variables de estado también vienen asociadas a un "calificador":
internal: es el calificador por defecto, la variable no lleva un calificador se asigna internal automáticamente. _internal _quiere decir que solo podrán ser usadas dentro del actual smart contract, no pueden ser modificadas desde afuera del contrato, sin embargo, si pueden ser vistas. un ejemplo: int internal privateStateVariable ;
private: Son similares a las internal _solo pueden ser usadas en el contrato donde fueron declaradas pero con la restricción de que no pueden ser usadas en los contratos derivados, un ejemplo: int private privateStateVariable ;
public: Este calificador hace que la variable de estado se pueda acceder directamente, el compilador de solidity genera un función getter _pata cada public variable, un ejemplo: int public stateIntVariable ;
constant: Este calificador hace que la variable sea inmutable, el valor debe ser asignado en el momento de declaración , un ejemplo: bool constant hasIncome = true ;
Como podemos observar en los anteriores ejemplos de declaración de variables, vienen acompañados por un tipo de dato. el tipo de dato nos ayuda a conocer la cantidad de memoria que se requiere para la variable y los valores que podemos almacenar en ella. por ejemplo uint8 también conocido como "Unsigned integer" se asigna una cantidad de memoria predeterminada y puede almacenar valores entre 0 y 255, otro valor se considera como extraño y no es aceptado por el compilador en tiempo de ejecución.
Tipos de datos listos para usar:
bool
uint / int
bytes
address
mapping
enum
struct
bytes / String
Usando enum y struct es posible declarar un tipo definido por el usuario.
Nos ayuda a crear tipos de datos personalizados o construidos por el usuario, un struct es compuesto por multiples variables tipos de datos, similares a los smart contracts pero solo con variables y no con eventos y funciones.
Las struct pueden contener array y mapping variables, mientras que estas no podrÃan contener structs.
Los modifiers están siempre asociados a una función y cambia el comportamiento en que se ejecuta el código, podemos pensar que el modifier se ejecuta justo antes de ejecutar la función a la cual está asociado. Esto nos ayuda a escribir funciones mas limpias y fácil de implementar, por ejemplo podemos poner en el modifier las validaciones necesarias antes de ejecutar la función real sea ejecutada., además los modifiers pueden ser asociados a multiples funciones, es decir se pueden escribir (una sola vez) modifiers generales que se usan en varias partes del smart contracts. Es una buena practica para mantener el código limpio y legible.
Asà se declara un modifier:
modifier es la palabra clave onlyBy es el identificador del modifier (puede recibir parámetros dentro de los paréntesis), dentro de los { } se pone el código del modifier, el **\ **_(underscore) significa que en ese punto se ejecuta la función objetivo, es decir la función asociada. En el anterior ejemplo el modifier revisa que msg.sender que es el address entrante sea igual el almacenado en la variable de estado personIdentifier y en caso de que esta validación sea verdadera se ejecutará la función asociada.
El uso del modifier se veria asÃ:
La función getAge solo se ejecutará cuando la cuenta entrante es igual a la almacenada en la variable del contrato personalIdentifier. Cabe anotar que cualquiera puede invocar getAge pero pero la ejecución solo será valida para una sola address (la almacenada en la variable).
Los eventos en solidity son usados para capturar y ejecutar cierto código de respuesta, principalmente captan un momento de ejecución dentro de una función y lo registra como un logging que facilita la EVM (ethereum virtual machine) pata notificar cambios importantes en el smart contract. La información de los Event y los valores almacenados en sus variables son registrados dentro de los blocks de la blockchain (_LogsBloom _property).
Los event son declarado en el nivel global del contrato y son invocados dentro de una función. No es necesario pasar variables como parámetros en la declaración de Events, basta con el tipo de dato:
Un evento puede ser invocado desde una función pasándole los parámetros que requiere (pueden ser variables con valores almacenados):
Los enum sirven para definir tipos de datos definidos por el usuario, funcionan como una lista o un conjunto de nombres constantes, cada valor constante dentro del enum toma un valor entero donde el primero es cero (0) y van incrementando en uno (1) los siguientes, es de notar que a diferencia que las anteriores sentencias de declaración los enum no requiere terminar con punto y coma (;), pero si debe contener al menos un item en la lista:
una variable de tipo enum puede ser declarada y asignada de la siguiente manera:
Los enum no son estrictamente necesarios dentro de un smart contract, se deben definir si los valores de los item de la lista no van a cambiar con el tiempo como en el anterior ejemplo.
Por medio de las funciones podemos cambiar los valores de las variables de estado en un smart contract, por medio de estas podemos ejecutar transacciones .
Cuando una function es llamada o invocada su resultado es una transaction
Son el mecanismo para leer y escribir valores en las variables de estado, pueden recibir parámetros, ejecutar lógica y opcionalmente retornar valores a quien las invoque.
la anterior function contiene un solo parámetro pero si se requiere mas pueden ir separados por coma (,). en la lista de parámetros se debe especificar el tipo de dato de cada uno, puede también tener modifiers como lo lo muestra el ejemplo anterior (onlyBy). las funciones pueden devolver una lista de parámetros utilizando la palabra clave return.
Hay un par de calificadores que afectan el comportamiento y ejecución de la function, los calificadores de visibilidad son:
public: hacen que la function sea visible directamente desde afuera, se convierten en la interfaz del contrato y pueden ser invocadas tanto desde afuera como desde dentro del smart contract
internal: Son el calificador por defecto, si no se especifica calificador automáticamente la function es internal, lo que quiere decir que solo se puede acceder desde el actual contrato o desde un contrato que derive de este. no hacen parte de la interfaz del smart contract
private: Las functions privadas solo son usadas desde el contract donde son declaradas, no los derivados, tampoco hacen parte de la interfaz del smart contract
external: hace que las functions sean directamente visibles desde el exterior pero no internamente, hacen parte de la interfaz del smart contract
las functions también pueden tener calificadores en función de cambiar el comportamiento de las variables de estado:
constant: Functions con este calificador no pueden modificar las variables de estado, solo pueden retornar el valor de una variable de estado, no pueden llamar a otra function
view: son un alias de las constant functions
pure: son function aún mas restringidas, no pueden leer ni escribir sobre las variables de estado, en otras palabras no pueden ver las variables de estado.
payable: Estas functions tienen la habilidad de aceptar Ether desde quien las invoca, estas functions fallaran en caso de que el Ether no sea provisionado, es la única que puede aceptar Ether.
Son útiles para almacenar variables relacionadas que queremos que permanezcan juntas o agrupadas para identificar una entidad, por ejemple un empleado :y para crear una instancia del struct anterior seria algo como (no hay necesidad de usar la palabra clave new):