Подписание и хеширование транзакций

Я просматривал EthereumJ, пытаясь понять, как работает хеширование и подпись транзакций.

Насколько я могу судить по коду, подпись создается путем подписания хэша транзакции, закодированной RLP. Однако причина, по которой я запутался, заключается в том, что хэш генерируется из значений r и s подписи вместе с остальными. Учитывая, что этих значений r и s еще не существует, как их включить?

Немного больше копаясь в коде, похоже, что генерируются два разных хэша. Один «сырой» хэш, в котором значения r и s представляют собой просто пустые массивы байтов, то есть хеш, который подписывается, а затем один фактический хеш, который включает в себя сгенерированные значения r и s.

Верно ли это понимание? Зачем беспокоиться о включении подписи в процесс подписания? Например, почему подпись просто не подписывает хэш элементов транзакции без подписи? Почему «сырой» хэш включает значения vr и s (даже если r и s пусты)?

Ответы (1)

Закодированная RLP транзакция с пустыми массивами байтов для r, s была исходным прообразом хэша. В EIP155 было добавлено значение в поле v для защиты подписей от повторных атак, что означает, что подписи в блокчейне Ethereum Classic не будут действительны для той же транзакции в блокчейне Ethereum. Таким образом, поле v служит двойной цели: защищает от повторных атак и обеспечивает восстановление открытого ключа из подписи, как описано здесь .

В EIP155 прообраз хэша был изменен и теперь включает идентификатор цепочки (предотвращает повторные атаки на другие форки/тестнеты Ethereum), а также нулевые значения (закодированные как 80 в RLP) в качестве временных значений r, s. После того, как подпись рассчитана, значения r, s из подписи вместе с битом восстановления вставляются в конечный шестнадцатеричный код транзакции, тем самым создавая подписанную транзакцию.

Мне трудно ответить, почему EIP155 меняет прообраз хэша с отсутствия полей r, s на пустые поля r, s. Спецификация не объясняет, почему было внесено это изменение .

До EIP155 подпись была:

ECDSA_secp256k1(private_key, Keccak256(RLP(nonce, gasPrice, gasLimit, To, Value, Data)))

С EIP155 подпись:

ECDSA_secp256k1(private_key, Keccak256(RLP(nonce, gasPrice, gasLimit, To, Value, Data, v, r, s))),

где r, s — RLP-кодирование списка [0x00]. Это кодируется как 0x80.

Сеть принимает оба вида подписи.

Идентификатор транзакции (TXID) рассчитывается на основе подписанной транзакции. Поэтому, если вы видите в коде значение хеш-функции, вычисляемое из чего-то, содержащего подпись, это TXID.