WEB3DEV

Cover image for Construindo Um contrato Inteligente de Serviço Baseado em Assinatura com QuickNode RPC
Isabela Curado Nehme
Isabela Curado Nehme

Posted on

Construindo Um contrato Inteligente de Serviço Baseado em Assinatura com QuickNode RPC

https://miro.medium.com/v2/resize:fit:720/format:webp/1*PydDdzpNecVgl8L_2EJcWA.png

Pré-requisitos

  • O que é um contrato inteligente de serviço baseado em assinatura?
  • Principais recursos e componentes de um contrato inteligente de serviço baseado em assinatura.
  • Casos de uso de um contrato inteligente de serviço baseado em assinatura.
  • Escrevendo um contrato inteligente de serviço baseado em assinatura.
  • Implantação com QuickNode RPC.

O QUE É UM CONTRATO INTELIGENTE DE SERVIÇO BASEADO EM ASSINATURA?

Um contrato inteligente de serviço baseado em assinatura é um acordo digital autoexecutável que rege a prestação de um serviço aos usuários em troca de pagamentos periódicos, normalmente chamados de assinaturas. Opera em plataforma blockchain, o que garante transparência, segurança e automação do processo de assinatura.

PRINCIPAIS RECURSOS E COMPONENTES DE UM CONTRATO INTELIGENTE DE SERVIÇO BASEADO EM ASSINATURA.

  1. Acordo automatizado: o contrato inteligente é um código autoexecutável executado em uma blockchain. Contém regras e condições predefinidas que regem o serviço baseado em assinatura.
  2. Pagamentos recorrentes: facilita pagamentos regulares dos assinantes ao provedor de serviços. Esses pagamentos ocorrem em intervalos especificados (por exemplo, mensalmente, trimestralmente, anualmente), conforme descrito no contrato.
  3. Transparente e confiável: todos os termos e condições da assinatura, incluindo cronogramas de pagamento, condições de renovação e regras de acesso, estão codificados de forma transparente no contrato. Isso garante a confiança entre o provedor de serviços e os assinantes.
  4. Elimina intermediários: elimina a necessidade de intermediários ou processadores de pagamento terceirizados. Os pagamentos são tratados diretamente pelo contrato, reduzindo custos e possíveis pontos de falha.
  5. Controle de acesso: o contrato gerencia o acesso ao serviço. Somente assinantes com assinaturas ativas e atualizadas têm acesso.
  6. Gerenciamento de assinantes: ele monitora os assinantes registrados, seu status de pagamento e datas de vencimento da assinatura.
  7. Tratamento de renovação e expiração: define o processo de renovação de assinaturas assim que expirarem. Isso pode incluir renovações automáticas, notificações ou um período de carência para renovação manual.
  8. Função de administrador: normalmente, existe um administrador ou proprietário do contrato que define os termos, gerencia as assinaturas e retira taxas de assinatura. Essa função garante o bom funcionamento do serviço.
  9. Eventos e notificações: o contrato pode acionar eventos ou notificações para diversas ações, como pagamentos bem-sucedidos, renovações de assinaturas ou expirações.
  10. Mecanismo de Fallback: o contrato pode ter planos de contingência para cenários inesperados, como falhas nos pagamentos ou interrupções no serviço.
  11. Medidas de segurança: inclui salvaguardas para evitar o acesso não autorizado ou a adulteração de parâmetros contratuais.
  12. Política de reembolso e resolução de desacordo (se aplicável): o contrato pode definir condições para reembolsos e mecanismos para lidar com desacordos entre o provedor de serviços e os assinantes.

CASOS DE USO DE UM CONTRATO INTELIGENTE DE SERVIÇO BASEADO EM ASSINATURA

Esses contratos inteligentes têm uma ampla gama de potenciais casos de uso em vários setores. Vejamos alguns exemplos abaixo:

  1. Plataformas de streaming: os contratos inteligentes podem gerenciar assinaturas de serviços de streaming, como plataformas de vídeo, música ou jogos. Os usuários pagam uma taxa mensal pelo acesso ao conteúdo.
  2. Software como um serviço (SaaS): empresas que oferecem soluções de software por assinatura podem usar contratos inteligentes para automatizar o faturamento e o controle de acesso.
  3. Assinaturas de revistas e notícias: os editores podem utilizar contratos inteligentes para gerenciar assinaturas digitais de revistas, jornais ou meios de comunicação online.
  4. Assinaturas de academias: as academias de ginástica podem implementar contratos inteligentes para gerenciar as associações. Os usuários pagam uma taxa recorrente pelo acesso às instalações da academia.
  5. Serviços de armazenamento em nuvem: os provedores de soluções de armazenamento em nuvem podem automatizar renovações de assinaturas e controle de acesso usando contratos inteligentes.
  6. Comunidades baseadas em membros: comunidades ou fóruns online que exigem taxas de adesão para acesso podem empregar contratos inteligentes para lidar com assinaturas.
  7. Plataformas de e-learning: plataformas educacionais que oferecem cursos por assinatura podem usar contratos inteligentes para processamento de pagamentos e controle de acesso.
  8. Caixas de assinatura: empresas que oferecem caixas de assinatura selecionadas com produtos ou serviços podem automatizar o faturamento e a entrega usando contratos inteligentes.
  9. Utilidades e serviços: contratos inteligentes podem ser usados ​​para gerenciar serviços públicos baseados em assinatura, como internet, eletricidade ou serviços de água.
  10. Assinaturas VIP: as empresas do setor de hospedagem ou entretenimento podem usar contratos inteligentes para gerenciar assinaturas VIP com benefícios exclusivos.
  11. Serviços de telecomunicações: as empresas de telecomunicações podem empregar contratos inteligentes para faturar e gerenciar assinaturas de serviços móveis ou de internet.
  12. Aplicativos de saúde e bem-estar: aplicativos que fornecem conteúdo ou serviços premium de saúde e bem-estar por assinatura podem automatizar pagamentos usando contratos inteligentes.
  13. Licenciamento de software: empresas que oferecem licenças de software por assinatura podem utilizar contratos inteligentes para lidar com renovações e controle de acesso.
  14. Plataformas freelancers: as plataformas que conectam freelancers a clientes podem implementar contratos inteligentes para gerenciar assinaturas premium ou níveis de acesso.
  15. Serviços de consultoria: consultores que oferecem serviços baseados em assinatura podem usar contratos inteligentes para cobrança e gerenciamento de acesso de clientes.

Escrevendo um Contrato Inteligente de Serviço Baseado em Assinatura

Ei, chega de fundamentos, é hora de ir para a parte técnica!

Abaixo está um código de contrato inteligente de serviço baseado em assinatura:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

contract SubscriptionService {
    address public owner;
    uint256 public subscriptionFee;
    uint256 public interval;
    mapping(address => uint256) public subscriptionExpiry;

    event SubscriptionRenewed(address subscriber, uint256 expiryTimestamp);

    modifier onlyOwner() {
        require(msg.sender == owner, "Somente o proprietário pode chamar esta função");
        _;
    }

    constructor(uint256 _subscriptionFee, uint256 _interval) {
        owner = msg.sender;
        subscriptionFee = _subscriptionFee;
        interval = _interval;
    }

    function setSubscriptionFee(uint256 _newFee) external onlyOwner {
        subscriptionFee = _newFee;
    }

    function subscribe() external payable {
        require(msg.value >= subscriptionFee, "Pagamento insuficiente para a assinatura");

        uint256 expiryTimestamp = block.timestamp + interval;
        subscriptionExpiry[msg.sender] = expiryTimestamp;

        emit SubscriptionRenewed(msg.sender, expiryTimestamp);
    }

    function checkSubscription() external view returns (bool) {
        return block.timestamp <= subscriptionExpiry[msg.sender];
    }

    function renewSubscription() external payable {
        require(block.timestamp > subscriptionExpiry[msg.sender], "A assinatura ainda está ativa");
        require(msg.value >= subscriptionFee, "Pagamento insuficiente para a assinatura");

        uint256 expiryTimestamp = block.timestamp + interval;
        subscriptionExpiry[msg.sender] = expiryTimestamp;

        emit SubscriptionRenewed(msg.sender, expiryTimestamp);
    }

    function withdrawFunds() external onlyOwner {
        uint256 balance = address(this).balance;
        require(balance > 0, "Sem saldo para sacar");

        payable(owner).transfer(balance);
    }
}
Enter fullscreen mode Exit fullscreen mode

Uma explicação detalhada do código:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

Enter fullscreen mode Exit fullscreen mode
  • // SPDX-License-Identifier: MIT: este é um comentário especial que indica a licença sob a qual o código é lançado (licença MIT, neste caso). Permite que outros usem, modifiquem e distribuam o código com a devida atribuição.
  • pragma solidity ^0.8.0;: esta instrução Pragma especifica a versão do compilador Solidity a ser usada. Diz ao compilador para usar uma versão igual ou superior a 0.8.0. do Solidity, que é a linguagem de programação usada para escrever contratos inteligentes Ethereum.
contract SubscriptionService {
    address public owner;
    uint256 public subscriptionFee;
    uint256 public interval;
    mapping(address => uint256) public subscriptionExpiry;

    event SubscriptionRenewed(address subscriber, uint256 expiryTimestamp);

    modifier onlyOwner() {
        require(msg.sender == owner, "Somente o proprietário pode chamar esta função");
        _;
    }
Enter fullscreen mode Exit fullscreen mode
  • contract SubscriptionService { ... }: define um novo contrato inteligente denominado SubscriptionService.
  • address public owner;: declara uma variável de estado pública owner do tipo address. Ela armazenará o endereço do proprietário ou criador do contrato.
  • uint256 public subscriptionFee;: declara uma variável de estado pública subscriptionFee do tipo uint256. Representa a taxa exigida para a assinatura.
  • uint256 public interval;: declara uma variável de estado pública interval do tipo uint256. Representa a duração da assinatura em segundos.
  • mapping(address => uint256) public subscriptionExpiry;: declara uma variável de estado pública subscriptionExpiry como um mapeamento. Associa os endereços de assinantes às respectivas marcas temporais (timestamps) de expiração da assinatura.
  • event SubscriptionRenewed(address subscriber, uint256 expiryTimestamp);: é um evento que será emitido sempre que uma assinatura for renovada. Fornece informações sobre o assinante e a nova marca temporal de expiração.
  • modifier onlyOwner() { ... }: define um modificador chamado onlyOwner. Modificadores são usados ​​para alterar o comportamento das funções. Este modificador restringe o acesso às funções apenas ao proprietário (owner).
  • require(msg.sender == owner, "Somente o proprietário pode chamar esta função");: verifica se o endereço que chama a função (msg.sender) é igual ao endereço do owner. Caso contrário, gera uma exceção com a mensagem "Somente o proprietário pode chamar esta função".
  • _;: é um espaço reservado para o código real da função. Indica onde o código da função modificada será executado.
constructor(uint256 _subscriptionFee, uint256 _interval) {
owner = msg.sender;
subscriptionFee = _subscriptionFee;
interval = _interval;
}

Enter fullscreen mode Exit fullscreen mode
  • constructor(uint256 _subscriptionFee, uint256 _interval) { ... }: é a função do construtor do contrato. É executada uma vez quando o contrato é implantado. Recebe dois parâmetros: _subscriptionFee e _interval.
  • owner = msg.sender;: define a variável owner para o endereço do remetente (aquele que implanta o contrato). Estabelece-se assim o proprietário inicial do contrato.
  • subscriptionFee = _subscriptionFee;: define subscriptionFee para o valor fornecido ao implantar o contrato.
  • interval = _interval;: define o inervalo (interval) para o valor fornecido ao implantar o contrato.
function setSubscriptionFee(uint256 _newFee) external onlyOwner {
        subscriptionFee = _newFee;
    }

Enter fullscreen mode Exit fullscreen mode
  • function setSubscriptionFee(uint256 _newFee) external onlyOwner { ... }: define uma função chamada setSubscriptionFee. Permite que o proprietário atualize a taxa de assinatura.
  • require(msg.sender == owner, "Somente o proprietário pode chamar esta função");: verifica se o endereço que chama a função é o owner. Caso contrário, gera uma exceção com a mensagem "Somente o proprietário pode chamar esta função".
  • subscriptionFee = _newFee;: isso atualiza o subscriptionFee com o novo valor fornecido.
function subscribe() external payable {
        require(msg.value >= subscriptionFee, "Pagamento insuficiente para a assinatura");

        uint256 expiryTimestamp = block.timestamp + interval;
        subscriptionExpiry[msg.sender] = expiryTimestamp;

        emit SubscriptionRenewed(msg.sender, expiryTimestamp);
}

Enter fullscreen mode Exit fullscreen mode
  • function subscribe() external payable { ... }: define uma função chamada subscribe. Permite que um usuário se inscreva enviando a taxa exigida.
  • require(msg.value >= subscriptionFee, "Pagamento insuficiente para a assinatura");: verifica se o valor (Ether) enviado com a transação é maior ou igual à subscriptionFee. Caso contrário, gera uma exceção com a mensagem “Pagamento insuficiente para a assinatura”.
  • uint256 expiryTimestamp = block.timestamp + interval;: calcula a marca temporal em que a assinatura expirará. Adiciona a marca temporal atual (block.timestamp) ao interval.
  • subscriptionExpiry[msg.sender] = expiryTimestamp;: define a marca temporal de expiração para o endereço do assinante no mapeamento subscriptionExpiry.
  • emit SubscriptionRenewed(msg.sender, expiryTimestamp);: emite o evento SubscriptionRenewed, indicando que uma assinatura foi renovada. Fornece informações sobre o assinante e a nova marca temporal de expiração.
function checkSubscription() external view returns (bool) {
        return block.timestamp <= subscriptionExpiry[msg.sender];
    }

Enter fullscreen mode Exit fullscreen mode
  • function checkSubscription() external view returns (bool) { ... }: define a função chamada checkSubscription. Permite que qualquer pessoa possa verificar se sua assinatura ainda está ativa.
  • return block.timestamp &lt;= subscriptionExpiry[msg.sender];: retorna um valor booleano que indica se a marca temporal atual é menor ou igual à marca temporal de expiração da assinatura do endereço do chamador.
function renewSubscription() external payable {
        require(block.timestamp > subscriptionExpiry[msg.sender], "A assinatura ainda está ativa");
        require(msg.value >= subscriptionFee, "Pagamento insuficiente para a assinatura");

        uint256 expiryTimestamp = block.timestamp + interval;
        subscriptionExpiry[msg.sender] = expiryTimestamp;

        emit SubscriptionRenewed(msg.sender, expiryTimestamp);
    }

Enter fullscreen mode Exit fullscreen mode
  • function renewSubscription() external payable { ... }: define uma função chamada renewSubscription. Permite que um usuário renove sua assinatura enviando a taxa exigida.
  • require(block.timestamp > subscriptionExpiry[msg.sender], "A assinatura ainda está ativa");: verifica se a marca temporal atual é maior que a marca temporal de expiração da assinatura do endereço do chamador. Caso contrário, gera uma exceção com a mensagem "A assinatura ainda está ativa".
  • require(msg.value >= subscriptionFee, "Pagamento insuficiente para a assinatura");: verifica se o valor (Ether) enviado com a transação é maior ou igual à subscriptionFee. Caso contrário, gera uma exceção com a mensagem “Pagamento insuficiente para a assinatura”.
  • uint256 expiryTimestamp = block.timestamp + interval;: calcula a nova marca temporal de expiração adicionando a marca temporal atual ao interval.
  • subscriptionExpiry[msg.sender] = expiryTimestamp;: atualiza a marca temporal de expiração do endereço do assinante no mapeamento subscriptionExpiry.
  • emit SubscriptionRenewed(msg.sender, expiryTimestamp);: emite o evento SubscriptionRenewed. Fornece informações sobre o assinante e a nova marca temporal de expiração.
function withdrawFunds() external onlyOwner {
        uint256 balance = address(this).balance;
        require(balance > 0, "Sem saldo para sacar");

        payable(owner).transfer(balance);
    }
}

Enter fullscreen mode Exit fullscreen mode
  • function withdrawFunds() external onlyOwner { ... }: define uma função chamada withdrawFunds. Permite ao proprietário retirar qualquer saldo Ether armazenado no contrato.
  • uint256 balance = address(this).balance;: recupera o saldo atual (em Wei) do contrato.
  • require(balance > 0, "Sem saldo para sacar");: verifica se o saldo é maior que zero. Caso contrário, gera uma exceção com a mensagem “Sem saldo para sacar”.
  • payable(owner).transfer(balance);: transfere todo o saldo para o owner.

Este contrato inteligente fornece serviços baseados em assinatura onde os usuários podem assinar, renovar suas assinaturas e verificar o status de suas assinaturas. O proprietário pode definir e atualizar a taxa de assinatura, bem como retirar quaisquer fundos acumulados.

Vamos escrever este código em nosso REMIX IDE.

https://miro.medium.com/v2/resize:fit:720/format:webp/1*dRBhXaUHcsTdcuJYA0DhTQ.png

https://miro.medium.com/v2/resize:fit:720/format:webp/1*wuqVEhN7wbAf3Z0MgFkjsA.png

IMPLANTAÇÃO COM RPC QUICKNODE

PASSO 1.

Crie um novo nó Sepolia no QuickNode. Você terá que navegar até o painel QuickNode e clicar em “Criar” (create).

https://miro.medium.com/v2/resize:fit:720/format:webp/0*SmQsbxxGUJVKGeE8.png

Depois, certifique-se de clicar na cadeia Ethereum. Confira uma captura de tela abaixo:

https://miro.medium.com/v2/resize:fit:720/format:webp/0*Z0I8BLOYbkVli45c.png

Clique em “Sepolia”:

https://miro.medium.com/v2/resize:fit:720/format:webp/0*ZEWCJ50xwIqZxWIK.png

Em seguida, clique em “Continuar” (continue) para prosseguir. Por fim, clique em “Criar ponto de extremidade” (criar endpoint) para obter seu URL da Sepolia.

https://miro.medium.com/v2/resize:fit:720/format:webp/0*Vs2F8SEVFahwemLL.png

PASSO 2.

Clique em “Adicionar rede” (add network). Siga as instruções sobre como adicionar o URL RPC ao navegador da sua carteira.

https://miro.medium.com/v2/resize:fit:720/format:webp/0*u2NUGrk4FjHX4_np.png

Clique em “Adicionar rede manualmente” (add network manually).

https://miro.medium.com/v2/resize:fit:720/format:webp/0*QIJAjeLYfzkIL1Bm.png

PASSO 3.

Insira um nome (qualquer), já que você está usando QuickNode, você pode usar “QKN”, copie/cole seu ponto de extremidade Web3 (certifique-se de incluir “/” no final!), insira o ChainID e clique em “Salvar” (save).

Estamos usando a rede de testes Sepolia, então é aconselhável usar o ID da cadeia Sepolia, que é “11155111”.

https://miro.medium.com/v2/resize:fit:720/format:webp/0*WLxLA5t-w2P9z9Xe.png

Finalmente, você obterá o resultado abaixo.

https://miro.medium.com/v2/resize:fit:720/format:webp/0*We2J47QGr8gHe_hn.png

Perfeito! Estamos quase terminando, agora solicitamos um pouco de Eth da rede de testes Sepolia para podermos implantar nosso contrato inteligente.

PASSO 4.

Agora, para obter taxas de gás, usaremos https://faucet.quicknode.com/drip. Abaixo está o procedimento.

https://miro.medium.com/v2/resize:fit:720/format:webp/0*le5BkQGvTbhuBHnF.png

Em seguida, conecte a carteira e obtenha um pouco de Eth.

Depois de fazer isso, você obterá o resultado abaixo:

https://miro.medium.com/v2/resize:fit:720/format:webp/0*-uF25G1qNyn7yXNm.png

Com isso, estamos prontos para implantar nosso contrato inteligente de serviço baseado em assinatura.

Implantação do Código de Contrato Inteligente na Rede de Testes Sepolia

https://miro.medium.com/v2/resize:fit:720/format:webp/1*stO02323g337ebgKwMC1eA.png

Clique em “Confirmar” (confirm) para finalizar as transações.

Conclusão

Parabéns por criar com sucesso seu próprio contrato inteligente de serviço baseado em assinatura na rede Ethereum!

Assine o boletim informativo QuickNode para mais artigos e guias sobre Ethereum. Se você tiver algum comentário, sinta-se à vontade para entrar em contato conosco através do Twitter. Você sempre pode conversar conosco em nosso servidor da comunidade Discord, que conta com alguns dos desenvolvedores mais legais que você já conheceu :)

Este artigo foi escrito por Playboi.eth e traduzido por Isabela Curado Nehme. Seu original pode ser lido aqui.

Top comments (0)