/lrn-solidity

Learning solidity basics

Primary LanguageSolidity

Structure

  • pragma, define version compiler
  • contract, define block contract logic. A file could have multiple contracts but it's not a good practice

Example:

pragma solidity >= 0.7.0 < 0.9.0;

contract Estructura {

    constructor(){

    }

}

Data types

  • int: Números enteros.
  • uint: Números enteros sin signo.

There's not decimals in solidity

  • Bool: Boolean values
  • Address: Almacenan direcciones de Ethereum, es decir transacciones o referencias a cuentas u otros contratos.
  • String: Represent texts.
  • Bytes: Represent bytes string without formats.

Variables scope

  • Local: They are temporal to use them inside code scope.
  • State: This persist inside all contract flow, inclusive after.
  • msg: Variable global, Valores de mensajes.
  • tx: Variable global, Valores de transacción.
  • block: Variable global, relacionado con bloque de ejecución.

Example:

// contract Estructura.sol

int cantidad;
uint cantidadSinSigno;
address direccion:
bool firmado;

Structs & Arrays

  • Structs: It's a complex structure, we can save multiple data with diferentes sort of entity, like arrays, integers, strings, etc...
  • Array: Save strings of elements with the same kind of data. These could be static or dynamic.

Example:

// contract Clase.sol

struct Alumno{
    string nombre;
    uint documento;
}

// Array de tipo Alumno 
Alumno[] public alumnos;

// Creating
Alumno({ nombre: "Carlos", documento: 123456 })

Mappings and enums

  • Mappings is a way to save data key-value
  • Enums allows to us define custom values, usually use it with status.

Example:

// contract Saldo.sol

mapping(address => uint) public balance;
// ----
enum Estado { Iniciado, Finalizado }
Estado public estadoDelContrato;

Control structures

  • if/else
  • For
  • while
  • Do - While

Events

Contracts doesn't notify what happends inside them. To do this we should use events to can notify something abroad. Each event uses gas!

Example:

// contract Events.sol

// Defining an event
event NotificacionCondicion(bool condicion);

// Using and event
emit NotificacionCondicion(condicion);

// Response in logs
"event": "NotificacionCondicion",
"args": {
    "0": false,
    "condicion": false
}

Functions

Are code pieces that we can reuse them.

encapsulation types:

  • public, we can access from anywhere
  • private, we can access from the same contract
  • internal, we can access from the same and its derivated contracts.
  • external, we can access only from outside of the contract

types of functions:

  • View: it's only read function. The contract does not change.
  • Pure: We couldn't access to contract variables.

Example:

// contract Funciones.sol

function Suma(uint numero1, uint numero2) public pure returns (uint){}

function ObtenerResultado() public view returns (uint){}

Modificators

It's like a before hook that we can use before execute some function. This is used to share logic or to restrict access. It's a function as well.

Example:

// contract Modificadores.sol

// Definition
modifier EsPropietario(){}

// Use of modificator
function Suma(uint numero1, uint numero2) public view EsPropietario() returns (uint){}

Error handling

We can use: commissions

  • Revert: This one rever all changes made previously and interrupt the process.
  • Require: This one allows to define a validation and a message instead of in case the validation fails.

Example:

// contract Errores.sol

require(msg.sender == propietario, "El sender no es el mismo que el propieatario :(");

Types of memory

  • Storage: It's a persisted storage. This is the most expensive.
  • Memory: It's a temporal storage. It's most cheap.
  • Calldata: it's a memory space use it when we pass parameters inside functions.

Always we are using storage, but if we can use memory, we've to specify it.

Example:

constructor(string memory palabra){
    nombre = palabra;
}

Gas and commissions

  • Gas: It's an unit of measurement. This one indicates the computer use or effor.
  • Gas price: This change depending to the offer and demand but its the price that we have to pay for each gas.
  • Gas fee: Es la propina para el minero.

Calculate gas cost: gas * gas price

Transfers | Cash out

We have three methods to do transfers from smart contract.

  • Send: Send an ammount to an address but if the transaction is failed, then return a false as a response.
  • Tranfer: Send an ammount to an address but if the transaction is failed, this one interrumpt the process.
  • Call: Send an ammount to an address but if the transaction is failed, this return operation result.

Payable means that the address is gonna receive payments. As well these one has a gas limit by default. We can custome gas limit with call function. Send and Transfer require that the addresses will be payable type.

Receive Eth

We have following functions:

  • Receive: This is optional and it's executed when a transfer was received. This doesn't receive parameters. This is runned by default.
  • Fallback: This is optional and it's executed when a transfer was received. This receive parameters.
  • Payable function: We can executed specifing a function inside the contract.

Example:

receive() external payable {
  balances[msg.sender] += msg.value;
}

fallback() external payable {}

function recibirSaldo(uint numero) public payable {
  saldoEnviado = msg.value;
  
  uint monto = numero;
}

Using libraries

We import them using keyword import, its the same to import contracts. Libraries doesn't have a state, just functions because it is a utility.

Example:

import "@openzeppelin/contracts/utils/math/SafeMath.sol";

Inheritance

It's works exact as POO. We use Interfaces and contracts to inheritance.

We use the keyword interface to define an interface.

  • Example in Herencia.sol

Polymorphism

It's the same concept that POO.

Example in polimorfismo.sol. Short explaniation:

Es complejo de entender... pero basicamente como lo entendi, lo que paso aqui es:

  • Creas una implementacion de una interfaz.
  • Usas la dirección generada de la interfaz y la pasas como parametro dentro del contrato que la quieres implementar.
  • Dentro del contrato a implementarla, referencias la direccion a la interfaz a la que pertenece lo cual genera una instancia, posteriormente puedes usar sus métodos.

Tokens

They area a representation for some object inside a specific context. Its value is cheaper that its real value.

There exist 2 sort of tokens:

  • Fungible: They are elements that we can replace to another same token. For example, cryptocurrencies like bitcoin or ether. They are divisibles.
  • Non fungible: They aren't divisibles and each one is unique and different. Its value as well is unique. For example NFTs sources as images.

Standards

  • ERC - 20: This is defined to Fungible tokens and specify the interface for can use this kind of tokens.
  • ERC - 721: This is defined to Non fungible tokens and specify the interface for can use this kind of tokens. Each one has a unique ID.

Both give us, No implementation, only interface definition.

We can see more about the standards in the link below:

Contract tokens standards

Token URI

This give us visual details of the token, its commonly used with NFTs.

ABI (Aplication Binary Interface)

  • Es una interface que nos detalla que definiciones tiene el contrato y sus funciones, sin conocer su implementacion.
  • Nos permite saber la forma que tiene un contrato para poder interactuar con las funciones.
  • ABI se presenta en formato JSON

Just describe external and public attributes and methods.