Lição 184: Padrões de Design: Máquina de Estados
Introdução
No desenvolvimento de software, uma máquina de estados é um modelo que pode estar exatamente em um dos estados de um número finito de estados em um determinado momento. Esse padrão de design é particularmente útil em contratos inteligentes, onde os diferentes estados de um contrato podem representar comportamentos ou condições distintas. Implementar uma máquina de estados ajuda a gerenciar fluxos complexos de contratos, garantindo que ações específicas só possam ser realizadas quando o contrato estiver em um estado válido.
Nesta lição, vamos explorar como implementar uma máquina de estados em Solidity, utilizando um contrato de exemplo para ilustrar o conceito.
Implementando uma Máquina de Estados em Solidity
Vamos criar um contrato simples que representa um sistema de processamento de pedidos. O pedido pode estar em um dos seguintes estados:
- Criado: O pedido foi criado.
- Pago: O pedido foi pago.
- Enviado: O pedido foi enviado.
- Concluído: O pedido foi concluído.
Usaremos um enum
para representar nossos estados e funções para realizar a transição entre eles.
Passo 1: Definir a Máquina de Estados
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
contract MaquinaDeEstadosDePedido {
enum Estado { Criado, Pago, Enviado, Concluído }
Estado public estadoAtual;
address public dono;
constructor() {
dono = msg.sender;
estadoAtual = Estado.Criado;
}
}
Passo 2: Implementar Funções de Transição de Estado
Em seguida, implementaremos funções que permitem a transição entre estados. Vamos garantir que as transições sejam permitidas apenas em condições válidas.
function pagar() public {
require(estadoAtual == Estado.Criado, "O pedido deve estar criado para ser pago.");
estadoAtual = Estado.Pago;
// Lógica adicional para processamento do pagamento pode ser adicionada aqui
}
function enviar() public {
require(estadoAtual == Estado.Pago, "O pedido deve estar pago para ser enviado.");
estadoAtual = Estado.Enviado;
// Lógica adicional para envio pode ser adicionada aqui
}
function concluir() public {
require(estadoAtual == Estado.Enviado, "O pedido deve estar enviado para ser concluído.");
estadoAtual = Estado.Concluído;
// Lógica adicional para conclusão do pedido pode ser adicionada aqui
}
Passo 3: Adicionar Função para Verificar o Estado Atual
Para permitir que contratos externos ou usuários verifiquem o estado do pedido, adicionamos uma função que retorna o estado atual.
function obterEstadoAtual() public view returns (Estado) {
return estadoAtual;
}
Contrato Completo
Combinando tudo, temos o seguinte contrato inteligente completo:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
contract MaquinaDeEstadosDePedido {
enum Estado { Criado, Pago, Enviado, Concluído }
Estado public estadoAtual;
address public dono;
constructor() {
dono = msg.sender;
estadoAtual = Estado.Criado;
}
function pagar() public {
require(estadoAtual == Estado.Criado, "O pedido deve estar criado para ser pago.");
estadoAtual = Estado.Pago;
}
function enviar() public {
require(estadoAtual == Estado.Pago, "O pedido deve estar pago para ser enviado.");
estadoAtual = Estado.Enviado;
}
function concluir() public {
require(estadoAtual == Estado.Enviado, "O pedido deve estar enviado para ser concluído.");
estadoAtual = Estado.Concluído;
}
function obterEstadoAtual() public view returns (Estado) {
return estadoAtual;
}
}
Conclusão
Nesta lição, implementamos uma máquina de estados em Solidity para gerenciar os diferentes estados de um sistema de processamento de pedidos. Ao utilizar enums
e declarações require
, garantimos que as transições de estado sejam válidas e que as ações realizadas no contrato correspondam ao estado atual.
Esse padrão é amplamente aplicável em contratos inteligentes, especialmente em cenários como processos em várias etapas, aprovações, ou qualquer situação em que o comportamento do contrato deva mudar com base em seu estado atual. Entender e aplicar o padrão de design de máquina de estados pode aumentar significativamente a confiabilidade e a clareza de suas implementações de contratos inteligentes.