Проверка подписи биткойнов и какие данные транзакции подписываются?

Учитывая транзакцию биткойнов, в которой он может выкупить свои UTXO, как я могу проверить на Java, действительно ли подпись является действительной подписью или нет. Я пытался использовать библиотеку Bouncy Castle, где я пытался воссоздать сообщение, которое подписывает закрытый ключ.

Насколько я знаю, мне нужны следующие вещи:

1. Номер версии (4 байта)
2. Количество входов (1 байт)
3. Хэш транзакции выкупаемых входных данных
4. Индекс выкупаемых выходных данных (4 байта)
5. ScriptPubKey выкупаемых выходных данных с предшествующим длина сценария
6. Порядковый номер (4 байта)
7. Количество выходов, которые мы подписываем (1 байт)
8. Общее значение вывода (8 байтов)
9. ScriptSig для вывода с добавленной длиной
10.locktime поле (4 байта)
11. тип хэш-кода (4 байта)

Я попытался получить эту информацию из данных транзакции, но когда я пытаюсь проверить подпись, это не удается. Я что-то упустил? Я хочу проверить правильность подписи. Спасибо.

Из того, что я прочитал, шаг номер 5 является временным шагом, и ScriptPubkey заменяется каким-то другим значением, но я не могу понять, каким должно быть это значение.

Ответы (1)

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

В общем, что вы делаете, так это берете транзакцию, которую хотите проверить, удаляете scriptSigs из всех входных данных и для конкретного ввода, который вы хотите, вы помещаете в scriptSig scriptPubKey (с добавлением его длины) вывода. этот вход тратит. Если вывод, который был потрачен, это P2SH, то вы ставите redeemScript вместо scriptPubKey. Затем вы помещаете тип sighash в конце модифицированной транзакции.

Получив это сообщение, вам нужно хэшировать его с помощью SHA256. Большинство криптографических библиотек берут сообщение и хэшируют его один раз. Однако в Биткойне сообщение на самом деле хешируется дважды. Таким образом, чтобы проверить подпись в биткойне с помощью криптографической библиотеки общего назначения, вам нужно сначала хешировать сообщение, а затем позволить библиотеке снова хешировать его, когда оно проверит.

Наконец, сообщение отличается для входов, которые тратят выходы Segwit. Это сообщение определено в BIP 143 .

Итак, в случае, когда у меня есть один вход, расходуемый на два выхода, как это будет работать? Скажем, у меня есть 500 BTC в одном закрытом ключе, и я отправляю 200 на адрес A, 200 на адрес B и 100 на адрес C (ради простоты мы опускаем комиссию за транзакцию). Затем какой ScriptPubkey нужно поставить в scriptSig для ввода 500 BTC. @ЭндрюЧоу
Потрясающий! Я нашел ошибку. Я понял, что кроме скриптов все остальное хранится в формате с прямым порядком байтов! Теперь это работает.