Se você já realizou uma transação no Ethereum (ou em qualquer blockchain habilitada para contratos inteligentes), então você provavelmente procurou isso em um explorador de blocos como o etherscan.io e viu esta montanha de informações:
Guia de Visão Geral de Transações
E se você tentou olhar os logs ou rastreamentos (transações internas), você pode ter visto essas páginas confusas:
Guia de registros (você tem sorte se estiverem bem decodificados assim)
Guia de rastreamentos (sim, parece um monte de bobagens)
Aprender a ler os detalhes de uma transação em exploradores de blocos será a base para toda a sua análise de dados e conhecimento do Ethereum, então vamos cobrir todas as partes e como trabalhar com elas em SQL.
Estou apenas passando por cima de como entender esses conceitos em um nível alto; se você quiser aprender a decodificá-los manualmente, então você precisará se familiarizar com comoos dados estão codificados(é o mesmo para transações/rastreios/logs) e como usarFunções bytearray/hex do Dunepara ir entre diferentes tipos.
Ao final deste guia, você será capaz de entender e navegar pelas tabelas de dados de qualquer contrato usando esta consulta de localizador de tabela de transações:
Link de consulta (Insira qualquer hash de transação, cadeia e número de bloco)
Depois de aprender os conceitos neste guia, você também deve aprender a usar o meu Painel de inicialização rápida do EVMpara começar a análise de qualquer contrato.
·
30 de dezembro de 2022
As transações são apenas a ponta do iceberg dos dados, todos os rastros e registros são invocados DEPOIS que os dados de entrada iniciais iniciam a função de nível superior. Vamos primeiro rotular todos os campos que você verá na página de transações do explorador de blocos:
Estes são os mesmos campos que você verá ao consultar "ethereum.transactions" no Dune. O item-chave a aprender a identificar aqui é se o "para" é um contrato ou não. Normalmente, os contratos serão claramente rotulados. Se for um contrato, deve haver "dados de entrada" que contenham uma chamada de função.
De todos esses conceitos, o primeiro a aprender bem é um EOA versus um endereço de contrato. Contratos são implantados por EOAs e podem ser chamados no campo 'para' de uma transação. Se você clicar em um endereço, os exploradores mostrarão no canto superior esquerdo se é um contrato ou uma conta. No dune, você pode se juntar à tabela ethereum.creation_traces para verificar se é um contrato. Observe que apenas EOAs podem ser o signatário 'de' da tx.
É importante aprender de onde vêm os dados diretamente da cadeia em comparação com os dados que o explorador/frontend adicionou por cima. Tudo na blockchain é representado como hex (às vezes chamado de binário ou bytes), então uma chamada de troca de 1inch terá essa string de dados de entrada:
Os primeiros 4 bytes (8 caracteres) são a “assinatura da função”, que é a hash keccakdo nome da função e dos tipos de entrada. O Etherscan tem um botão de "decodificar" para alguns contratos, fornecendo esta forma legível:
Como você pode ver, existem muitas variáveis empacotadas juntas naquela única sequência hexadecimal longa de antes. A maneira como elas são codificadas segue a especificação de interface binária de aplicativo (ABI) dos contratos inteligentes.
ABI's são como documentação de API para contratos inteligentes (como especificações OpenAPI), você pode ler mais sobre o detalhes técnicos aqui. A maioria dos desenvolvedores verificará se sua ABI corresponde ao contrato e fará o upload da ABI para que todos possam consultar ao decodificar. Muitos contratos podem estar relacionados a MEV/negociação, onde o desenvolvedor deseja manter as coisas como código fechado e privado - então não obtemos nenhuma decodificação deles.
Em Duna, temos tabelas decodificadas com base nos ABIs do contrato submetidopara uma tabela de contratos (ou seja, ethereum.contracts), funções e eventos são convertidos em assinaturas de bytes (ethereum.signatures) que são então correspondidos a rastros e logs para fornecer tabelas decodificadas, como uniswap_v2_ethereum.Pair_evt_Swap, que armazena todas as trocas de todos os contratos de par criados pela fábrica de pares Uniswap v2. Você pode filtrar trocas em um par específico olhando a tabela de endereços de contrato para eventos.
Na Dune, você gostaria de consultar esta tabela para esta chamada de função oneinch_ethereum.AggregationRouterV6_call_swap. Você verá que o nome desta tabela está no topo dos resultados da consulta no localizador de tabelas no início do guia.
Para as seguintes seções sobre rastreamentos e registros, estaremos usandoa mesma transação de swap agregador de 1 polegada. Este é um bom exemplo porque um roteador irá trocar tokens em vários contratos DEX, então teremos uma boa diversidade de rastros e logs para investiGate.
Vamos falar sobre os registros de eventos a seguir. Os registros podem ser emitidos em qualquer ponto de uma chamada de função. Os desenvolvedores geralmente emitem um registro no final de uma função, depois que todas as transferências/lógica forem concluídas sem erros. Vamos dar uma olhada no evento de troca uniswap v3 emitido da transação anterior:
Você verá que há um campo topic0, topic1, topic2 e dados. topic0 é semelhante à assinatura da função, exceto que é de 32 bytes em vez de apenas 4 bytes (ainda hashed da mesma maneira). Os eventos podem ter campos "indexados" para uma filtragem de dados mais rápida, que pode aparecer em topic1, topic2 ou topic3. Todos os outros campos são codificados juntos no objeto "data". Novamente, eles seguem as mesmas regras de codificação que transações e rastreamentos. O "28" é o índice do evento em todo o bloco. Às vezes, pode ser útil participar quando você quiser a primeira troca ou transferência em um tx.
Para encontrar a lógica por trás de onde e como esse evento foi emitido, precisarei mergulhar no código de solidez. Vou clicar no endereço vinculado do evento, ir para a aba contrato e pesquisar "emit swap" porque sei que todos os eventos têm "emit" antes de serem invocados no código.
Este é o contrato uniswapv3poolque é criado pela fábrica para cada par.
Eu posso ver que isso é emitido na linha 786 do contrato, como parte da função “swap”.
Ser capaz de naveGar funções e linhagem de eventos através de contratos será uma habilidade chave que você precisará adquirir para entender com precisão a linhagem dos dados que está consultando. Você não precisa aprender solidez em profundidade para naveGar esses arquivos, apenas saber como entender interfaces de contratoe quando funções/eventos são chamados (function e emit são suas palavras-chave).
Para um exemplo detalhado de investigação do código para funções e eventos, confira este detalhamento dos contratos e dados do Sudoswap.
Usando a consulta do localizador de tabela anterior, posso ver que a tabela que devo consultar para essa troca é uniswap_v3_ethereum.Pair_evt_Swap e que ela é emitida após a chamada da função swap().
Os rastreamentos podem rapidamente se tornar muito difíceis de navegar, por causa de como as chamadas aninhadas entre contratos diferentes ficam. Vamos primeiro entender os tipos de vestígios:
Você também precisará entender a coluna/índice trace_address. Este é o padrão [0,1,1,1,1] que você frequentemente vê. Imagine que seja como marcadores, onde o número de números no array indica a profundidade e a ordem das chamadas de função.
A (nulo) —o primeiro input da transação tem um trace_address de []
CALLs B (0)
CALLs C (0,0)
CHAMADAS D (1)
CHAMADAS E (1,0) CHAMADAS F (1,0,0)CHAMADAS G (1,1)
CALLs H (2)
Como você pode ver na captura de tela de nossas transações internas anteriores (traços), o etherscan não é um lugar amigável para visualizar traços. Prefiro usar o phalcon blocksec, que desembrulha a transação assim:
Isso pode parecer avassalador, mas na verdade é uma maneira super fácil de explorar todas as funções, eventos e argumentos no fluxo de uma transação. Depois de conseguir entender isso, você pode dizer com segurança que entende todos os dados em uma transação. Observe que o meu consulta do localizador de tabelaé uma cópia quase exata deste layout, fui amplamente inspirado por eles!
Observe que no Dune, decodificamos automaticamente chamadas de transação e rastreamentos da mesma função para a mesma tabela. Você pode estar se perguntando se é possível juntar facilmente eventos, rastreamentos e transações na ordem mostrada no phalcon. No Dune, você pode fazer join no hash da transação para vincular os dados em geral, mas não é possível fazer join em nenhum índice para recriar a ordem exata das interações. É uma limitação infeliz no momento que requer um indexador personalizado.
Se você entende os conceitos que expus neste guia, está pronto para se aprofundar e escrever consultas mais complexas. Navegar por transações usando várias ferramentas diferentes será uma das habilidades mais importantes que você precisará para se destacar neste espaço.
Provavelmente uso cerca de 10 exploradores diferentes todas as semanas, e o número de ferramentas é 10 vezes maior. Eu escrevo um guia anual que abrange a evolução da pilha de ferramentas de dados e para quais finalidades você deve usar cada ferramenta:
Mời người khác bỏ phiếu
Se você já realizou uma transação no Ethereum (ou em qualquer blockchain habilitada para contratos inteligentes), então você provavelmente procurou isso em um explorador de blocos como o etherscan.io e viu esta montanha de informações:
Guia de Visão Geral de Transações
E se você tentou olhar os logs ou rastreamentos (transações internas), você pode ter visto essas páginas confusas:
Guia de registros (você tem sorte se estiverem bem decodificados assim)
Guia de rastreamentos (sim, parece um monte de bobagens)
Aprender a ler os detalhes de uma transação em exploradores de blocos será a base para toda a sua análise de dados e conhecimento do Ethereum, então vamos cobrir todas as partes e como trabalhar com elas em SQL.
Estou apenas passando por cima de como entender esses conceitos em um nível alto; se você quiser aprender a decodificá-los manualmente, então você precisará se familiarizar com comoos dados estão codificados(é o mesmo para transações/rastreios/logs) e como usarFunções bytearray/hex do Dunepara ir entre diferentes tipos.
Ao final deste guia, você será capaz de entender e navegar pelas tabelas de dados de qualquer contrato usando esta consulta de localizador de tabela de transações:
Link de consulta (Insira qualquer hash de transação, cadeia e número de bloco)
Depois de aprender os conceitos neste guia, você também deve aprender a usar o meu Painel de inicialização rápida do EVMpara começar a análise de qualquer contrato.
·
30 de dezembro de 2022
As transações são apenas a ponta do iceberg dos dados, todos os rastros e registros são invocados DEPOIS que os dados de entrada iniciais iniciam a função de nível superior. Vamos primeiro rotular todos os campos que você verá na página de transações do explorador de blocos:
Estes são os mesmos campos que você verá ao consultar "ethereum.transactions" no Dune. O item-chave a aprender a identificar aqui é se o "para" é um contrato ou não. Normalmente, os contratos serão claramente rotulados. Se for um contrato, deve haver "dados de entrada" que contenham uma chamada de função.
De todos esses conceitos, o primeiro a aprender bem é um EOA versus um endereço de contrato. Contratos são implantados por EOAs e podem ser chamados no campo 'para' de uma transação. Se você clicar em um endereço, os exploradores mostrarão no canto superior esquerdo se é um contrato ou uma conta. No dune, você pode se juntar à tabela ethereum.creation_traces para verificar se é um contrato. Observe que apenas EOAs podem ser o signatário 'de' da tx.
É importante aprender de onde vêm os dados diretamente da cadeia em comparação com os dados que o explorador/frontend adicionou por cima. Tudo na blockchain é representado como hex (às vezes chamado de binário ou bytes), então uma chamada de troca de 1inch terá essa string de dados de entrada:
Os primeiros 4 bytes (8 caracteres) são a “assinatura da função”, que é a hash keccakdo nome da função e dos tipos de entrada. O Etherscan tem um botão de "decodificar" para alguns contratos, fornecendo esta forma legível:
Como você pode ver, existem muitas variáveis empacotadas juntas naquela única sequência hexadecimal longa de antes. A maneira como elas são codificadas segue a especificação de interface binária de aplicativo (ABI) dos contratos inteligentes.
ABI's são como documentação de API para contratos inteligentes (como especificações OpenAPI), você pode ler mais sobre o detalhes técnicos aqui. A maioria dos desenvolvedores verificará se sua ABI corresponde ao contrato e fará o upload da ABI para que todos possam consultar ao decodificar. Muitos contratos podem estar relacionados a MEV/negociação, onde o desenvolvedor deseja manter as coisas como código fechado e privado - então não obtemos nenhuma decodificação deles.
Em Duna, temos tabelas decodificadas com base nos ABIs do contrato submetidopara uma tabela de contratos (ou seja, ethereum.contracts), funções e eventos são convertidos em assinaturas de bytes (ethereum.signatures) que são então correspondidos a rastros e logs para fornecer tabelas decodificadas, como uniswap_v2_ethereum.Pair_evt_Swap, que armazena todas as trocas de todos os contratos de par criados pela fábrica de pares Uniswap v2. Você pode filtrar trocas em um par específico olhando a tabela de endereços de contrato para eventos.
Na Dune, você gostaria de consultar esta tabela para esta chamada de função oneinch_ethereum.AggregationRouterV6_call_swap. Você verá que o nome desta tabela está no topo dos resultados da consulta no localizador de tabelas no início do guia.
Para as seguintes seções sobre rastreamentos e registros, estaremos usandoa mesma transação de swap agregador de 1 polegada. Este é um bom exemplo porque um roteador irá trocar tokens em vários contratos DEX, então teremos uma boa diversidade de rastros e logs para investiGate.
Vamos falar sobre os registros de eventos a seguir. Os registros podem ser emitidos em qualquer ponto de uma chamada de função. Os desenvolvedores geralmente emitem um registro no final de uma função, depois que todas as transferências/lógica forem concluídas sem erros. Vamos dar uma olhada no evento de troca uniswap v3 emitido da transação anterior:
Você verá que há um campo topic0, topic1, topic2 e dados. topic0 é semelhante à assinatura da função, exceto que é de 32 bytes em vez de apenas 4 bytes (ainda hashed da mesma maneira). Os eventos podem ter campos "indexados" para uma filtragem de dados mais rápida, que pode aparecer em topic1, topic2 ou topic3. Todos os outros campos são codificados juntos no objeto "data". Novamente, eles seguem as mesmas regras de codificação que transações e rastreamentos. O "28" é o índice do evento em todo o bloco. Às vezes, pode ser útil participar quando você quiser a primeira troca ou transferência em um tx.
Para encontrar a lógica por trás de onde e como esse evento foi emitido, precisarei mergulhar no código de solidez. Vou clicar no endereço vinculado do evento, ir para a aba contrato e pesquisar "emit swap" porque sei que todos os eventos têm "emit" antes de serem invocados no código.
Este é o contrato uniswapv3poolque é criado pela fábrica para cada par.
Eu posso ver que isso é emitido na linha 786 do contrato, como parte da função “swap”.
Ser capaz de naveGar funções e linhagem de eventos através de contratos será uma habilidade chave que você precisará adquirir para entender com precisão a linhagem dos dados que está consultando. Você não precisa aprender solidez em profundidade para naveGar esses arquivos, apenas saber como entender interfaces de contratoe quando funções/eventos são chamados (function e emit são suas palavras-chave).
Para um exemplo detalhado de investigação do código para funções e eventos, confira este detalhamento dos contratos e dados do Sudoswap.
Usando a consulta do localizador de tabela anterior, posso ver que a tabela que devo consultar para essa troca é uniswap_v3_ethereum.Pair_evt_Swap e que ela é emitida após a chamada da função swap().
Os rastreamentos podem rapidamente se tornar muito difíceis de navegar, por causa de como as chamadas aninhadas entre contratos diferentes ficam. Vamos primeiro entender os tipos de vestígios:
Você também precisará entender a coluna/índice trace_address. Este é o padrão [0,1,1,1,1] que você frequentemente vê. Imagine que seja como marcadores, onde o número de números no array indica a profundidade e a ordem das chamadas de função.
A (nulo) —o primeiro input da transação tem um trace_address de []
CALLs B (0)
CALLs C (0,0)
CHAMADAS D (1)
CHAMADAS E (1,0) CHAMADAS F (1,0,0)CHAMADAS G (1,1)
CALLs H (2)
Como você pode ver na captura de tela de nossas transações internas anteriores (traços), o etherscan não é um lugar amigável para visualizar traços. Prefiro usar o phalcon blocksec, que desembrulha a transação assim:
Isso pode parecer avassalador, mas na verdade é uma maneira super fácil de explorar todas as funções, eventos e argumentos no fluxo de uma transação. Depois de conseguir entender isso, você pode dizer com segurança que entende todos os dados em uma transação. Observe que o meu consulta do localizador de tabelaé uma cópia quase exata deste layout, fui amplamente inspirado por eles!
Observe que no Dune, decodificamos automaticamente chamadas de transação e rastreamentos da mesma função para a mesma tabela. Você pode estar se perguntando se é possível juntar facilmente eventos, rastreamentos e transações na ordem mostrada no phalcon. No Dune, você pode fazer join no hash da transação para vincular os dados em geral, mas não é possível fazer join em nenhum índice para recriar a ordem exata das interações. É uma limitação infeliz no momento que requer um indexador personalizado.
Se você entende os conceitos que expus neste guia, está pronto para se aprofundar e escrever consultas mais complexas. Navegar por transações usando várias ferramentas diferentes será uma das habilidades mais importantes que você precisará para se destacar neste espaço.
Provavelmente uso cerca de 10 exploradores diferentes todas as semanas, e o número de ferramentas é 10 vezes maior. Eu escrevo um guia anual que abrange a evolução da pilha de ferramentas de dados e para quais finalidades você deve usar cada ferramenta: