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

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

Итак, мой вопрос: как именно рассчитывается хэш, который должен быть подписан для каждого ввода?

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

Это правильно? Например, мы хотим провести ввод aaaa:0 и ввод bbbb:1 и отправить их на какой-то адрес:

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

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

И чтобы вычислить хэш, который должен подписать второй ввод:

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

Мы сериализуем их, добавляем к ним 01000000 (SIGHASH_ALL), удваиваем это sha256, подписываем и добавляем 01. Таким образом мы получаем две подписи, которые мы будем использовать на каждом входе соответственно. Мое приложение делает именно это и не работает. Что мне не хватает?

Возможно, взгляните на python-bitcoinlib .
Точная процедура описана в этом вопросе: bitcoin.stackexchange.com/questions/3374/…
Эта процедура показывает, как подписать транзакцию только с одним входом. Это ответ, который я использовал, чтобы узнать, как подписать 1 вход, и я добился этого, но с двумя или более входами я просто не могу заставить его работать, и в этом ответе не сказано, как это должно быть сделано.

Ответы (3)

Я нашел способ сделать это, так что, если кому интересно, вот как это сделать:

Когда у вас более 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': (1)
    'value' : 100000
    'script' : '76a914' + hash of btc pub key + '88ac'
'locktime': 0

И второй хэш:

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

Надеюсь, это поможет кому-нибудь.

Чувак, я исследовал это весь чертов день. Хотел бы я увидеть это пять часов назад. Спасибо большое.
Такой же! Я не мог быть более счастливым, чтобы найти это.
Итак, что вы делаете с двумя хэшами?

Это сработало и для меня.

Вы просто должны

1) Составьте signable для первого ввода со строкой нулевой длины в качестве сценария для всех входов, кроме подписанного.

2) Подпишите первый ввод с помощью кодировки подписанного знака der 1.

3) Иметь одну и ту же операцию на каждом входе

Да, это работает, просто будьте осторожны, когда он говорит

'script': '' # Nothing

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