Transações
Última edição: @rafarocha(opens in a new tab), 16 de julho de 2024
Transações são instruções assinadas criptograficamente de contas. Uma conta iniciará uma transação para atualizar o estado da rede Ethereum. A transação mais simples é transferir ETH de uma conta para outra.
Pré-Requisitos
Mas para ajudá-lo a entender melhor esta página, recomendamos que você primeiro leia Contas, Transaçõese nossa introdução ao Ethereum.
O que é uma transação?
Uma transação Ethereum refere-se a uma ação iniciada por uma conta de propriedade externa, ou seja, uma conta gerenciada por um ser humano, não um contrato. Por exemplo, se Bob enviar a Alice 1 ETH, a conta de Bob deverá ser debitada e a de Alice deverá ser creditada. Esta ação de mudança de estado ocorre no âmbito de uma transação.
Diagrama adaptado de Ethereum EVM ilustrado(opens in a new tab)
Transações que alteram o estado da EVM precisam ser transmitidas para toda a rede. Qualquer nó pode transmitir uma solicitação para que uma transação seja executada na EVM; depois que isso acontecer, um validador executará a transação e propagará a mudança de estado resultante para o restante da rede.
As transações exigem uma taxa e devem ser incluídas em um bloco validado. Para tornar esta visão geral mais simples, cobriremos as taxas de gás e validação em outro lugar.
Uma transação enviada inclui as seguintes informações:
from
: o endereço do remetente que assinará a transação. Ela será uma conta de propriedade externa, pois as contas de contrato não podem enviar transações.para
: o endereço de recebimento (se for uma conta de propriedade externa, a transação transferirá o valor. Se for uma conta de contrato, a transação executará o código do contrato)signature
: o identificador do remetente. Ele é gerado quando a chave privada do remetente assina a transação e confirma que o remetente autorizou essa transação.nonce
: um contador de incremento sequencial que indica o número da transação a partir da conta.value
: a quantidade de ETH a transferir do remetente para o destinatário (denominado em WEI, onde 1ETH equivale a 1e+18wei).input data
– campo opcional para incluir um dado arbitráriogasLimit
: a quantidade máxima de gás que pode ser consumida pela transação. A EVM especifica as unidades de gás necessárias para cada etapa computacionalmaxPriorityFeePerGas
: o preço máximo do gás consumido a ser incluído como gorjeta para o validador.maxFeePerGas
: a taxa máxima por unidade de gás disposta a ser paga pela transação (inclusive debaseFeePerGas
emaxPriorityFeePerGas
)
Gás é uma referência ao cálculo necessário para processar a transação por um validador. Os usuários têm que pagar uma taxa por este cálculo. O gasLimit
e o maxPriorityFeePerGas
determinam a taxa máxima de transação paga ao validador. Mais sobre gás.
O objeto da transação ficará um pouco assim:
1{2 from: "0xEA674fdDe714fd979de3EdF0F56AA9716B898ec8",3 to: "0xac03bb73b6a9e108530aff4df5077c2b3d481e5a",4 gasLimit: "21000",5 maxFeePerGas: "300",6 maxPriorityFeePerGas: "10",7 nonce: "0",8 value: "10000000000"9}Exibir tudoCopiar
Mas um objeto de transação deve ser assinado usando a chave privada do remetente. Isso prova que a transação só poderia ter vindo do remetente e não foi enviada fraudulentamente.
Um cliente Ethereum como o Geth irá lidar com este processo de assinatura.
Exemplo de chamada JSON-RPC:
1{2 "id": 2,3 "jsonrpc": "2.0",4 "method": "account_signTransaction",5 "params": [6 {7 "from": "0x1923f626bb8dc025849e00f99c25fe2b2f7fb0db",8 "gas": "0x55555",9 "maxFeePerGas": "0x1234",10 "maxPriorityFeePerGas": "0x1234",11 "input": "0xabcd",12 "nonce": "0x0",13 "to": "0x07a565b7ed7d7a678680a4c162885bedbb695fe0",14 "value": "0x1234"15 }16 ]17}Exibir tudoCopiar
Exemplo de resposta:
1{2 "jsonrpc": "2.0",3 "id": 2,4 "result": {5 "raw": "0xf88380018203339407a565b7ed7d7a678680a4c162885bedbb695fe080a44401a6e4000000000000000000000000000000000000000000000000000000000000001226a0223a7c9bcf5531c99be5ea7082183816eb20cfe0bbc322e97cc5c7f71ab8b20ea02aadee6b34b45bb15bc42d9c09de4a6754e7000908da72d48cc7704971491663",6 "tx": {7 "nonce": "0x0",8 "maxFeePerGas": "0x1234",9 "maxPriorityFeePerGas": "0x1234",10 "gas": "0x55555",11 "to": "0x07a565b7ed7d7a678680a4c162885bedbb695fe0",12 "value": "0x1234",13 "input": "0xabcd",14 "v": "0x26",15 "r": "0x223a7c9bcf5531c99be5ea7082183816eb20cfe0bbc322e97cc5c7f71ab8b20e",16 "s": "0x2aadee6b34b45bb15bc42d9c09de4a6754e7000908da72d48cc7704971491663",17 "hash": "0xeba2df809e7a612a0a0d444ccfa5c839624bdc00dd29e3340d46df3870f8a30e"18 }19 }20}Exibir tudoCopiar
- o
raw
é a transação assinada no Prefixo de Tamanho Recursivo (RLP) na forma codificada tx
é a transação assinada no formato JSON
Com o hash da assinatura, a transação pode ser provada criptograficamente de que veio do remetente e enviada para a rede.
O campo de dados
A grande maioria das transações acessa um contrato de uma conta de propriedade externa. A maioria dos contratos é escrita em Solidity e interpreta seus campos de dados de acordo com a .
Os primeiros quatro bytes especificam qual função chamar, usando o hash do nome e dos argumentos da função. Às vezes, você pode identificar a função do seletor usando este banco de dados(opens in a new tab).
O restante dos dados da chamada são os argumentos, codificado conforme especificado nas especificações ABI(opens in a new tab).
Por exemplo, vejamos esta transação(opens in a new tab). Use Clique para ver mais para conferir os dados de chamada.
O seletor de função é 0xa9059cbb
. Existem várias funções conhecidas com esta assinatura(opens in a new tab). Nesse caso, o código-fonte do contrato(opens in a new tab) foi carregado para o Etherscan, então sabemos que a função é transfer(address, uint256)
.
O resto dos dados é:
10000000000000000000000004f6742badb049791cd9a37ea913f2bac38d012792000000000000000000000000000000000000000000000000000000003b0559f4
De acordo com as especificações da ABI, valores inteiros (como endereços, que são inteiros de 20 bytes) aparecem na ABI como palavras de 32 bytes, preenchidos com zeros na frente. Portanto, sabemos que o endereço para
é 4f6742badb049791cd9a37ea913f2bac38d01279
(opens in a new tab). O valor
é 0x3b0559f4 = 990206452.
Tipos de transações
No Ethereum existem alguns tipos diferentes de transações:
- Transações regulares: uma transação de uma conta para outra.
- Transações de implantação do contrato: uma transação sem um endereço 'para', onde o campo de dados é usado para o código do contrato.
- Execução de um contrato: uma transação que interage com um contrato inteligente implantado. Nesse caso, o endereço "para" é o endereço do contrato inteligente.
Sobre gás
Como mencionado, as transações custam gás para serem executadas. Transações de transferência simples requerem 21.000 unidades de gás.
Então para Bob enviar a Alice 1 ETH para baseFeePerGas
de 190 gwei e maxPriorityFeePerGas
de 10 gwei, Bob precisará pagar a seguinte taxa:
1(190 + 10) * 21000 = 4.200.000 gwei2--ou--30,0042 ETH
A conta de Bob será debitada -1,0042 ETH (1 ETH para Alice + 0,0042 ETH em taxas de gás)
A conta de Alice será creditada +1,0 ETH
A taxa base queimará -0,00399 ETH
O validador mantém a gorjeta de +0,000210 ETH
Diagrama adaptado do Ethereum EVM ilustrado(opens in a new tab)
Qualquer gás não usado em uma transação é reembolsado para a conta do usuário.
Interações de contratos inteligentes
Gás é necessário para qualquer transação que envolva um contrato inteligente.
Contratos inteligentes também podem conter funções conhecidas como visões
(opens in a new tab) ou puras
(opens in a new tab), as quais não alteram o estado do contrato. Dessa maneira, nenhum gás é necessário ao chamar essas funções de um EOA. A chamada RPC subjacente para esse cenário é eth_call
Diferentemente de quando acessadas usando eth_call
, essas funções de visualização
ou puras "
também são comumente chamadas internamente (ou seja, a partir do próprio contrato ou de outro contrato), o que custa gás.
Ciclo de vida de transação
Quando uma transação é enviada, acontece o seguinte:
- Um hash de transação é gerado criptograficamente:
0x97d99bc7729211111a21b12c933c949d4f31684f1d6954ff477d0477538ff017
- A transação é então transmitida para a rede e adicionada a um pool de transações que compreende todas as outras transações de rede pendentes.
- Um validador deve escolher sua transação e incluí-la em um bloco para verificar a transação e considerá-la "bem-sucedida".
- Com o passar do tempo, o bloco que contém sua transação será atualizado para "justificado" e depois "finalizado". Essas atualizações tornam muito mais certo de que sua transação foi bem-sucedida e nunca será alterada. Uma vez que um bloco é “finalizado”, ele só poderá ser alterado por um ataque na rede que custe muitos bilhões de dólares.
Uma demonstração visual
Assista Austin mostrar as transações, gás e mineração.
Envelope de transação digitado
O Ethereum originalmente tinha um formato para transações. Cada transação possuía um emissor, custo de "queima", parâmetro de "queima", endereçamentos, valores, dados, v, r, e s. Esses campos são codificados por RLP, podendo se parecer com isto:
RLP ([emissor, taxa de "queima", parâmetros de "queima", destino, valor, dados, v, r, s])
O Ethereum evoluiu para apoiar vários tipos de transações, permitindo que novos recursos, como listas de acesso e EIP-1559(opens in a new tab) sejam implementados sem que isso afete os formatos de transação herdados.
EIP-2718(opens in a new tab) é o que permite esse comportamento. Transações são interpretadas como:
TransactionType || TransactionPayload
Onde os campos são definidos como:
TransactionType
: um número entre 0 e 0x7f, para um total de 128 tipos de transações possíveis.TransactionPayload
: um array de bytes arbitrário definido pelo tipo de transação.
Baseado no valor do TransactionType
, a transação pode ser classificada como
Transações do tipo 0 (legado): O formato de transação original usado desde o lançamento do Ethereum. Eles não incluem recursos do EIP-1559(opens in a new tab), como cálculos dinâmicos de taxas de gás ou listas de acesso para contratos inteligentes. As transações legadas não têm um prefixo específico que indique seu tipo em sua forma serializada, começando com o byte
0xf8
ao usar a codificação Prefixo de comprimento recursivo (RLP, na sigla em inglês). O valor TransactionType para essas transações é0x0
.Transações do tipo 1: Introduzidas na EIP-2930(opens in a new tab) como parte da Melhoria de Berlim do Ethereum, essas transações incluem um parâmetro
accessList
. Essa lista especifica endereços e chaves de armazenamento que a transação espera acessar, ajudando a reduzir potencialmente os custos de gás para transações complexas que envolvem contratos inteligentes. As alterações de mercado da taxa EIP-1559 não estão incluídas nas transações do Tipo 1. As transações do tipo 1 também incluem um parâmetroyParity
, que pode ser0x0
ou0x1
, indicando a paridade do valor y da assinatura secp256k1. Elas começam com o byte0x01
, e seu valor TransactionType é0x1
.Transações do Tipo 2, comumente conhecidas como transações EIP-1559, são transações introduzidas no EIP-1559(opens in a new tab), na Melhoria Londres do Ethereum. Elas se tornaram o tipo de transação padrão na rede Ethereum. Essas transações introduzem um novo mecanismo de mercado de taxas que melhora a previsibilidade ao separar a taxa de transação em uma taxa base e uma taxa de prioridade. Elas começam com o byte
0x02
e incluem campos comomaxPriorityFeePerGas
emaxFeePerGas
. As transações do Tipo 2 agora são o padrão devido à sua flexibilidade e eficiência, especialmente preferidas durante períodos de alta congestão na rede por sua capacidade de ajudar os usuários a gerenciar as taxas de transação de forma mais previsível. O valor TransactionType para essas transações é0x2
.
Leitura adicional
Conhece um recurso da comunidade que o ajudou? Edite esta página e adicione-a!