foto por Shubham Dhage em Unsplash
Metatransações, também conhecidas como transações “sem gas”, são uma forma de permitir que os usuários interajam com um contrato inteligente sem ter que pagar pelas próprias taxas de gas. Isso pode ser especialmente útil para aplicativos que exigem que os usuários façam transações frequentes ou pequenas, pois o custo das taxas de gas pode aumentar rapidamente. Nesta postagem do blog, discutiremos como começar a implementar metatransações sem gas no Solidity, a linguagem de programação usada para escrever contratos inteligentes na blockchain Ethereum.
O que são metatransações?
Na rede Ethereum, toda vez que um usuário deseja interagir com um contrato inteligente, ele deve pagar uma taxa (na forma de gas) à rede para executar a transação. Essa taxa é necessária para incentivar os mineradores a incluir a transação na blockchain e garantir que a rede permaneça descentralizada e segura.
No entanto, esse modelo pode ser limitante para aplicativos que exigem que os usuários façam transações frequentes ou pequenas, pois o custo das taxas de gas pode aumentar rapidamente e se tornar uma barreira à entrada dos usuários. As metatransações fornecem uma maneira de contornar isso, permitindo que os usuários interajam com um contrato inteligente sem ter que pagar pelas próprias taxas de gas.
Em uma metatransação, a transação do usuário é realmente executada por outra conta que paga as taxas de gas em seu nome. Essa conta é conhecida como “relayer” (retransmissor) e pode ser um contrato ou uma conta Ethereum comum. O retransmissor recebe a transação do usuário, a assina com sua própria chave privada e a envia à rede para ser minerada. A transação do usuário é essencialmente envolvida em uma segunda transação que paga as taxas de gas, permitindo que o usuário interaja com o contrato sem ter que pagar pelo gas.
foto por toro
Implementando metatransações sem gas em Solidity
Para implementar metatransações sem gas em um contrato inteligente do Solidity, precisamos fazer o seguinte:
- Crie uma função que permita ao retransmissor executar transações em nome do usuário.
- Verifique se o retransmissor está autorizado a executar transações em nome do usuário.
- Verifique a assinatura da transação do usuário para garantir que seja autêntica.
- Execute a transação do usuário e pague as taxas de gas usando a conta do retransmissor.
Vamos passar por cada uma dessas etapas com mais detalhes.
1. Crie uma função para o retransmissor executar transações
Primeiro, precisamos criar uma função em nosso contrato inteligente que permita ao retransmissor executar transações em nome do usuário. Esta função deve receber os seguintes argumentos:
-
_user
: O endereço do usuário que deseja executar a transação. -
_data
: Os dados da transação do usuário, codificados como uma matriz de bytes. Isso normalmente será a assinatura da função e os parâmetros da função que o usuário deseja chamar, codificados usando a funçãoabi.encode().
-
_signature
: A assinatura da transação do usuário, gerada através da funçãoeth_signTypedData()
.
Aqui está um exemplo de como esta função pode aparecer no Solidity:
function execute(address _user, bytes _data, bytes _signature) public {
// TODO: Adicionar código para verificar o retransmissor e a assinatura
// TODO: Adicionar código para executar a transação do usuário
}
2. Verifique se o retransmissor está autorizado
Em seguida, precisamos verificar se o retransmissor está autorizado a executar transações em nome do usuário. Isso é importante para evitar que agentes mal-intencionados enviem transações arbitrárias em nome de outros usuários.
Uma maneira de fazer isso é fazer com que o usuário autorize explicitamente o retransmissor a executar transações em seu nome. Isso pode ser feito adicionando um mapeamento no contrato inteligente que armazena os retransmissores autorizados para cada usuário. A função execute()
pode verificar esse mapeamento para confirmar se o chamador está autorizado a executar transações em nome do usuário.
Aqui está um exemplo de como esse mapeamento e verificação podem aparecer no Solidity:
mapping(address => address[]) public authorizedRelayers;
function execute(address _user, bytes _data, bytes _signature) public {
// Verifique se o chamador está autorizado a executar transações em nome do usuário
require(authorizedRelayers[_user].contains(msg.sender), "retransmissor não autorizado");
// TODO: Adicionar código para verificar a assinatura
// TODO: Adicionar código para executar a transação do usuário
}
Neste exemplo, o mapeamento authorisedRelayers
é usado para armazenar uma matriz de retransmissores autorizados para cada usuário. A função execute()
então verifica se o responsável pela chamada (msg.sender
) está no array de retransmissores autorizados para o usuário antes de prosseguir.
3. Verifique a assinatura
Em seguida, precisamos verificar a assinatura da transação do usuário para garantir que ela seja autêntica. Isso é importante para evitar que agentes mal-intencionados enviem transações que não foram realmente assinadas pelo usuário.
Para verificar a assinatura, podemos utilizar a função ecrecover
(), que recebe como entrada a assinatura, os dados da transação e o ID da cadeia e retorna o endereço que assinou a transação. Podemos então comparar esse endereço com o argumento _user
passado para a função execute()
para garantir que eles correspondam.
Aqui está um exemplo de como essa verificação de assinatura pode parecer no Solidity:
function execute(address _user, bytes _data, bytes _signature) public {
// Verifica se o chamador está autorizado a executar transações em nome do usuário
require(authorizedRelayers[_user].contains(msg.sender), "Retransmissor não autorizado");
// Verifica a assinatura
bytes32 hash = keccak256(abi.encodePacked(chainId, _data));
address signer = ecrecover(hash, sig.v, sig.r, sig.s);
require(signer == _user, "Assinatura inválida");
// TODO: Adicionar o código para executar a transação do usuário
}
Neste exemplo, a função ecrecover()
é usada para recuperar o endereço que assinou a transação usando a assinatura e os dados fornecidos. O endereço recuperado é então comparado com o argumento _user
passado para a função execute()
para garantir que eles se correspondam.
4. Execute a transação do usuário
Finalmente, precisamos executar a transação do usuário e pagar as taxas de gas usando a conta do retransmissor. Para fazer isso, podemos usar a funçãodelegatecall()
, que nos permite chamar a função de outro contrato com o chamador e os argumentos do contrato atual.
Aqui está um exemplo de como isso pode parecer no Solidity:
function execute(address _user, bytes _data, bytes _signature) public {
// Verifica se o chamador está autorizado a executar transações em nome do usuário
require(authorizedRelayers[_user].contains(msg.sender), "Retransmissor não autorizado");
// Verifica a assinatura
bytes32 hash = keccak256(abi.encodePacked(chainId, _data));
address signer = ecrecover(hash, sig.v, sig.r, sig.s);
require(signer == _user, "Assinatura inválida");
// Executa a transação do usuário
// A conta do retransmissor é usada para pagar as taxas de gas
delegadocall(_data);
}
Neste exemplo, a função delegatecall()
é usada para executar a transação do usuário, usando a conta do retransmissor para pagar as taxas de gas. O argumento _data
, que contém a assinatura da função e os parâmetros da transação do usuário, é passado para a função delegatecall()
como o contrato e os argumentos a serem chamados.
Conclusão
Nesta postagem do blog, discutimos como implementar metatransações sem gas na Solidity, a linguagem de programação usada para escrever contratos inteligentes na blockchain Ethereum. Percorremos as etapas envolvidas na criação de uma função que permite que um retransmissor execute transações em nome do usuário, verificando se o retransmissor está autorizado, se a assinatura é autêntica e executando a transação do usuário enquanto paga as taxas de gas usando a conta do retransmissor .
As metatransações podem ser uma ferramenta útil para aplicativos que exigem que os usuários façam transações frequentes ou pequenas, pois permitem que os usuários interajam com um contrato inteligente sem ter que pagar pelas próprias taxas de gas. Seguindo as etapas descritas nesta postagem do blog, você pode implementar metatransações sem gas em seus próprios contratos inteligentes do Solidity.
OBSERVAÇÃO: esta postagem de blog foi criada pelo OpenAI GPT-3, um grande modelo de linguagem treinado pelo OpenAI. Embora o conteúdo deste post possa ser informativo e interessante, é importante ter em mente que ele não foi escrito por um ser humano. Como resultado, as informações fornecidas podem não ser 100% precisas e não devem ser tomadas como uma fonte definitiva de verdade. É sempre uma boa ideia fazer sua própria pesquisa e verificar qualquer informação que você leia na internet antes de tomar qualquer decisão importante com base nela. Obrigado por ler!
Este artigo foi publicado por Evangelos Pappas e traduzido por Diogo Jorge. O artigo original pode ser encontrado aqui.
Latest comments (0)