Как вручную подписать транзакцию с несколькими входами и несколькими выходами?

Я разрабатываю конструктор транзакций, но столкнулся с несколькими проблемами. На некоторые из них я нашел ответ в разделе Как подписать транзакцию с несколькими входами? , а в остальном попробую объяснить:

  1. Когда у нас есть несколько входов и несколько выходов и мы пытаемся подписать каждый вход, что мы заполняем в разделе выходного значения для каждого из них: общая сумма входов транзакции или соответствующая сумма, которую имеет каждый вход, который мы подписываем, и мы распределяем между выходами?

'version': 1, 'inputs': (2) { 'output_tx_hash': 'aaaa', 'output_position': 0, 'script': the original script, like: '76a914' + hash + '88ac', 'sequence': ffffffff, }, { 'output_tx_hash': 'bbbb', 'output_position': 1, 'script': '', # Nothing 'sequence': ffffffff, } 'outputs': (2) 'value' : 100000 'script' : '76a914' + hash of btc pub key + '88ac' 'value' : 50000 'script' : '76a914' + hash of btc pub key + '88ac' 'locktime': 0

  1. В разделе script во входных данных есть "Ничего", но каково точное количество байтов - 1 байт, 4 байта или что-то еще?
  2. Существует ли пошаговое руководство или учебник по ручному созданию и подписанию транзакций, охватывающий транзакцию с несколькими входами и несколькими выходами. Я успешно отправляю транзакции в блокчейн, но только с одним входом.

Ответы (2)

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

Учитывая вашу транзакцию P2PKH с двумя входами, вот необработанная транзакция, которая должна быть подписана закрытым ключом, соответствующим первой точке выхода:

01000000
02
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
00000000
19
76a914<your-first-pkhash(160bit)>88ac
ffffffff
bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
01000000
00
ffffffff
02
a086010000000000
19
76a914<hash-of-target-btc-pubkey1(160bit)>88ac
50c3000000000000
19
76a914<hash-of-target-btc-pubkey2(160bit)>88ac
00000000
01000000

Вот необработанная транзакция, которая должна быть подписана закрытым ключом, соответствующим второй точке отказа:

01000000
02
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
00000000
00
ffffffff
bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
01000000
19
76a914<your-second-pkhash(160bit)>88ac
ffffffff
02
a086010000000000
19
76a914<hash-of-target-btc-pubkey1(160bit)>88ac
50c3000000000000
19
76a914<hash-of-target-btc-pubkey2(160bit)>88ac
00000000
01000000

И вот получившаяся подписанная транзакция:

01000000
02
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
00000000
6a
47
304<...rest-of-signature>
01
21
<your-first-pk(264bit)>
ffffffff
bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
01000000
6a
47
304<...rest-of-signature>
01
21
<your-second-pk(264bit)>
ffffffff
02
a086010000000000
19
76a914<hash-of-target-btc-pubkey1(160bit)>88ac
50c3000000000000
19
76a914<hash-of-target-btc-pubkey2(160bit)>88ac
00000000

Предположения: (1) Вы используете сжатые открытые ключи. (2) тип SIG_ALL.
Примечание. Длина подписи может варьироваться, поэтому байты, указывающие длину скрипта, могут отличаться от приведенного выше примера. Отвечая на ваш третий вопрос, здесь

есть описание

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

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

Для входных данных segwit вместо того, чтобы помещать все выходные данные в сообщение, вы сначала хешируете их все вместе. Они сериализуются, как если бы они были в транзакции, а затем хэшируются все сразу. Полученный хэш SHA256 — это то, что вы используете в сообщении. Прочитайте BIP 143 для получения дополнительной информации об этом. Поле valueв этом сообщении представляет собой значение только вывода, потраченного на этот конкретный ввод.

В разделе script во входных данных есть "Ничего", но каково точное количество байтов - 1 байт, 4 байта или что-то еще?

«Ничего» означает, что существует сценарий длины 0, поэтому это означает один байт 00. Однако ни в одном из моментов подписания транзакции вы никогда не подписываете пустой скрипт. Если да, то что-то не так.

Так, например, если у меня есть 5 входов, мне нужно подписать каждый вход отдельно, помещая sigScript для того, который мы подписываем, и один байт 00, как вы говорите, для остальных, и я повторяю этот шаг 5 раз - для каждого входа?
@DimitarVasilev Да.