Етхт биржа вход: Биржа копирайтинга Etxt.ru | отзывы

web3js — декодировать входные данные транзакции

У меня есть ABI и значение ввода транзакции, и я хочу знать, какая функция была вызвана в контракте и с какими аргументами (один или несколько разных типов), предпочтительно используя geth , JSON-RPC и некоторый псевдокод, который я затем могу перевести на Ruby.

На SO есть пара похожих вопросов, но ни один из них не ответил на вопрос так, чтобы он был понятен новичку в Ethereum.

В качестве примера я использую контракт MetaCoin , сгенерированный Truffle. Я вызываю метод getBalance('0xfd46f749f9d916122fe958d7f8d5ad033b187472') и получаю ввод 0xf8b2cb4f00000000000000000000000000fd46f749f9d916 122fe958d7f8d5ad033b187472 .

трюфель (разработка) > web3.eth.getTransaction('0x5d7a91c9f068d723ac52480c0ef61b9bf3f7b52dc726046e0b47f1beaa2f44ff')
{хэш: '0x5d7a91c9f068d723ac52480c0ef61b9bf3f7b52dc726046e0b47f1beaa2f44ff',
  одноразовый номер: 5,
  блокхеш: '0xd150b520eb69а621а7218722c0de5b270c9abc499a90a81ca96340e274599c28',
  номер блока: 6,
  индекс транзакции: 0,
  от: '0xfd46f749f9d916122fe958d7f8d5ad033b187472',
  на: '0x8dec2f9cccbe718c7c51e9154f223eb226bb7942',
  значение: { [Строка: '0'] s: 1, e: 0, c: [0]},
  газ: 4712388,
  gasPrice: { [Строка: '100000000000'] s: 1, e: 11, c: [100000000000]},
  ввод: '0xf8b2cb4f0000000000000000000000000fd46f749f9d916122fe958d7f8d5ad033b187472' }
 

ABI выглядит следующим образом:

[
    {
      "константа": ложь,
      "входы": [
        {
          "имя": "адрес",
          "тип": "адрес"
        }
      ],
      "имя": "getBalanceInEth",
      "выход": [
        {
          "имя": "",
          "тип": "uint256"
        }
      ],
      «подлежит оплате»: ложь,
      "тип": "функция"
    },
    {
      "константа": ложь,
      "входы": [
        {
          "имя": "получатель",
          "тип": "адрес"
        },
        {
          "имя": "количество",
          "тип": "uint256"
        }
      ],
      "имя": "sendCoin",
      "выход": [
        {
          "имя": "достаточно",
          "тип": "логическое"
        }
      ],
      «подлежит оплате»: ложь,
      "тип": "функция"
    },
    {
      "константа": ложь,
      "входы": [
        {
          "имя": "адрес",
          "тип": "адрес"
        }
      ],
      "имя": "получить баланс",
      "выход": [
        {
          "имя": "",
          "тип": "uint256"
        }
      ],
      «подлежит оплате»: ложь,
      "тип": "функция"
    },
    {
      "входы": [],
      «подлежит оплате»: ложь,
      "тип": "конструктор"
    },
    {
      "анонимно": ложь,
      "входы": [
        {
          "индексировано": правда,
          "имя": "_от",
          "тип": "адрес"
        },
        {
          "индексировано": правда,
          "имя": "_к",
          "тип": "адрес"
        },
        {
          "индексировано": ложь,
          "имя": "_значение",
          "тип": "uint256"
        }
      ],
      "имя": "Перевод",
      "тип": "событие"
    }
  ]
 

Как я могу декодировать любой ввод, чтобы узнать, какой метод был вызван и какие аргументы были переданы?

Обновление

Добавил в логи все данные блока с полем ввода в самом низу.

 {"число"=>"0x09",
 "хэш" => "0xf543eba0c80d49beea1f934c0f0ad9f0babe272a8318312545d43e6b612e4006",
 "родительский хэш" =>
  "0xde7a61e8dd84b5e080da8e16430951f7f138347c77ed263d0093e367c9d30775",
 "одноразовый номер" => "0x0",
 "sha3Uncles"=>
  "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948а7413ф0а142фд40д49347",
 "журналыБлум"=>
  "0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000",
 "Корень транзакций"=>
"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", "государственный корень" => "0x269cfa04ca1fe73202f788397ece62c520c64d5da7225ba2af2d673a2e9892f2", "receipRoot"=> "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", "майнер"=>"0x000000000000000000000000000000000000000000000000000000000000000000000000000, "сложность"=>"0x0", "totalDifficulty"=>"0x0", "дополнительные данные"=>"0x0", "размер" => "0x03e8", "gasLimit"=>"0x47e7c4", "использованный газ"=>"0x5a3e", "отметка времени" => "0x58c83fda", "транзакции" => [{"хеш"=> "0xce1eaf03dd1dfa5898243711ebcc1dc5c6357701f5a6c19f0b1f84130cb651fa", "одноразовый номер" => "0x08", "блокхэш" => "0xf543eba0c80d49beea1f934c0f0ad9f0babe272a8318312545d43e6b612e4006", "номер_блока"=>
"0x09", "индекс транзакции"=>"0x0", "из" => "0xfd46f749f9d916122fe958d7f8d5ad033b187472", "к" => "0x8dec2f9cccbe718c7c51e9154f223eb226bb7942", "значение" => "0x0", "газ"=>"0x47e7c4", "Цена газа"=>"0x174876e800", "ввод" => "0xf8b2cb4f0000000000000000000000000fd46f749f9d916122fe958d7f8d5ad033b187472"}], "дяди"=>[]}

Декодирование входных данных транзакции Ethereum с помощью Python

Декодирование входных данных с помощью Python

Опубликовано в

·

4 мин чтения

·

24 июня 2021 г. 90 009

Если вы делаете первые шаги в качестве блокчейна Инженер, отличным местом для начала может стать создание приложения, которое декодирует транзакции, в частности входные данные. Расшифровка входных данных является ключом к пониманию того, что на самом деле имело место в транзакции. Например, взгляните на эту транзакцию ниже.

Вы можете видеть, что он содержит высокоуровневую информацию о транзакции, включая адреса туда и обратно, использованный газ, стоимость транзакции, компоненты подписи и многое другое. Но что на самом деле произошло в этой сделке? Какие токены были обменены? Чей смарт-контракт использовался? Чтобы по-настоящему понять детали, нам нужно расшифровать входных данных .

Входные данные… что это?

Прежде чем мы перейдем к коду, давайте рассмотрим входные данные и то, как они используются в блокчейне. Мы будем использовать транзакцию, показанную выше, в качестве нашего примера.

Когда мы ищем транзакцию на Etherscan, мы видим, что кто-то отправил 4. 195472736637743549 ETH на смарт-контракт SushiSwap в обмен на токена 20 BOR . Пользователь, вероятно, инициировал транзакцию в пользовательском интерфейсе SushiSwap, что привело к выполнению транзакции смарт-контрактом. Но откуда смарт-контракт знал, что делать? Как вы уже догадались — входные данные.

Входные данные описаны ethereum.org как дополнительная информация, необходимая для транзакции . Структура этой информации зависит от того, какой тип транзакции имеет место. Если транзакция представляет собой вызов сообщения (подписанный внешней учетной записью (EOA) или из смарт-контракта в EOA), входные данные содержат информацию, необходимую для правильного выполнения функции смарт-контракта. Если это транзакция создания контракта , то входные данные будут содержать байт-код контракта и любые закодированные аргументы, требуемые конструктором. Если транзакция перевод средств между двумя EOA, входные данные будут пустыми, так как дополнительная информация не требуется.

В нашем примере транзакция представляет собой вызов сообщения , поскольку мы вызываем функцию в развернутом смарт-контракте. The input data looks like this:

 0x8803dbee000000000000000000000000000000000000000000000001158e460913d000000000000000000000000000000000000000000000000000003a4837fc5242c4ec00000000000000000000000000000000000000000000000000000000000000a00000000000000000000000009a7ed54b8c2c5816c1800476f5111a1e886575020000000000000000000000000000000000000000000000000000000000000000000000000000000000060cfee3f00000000000000000000000 00000000000000000000000000000000000000000200000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2000000000000000000000 000003c9d6c1c73b31c837832c72e04d3152f051fc1a9 

Это шестнадцатеричное значение используется смарт-контрактом, чтобы определить, какую функцию ему необходимо выполнить, и какие аргументы необходимы для обеспечения выполнения функции так, как задумано пользователем SushiSwap. При декодировании вы получаете определение функции:

 swapTokensForExactTokens(uint256 amountOut, uint256 amountInMax, address[] путь, адрес до, uint256 крайний срок) 

И его аргументы:

  amountOut  : 2000000000000000000 00 
amountInMax : 4199668209374381292
путь : 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2, 0x3c9d6c1C73b 31c837832c72E04D3152f051fc1A9
to : 0x9A7eD54b8c2c5816C1800476F5111A1e88657502
крайний срок : 1624239679

Но как мы можем использовать Python для преобразования этого шестнадцатеричного ввода в обычный текст? Разберем код.

Декодирование входных данных

Мы будем использовать библиотеку Web3 для взаимодействия с узлом Ethereum. Требования по установке и началу работы см. в документации по Web3.

Наш первый шаг — получить сводку транзакций, передав хэш транзакции методу get_transaction() Web3 . Это возвращает словарь, содержащий соответствующую информацию для нашей транзакции, как показано в начале этой статьи.

Далее нам нужно получить Application Binary Interface (ABI) смарт-контракта. Это позволяет нам создать Объект контракта , который мы используем для взаимодействия со смарт-контрактом. Мы можем сделать это, вызвав Etherscan API. Вам понадобится ключ API Etherscan, и вы можете получить его бесплатно, настроив учетную запись на странице разработчика Etherscan.

Обратите внимание, что мы используем значение от до из нашей транзакции в качестве адреса смарт-контракта. Для транзакций, которые вызывают функцию смарт-контракта, адресом смарт-контракта всегда будет адрес транзакции от до .

Далее мы создадим наш объект контракта , передав адрес смарт-контракта и ABI в качестве аргументов методу contract() . Возвращаемый объект содержит множество полезных методов и свойств, которые мы можем использовать для взаимодействия с нашим смарт-контрактом.

Когда у нас есть объект Contract , мы используем метод decode_function_input() для декодирования нашего ввода.

И бац! Мы сделали это. Метод возвращает кортеж, который мы можем распаковать в два объекта.

func_obj — это экземпляр функции смарт-контракта, используемой нашей транзакцией.

 swapTokensForExactTokens(unit256,united256,address[],unit256) 

Этот объект включает в себя ABI смарт-контракта, имя функции, инструмент оценки газа и другие методы и свойства, которые мы можно использовать для создания и вызова новых транзакций.

func_params — это словарь, содержащий параметры транзакции в виде ключей и аргументы в виде значений.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *