Необходим пошаговый пример погашения необработанной транзакции

Я ищу, в частности, пошаговый пример транзакции отправки биткойнов, которая использует реальную транзакцию ( How To Redeem A Basic Txn , несколько лет назад, отлично описывает большинство шагов отправки необработанного txn, но не не используйте настоящий TxID ).

Я поиграл с библиотекой Python pybitcointools, библиотекой SX и выводом JSON из клиента Bitcoin Core (Bitcoin-QT, Bitcoin-cli, биткойн-демон), но еще не нашел фактического пошагового руководства с использованием необработанного вывода транзакции ( однократный ввод/вывод Bitcoin txn, т.е. не мультиподпись).

Надеюсь, награда принесет пошаговый пример транзакции (с закрытыми ключами для адреса отправки) и принесет ответ, показывающий, как это делается, и, в частности:

  • как элемент ScriptPubKey вписывается в необработанный txn
  • как элемент ScriptSig вписывается в необработанный txn
  • как подписан txn (с кодировкой DER).

РЕДАКТИРОВАТЬ: я думаю, что лучший ресурс — это биткойны Кена Ширриффа , но, опять же, нет ни одного источника в Интернете, который бы ответил на мой вопрос, не просматривая прошлые области, такие как scriptPubKey, подпись и т. д.

Когда я активирую вознаграждение, если вы можете ответить на этот вопрос, обратитесь к этому Tx , поскольку он может служить фактическим примером (т.е. я предоставлю ~ 1 доллар в BTC и закрытые ключи для 1From/1MBngSqZbMydscpzSoehjP8kznMaHAzh9y, если интересно)

РЕДАКТИРОВАТЬ 2: Блог RoyalFork: Деконструкция Txn предоставляет невероятно хороший справочник для интерактивного создания Txn.

Вы должны читать Биткойн с трудом.
Вы ищете шаг за шагом с вызовами RPC или шаг за шагом с манипулированием байтами вручную?
@NickODell - да, видел это, Ник, и ты прав, это фантастический ресурс! Проблема все еще остается, хотя даже после прочтения кода Python... Я просто не понимаю всю часть ScriptPubKey / scriptSig, и каждый ресурс, который я читал, очень непрозрачен в этой части. Я отредактирую вопрос, чтобы внести больше ясности, как только смогу назначить награду.
@StephenM347 Ищете пошаговый пример, который максимально близок к тому, как бы я создал биткойн-транзакцию с карандашом и бумагой? (аналогично: bitcoin.stackexchange.com/q/808/9382 ). Я, конечно, избегаю вызовов RPC, которые, так сказать, «делают работу».
Вас волнует, что он использует именно тот txid, который вы упомянули? Я просто думаю, что было бы проще сделать это с передатчиком, который у меня есть. Я бы не раскрывал закрытый ключ, но сделал бы известными подписи, которые он вычисляет.
@ stephenm347 это не обязательно должен быть tx. Если вы хотите сослаться на свой собственный txn, это тоже хорошо, но я настроил это, потому что выходные данные исходят от 1From, а адрес 1 МБ — это мозговой кошелек, который ссылается на буквы, такие же, как 1 МБ (поэтому закрытый ключ легко связать с адрес)
@StephenM347StephenM347 Для награды мне нужны закрытые ключи, чтобы я мог повторить процесс сам. Даже предложение Ника проверить «Биткойн трудным путем» ссылается на обмен стеками How To Redeem A Raw TX, поэтому в Интернете нет канонического ответа на этот вопрос; github.com/shirriff/bitcoin-code/blob/master/txnUtils.py
Обратите внимание, что даже если вы повторите указанный процесс, полученная подпись может не совпадать с той, что указана в инструкциях. Это связано с тем, что подписи DSA/ECDSA необходимо создавать с секретным значением (часто называемым k), а одним из методов создания секретного значения является одноразовое случайное число. Если вам нужны идеально воспроизводимые шаги, вы должны указать, что либо значение kдолжно быть предоставлено в инструкциях, либо что будет использоваться детерминированная генерация RFC6979k .

Ответы (2)

Пошаговое описание:

Мы начинаем создавать новую транзакцию, которую хешируем и подписываем.

  1. Добавьте четырехбайтное поле версии:01000000
  2. Однобайтовый вариант, указывающий количество входов:01
  3. 32-байтный хеш транзакции, из которой мы хотим выкупить выход (обратный порядок):be66e10da854e7aea9338c1f91cd489768d1d6d7189f586d7a3613f2a24d5396
  4. Четырехбайтовое поле, обозначающее выходной индекс, который мы хотим выкупить из транзакции с указанным выше хэшем (считая с нуля):00000000
  5. Теперь идет сценарий Sig. В целях подписания транзакции он временно заполняется scriptPubKey вывода, который мы хотим выкупить. Сначала мы пишем однобайтовый вариант, который обозначает длину scriptSig (0x19 = 25 байт):19
  6. Затем мы пишем фактический scriptSig (который является scriptPubKey вывода, который мы хотим выкупить): 76 a9 14 dd6cce9f255a8cc17bda8ba0373df8e861cb866e 88 ac(посмотрите на нижнюю строку на https://blockchain.info/tx/96534da2f213367a6d589f18d7d6d1689748cd911f8c33a9aee754a80de166be?show_adv=true )
  7. Затем мы записываем четырехбайтовое поле, обозначающее последовательность. В настоящее время всегда установлено значение 0xffffffff:ffffffff
  8. Далее идет однобайтовый варинт, содержащий количество выходов в нашей новой транзакции. В этом примере мы установим это значение равным 1:01
  9. Затем мы записываем 8-байтовое поле (64-битное целое число, обратный порядок байтов), содержащее сумму, которую мы хотим получить от указанного выхода. Я установлю это на общую сумму, доступную на выходе, за вычетом комиссии в размере 0,0001 BTC (128307 - 10000):23ce010000000000
  10. Затем мы начинаем записывать вывод нашей транзакции. Начнем с однобайтового варинта, обозначающего длину выходного скрипта (0x19 или 25 байт):19
  11. Затем фактический сценарий вывода: 76 a9 14 a2fd2e039a86dbcf0e1a664729e09e8007f89510 88 ac(это перевод средств обратно на адрес 1FromKBPAS8MWsk1Yv1Yiu8rJbjfVioBHc)
  12. Затем пишем четырехбайтное поле «время блокировки»:00000000
  13. И, наконец, пишем четырехбайтный «тип хеш-кода» (1 в нашем случае):01000000

ОК, результат

01000000
01
be66e10da854e7aea9338c1f91cd489768d1d6d7189f586d7a3613f2a24d5396
00000000
19 76 a9 14 dd6cce9f255a8cc17bda8ba0373df8e861cb866e 88 ac
ffffffff
01
23ce010000000000
19 76 a9 14 a2fd2e039a86dbcf0e1a664729e09e8007f89510 88 ac
00000000
01000000
  1. Теперь мы дважды хешируем всю эту структуру с помощью SHA256, что дает хэш1cde0239b55717cca8003104abc2ec2673d4f6fabea0b74351940e382e88486f

  2. Теперь мы должны создать подпись ECDSA... 1MBngSqZbMydscpzSoehjP8kznMaHAzh9yэто мозговой кошелек "mrbubbymrbubbymrbubby!" , который просто кодирует адрес, начинающийся с «MB» (что упрощает связывание 2; см. комментарий @WizardOfAussie ниже для получения сведений о происхождении фраз). Закрытый ключ в WIF:5HvofFG7K1e2aeWESm5pbCzRHtCSiZNbfLYXBvxyA57DhKHV4U3

В шестнадцатеричном формате закрытый ключ имеет вид 0ecd20654c2e2be708495853e8da35c664247040c00bd10b9b13e5e86e6a808d. В каждой криптобиблиотеке есть метод знака (ключа, дайджеста). Он вернет массив байтов. Этот массив будет иметь размер не более 72 байт и начинаться с шестнадцатеричного кода 30. Давайте представим, что подпись 3046022100cf4d7571dd47a4d47f5cb767d54d6702530a3555726b27b6ac56117f5e7808fe0221008cbb42233bb04d7f28a715cf7c938e238afde90207e9d103dd9018e12cb7180eК этой подписи мы добавляем однобайтный хеш-код типа: 01. Открытый ключ для 1MBngSqZbMydscpzSoehjP8kznMaHAzh9y:042daa93315eebbe2cb9b5c3505df4c6fb6caca8b756786098567550d4820c09db988fe9997d049d687292f815ccd6e7fb5c1b1a91137999818d17c73d0f80aef9

  1. Мы создаем окончательный scriptSig путем конкатенации: <Однобайтовый OPCODE сценария, содержащий длину подписи в кодировке DER плюс тип однобайтового хэш-кода>|< Фактическая подпись в кодировке DER плюс тип однобайтового хэш-кода>| <Однобайтовый скрипт OPCODE, содержащий длину открытого ключа>|<Фактический открытый ключ>

scriptSig будет

49 3046022100cf4d7571dd47a4d47f5cb767d54d6702530a3555726b27b6ac56117f5e7808fe0221008cbb42233bb04d7f28a715cf7c938e238afde90207e9d103dd9018e12cb7180e 01
41 042daa93315eebbe2cb9b5c3505df4c6fb6caca8b756786098567550d4820c09db988fe9997d049d687292f815ccd6e7fb5c1b1a91137999818d17c73d0f80aef9

первая строка — «push подпись, объединенная с 01», вторая строка — «push pubkey». Длина scriptSig составляет 140 байт (0x8c в шестнадцатеричном формате).

  1. Затем мы заменяем однобайтовое поле длины varint из шага 5 на длину данных из шага 16. Длина составляет 140 байтов или 0x8C байтов:8c

  2. И мы заменяем фактический scriptSig структурой данных, созданной на шаге 16.

  3. Мы заканчиваем удалением четырехбайтового типа хэш-кода, который мы добавили на шаге 13, и получаем следующий поток байтов, который является финальной транзакцией:

    01000000 01 be66e10da854e7aea9338c1f91cd489768d1d6d7189f586d7a3613f2a24d5396 00000000 8c 49 3046022100cf4d7571dd47a4d47f5cb767d54d6702530a3555726b27b6ac56117f5e7808fe0221008cbb42233bb04d7f28a715cf7c938e238afde90207e9d103dd9018e12cb7180e 01 41 042daa93315eebbe2cb9b5c3505df4c6fb6caca8b756786098567550d4820c09db988fe9997d049d687292f815ccd6e7fb5c1b1a91137999818d17c73d0f80aef9 ffffffff 01 23ce010000000000 19 76 a9 14 a2fd2e039a86dbcf0e1a664729e09e8007f89510 88 ac 00000000

Разве это не шаги, описанные в ссылке в вопросе? Я не знаю, это подходит для награды. @wizardofozzie Одна вещь, которую вы должны понимать о биткойнах, заключается в том, что тестирование транзакций отличается от любой другой компьютерной программы в истории: невозможно воспроизвести одну и ту же ситуацию дважды, как это обычно бывает при тестировании. т.е. вы никогда не сможете вернуться к повторному запуску той же самой ситуации снова.
Я не претендую на щедрость. Я только что ответил на вопрос. И да, большая часть моего ответа — чистая копипаста. Могут быть очень маленькие дополнения. Английский не мой родной язык, и мне сложно самому написать весь ответ :)
Теперь я понимаю! @amaclin, если вы хотите, чтобы закрытые ключи редактировали ваш ответ, я могу предоставить его (или я могу отредактировать ответ и дать закрытый ключ). К вашему сведению, это была кодировка DER (часть, начинающаяся с байта 0x30), которую я не мог найти в жизни. Я знал, что в массиве байтов есть открытый ключ из 130 символов, начинающийся с 0x04, но я не мог разместить первую часть. Я понимаю, что каждый раз его будут подписывать по-разному (хотелось бы надеяться!), но это именно то уточнение, которое мне было нужно. Вероятно, мне придется подождать, пока я не перестану использовать приложение для iOS, чтобы присудить награду, но спасибо вам, амаклин!
Вы не должны публиковать свои закрытые ключи. Вы даже не должны присылать мне свои ключи (мой адрес электронной почты находится в профиле). Я думаю, что мой ответ достаточно полный, никому не нужно, чтобы результатом была правильная транзакция, существующая в блокчейне.
Я ценю то, что вы имеете в виду (и потрясающий ответ!), но адреса не содержат BTC. Весь смысл этого заключался в том, чтобы получить канонический ответ, который не является тестовой сетью, регтестом или абстрактным. Поэтому я собираюсь отредактировать ваш ответ, так как я успешно подписал txn и передал его. blockchain.info/tx/…
Я добавлю ответ, описывающий процесс с использованием инструментов sx, но для тех, кто заинтересован, мозговой кошелек на 1 МБ ... это «mrbubbymrbubbymrbubby!» (без кавычек) => 1MBngSqZbMydscpzSoehjP8kznMaHAzh9y ... если вам интересно, как кричит соседка каждую ночь, чтобы назвать свою кошку. Просто так получилось, что хэш равен 1 МБ :)
Жду вашего следующего вопроса: как выкупить два выхода за один tx (как создать и подписать транзакцию с более чем одним вводом)
@amaclin Нашел эту УДИВИТЕЛЬНУЮ ссылку; этот блог невероятно хорош для визуалов вроде меня... royalforkblog.com/2014/11/20/txn-demo/…
Это круто! Однако как строится необработанная транзакция, когда имеется более одного входа/выхода?
Есть ли бип, описывающий вышеизложенное?
Это отличный пост. Спасибо. Я написал код на основе вашего отличного ответа, но мой код не работает. Не могли бы вы помочь взглянуть на bitcoin.stackexchange.com/questions/92005/… ? Большое спасибо.

Это отличный ответ от amaclin и Wizard of Ozzie. Я просто хотел бы добавить некоторые подробности о транзакции Волшебника Оззи на blockchain.info .

  1. Правильные входные данные для процесса подписи для этой транзакции:

     01000000
     01
     be66e10da854e7aea9338c1f91cd489768d1d6d7189f586d7a3613f2a24d5396
     00000000
     19 76 a9 14 dd6cce9f255a8cc17bda8ba0373df8e861cb866e 88 ac
     ffffffff
     01
     23ce010000000000
     19 76 a9 14 2bc89c2702e0e618db7d59eb5ce2f0f147b40754 88 ac
     00000000
     01000000
    
  2. Хэш с двойным SHA256 вычисляется bxкак

     d304448dff517bcf677cd36f3491e9ef2ccfdf40fb63af5782d9b768640af130
    

но это написано в «обратном» порядке по какой-то особой исторической причине (я слышал, что это должно было быть совместимо с M * soft CRAPi). Поэтому при использовании этого с sign(key, digest)наиболее разумными криптографическими инструментами вам может потребоваться изменить хеш-значение на «правильный» порядок дляSHA256(SHA256(m))

30f10a6468b7d98257af63fb40dfcf2cefe991346fd37c67cf7b51ff8d4404d3
  1. Вышеупомянутые входные данные действительно будут проверяться на соответствие подписи, указанной в фактической транзакции блокчейна.

      3045022100da43201760bda697222002f56266bf65023fef2094519e13077f777baed553b102205ce35d05eabda58cd50a67977a65706347cc25ef43153e309ff210a134722e9e
    

используя данный открытый ключ

042daa93315eebbe2cb9b5c3505df4c6fb6caca8b756786098567550d4820c09db988fe9997d049d687292f815ccd6e7fb5c1b1a91137999818d17c73d0f80aef9
  1. Чтобы сгенерировать воспроизводимую подпись для тех же данных, следующая подпись была сделана детерминированным методом RFC6979 .

     30450220587ce0cf0252e2db3a7c3c91b355aa8f3385e128227cd8727c5f7777877ad772022100edc508b7c14891ed15ab38c687019d7ebaf5c12908cf21a83e8ae57e8c47e95c
    

используя соответствующий закрытый ключ, предоставленный Wizard of Ozzie

0ecd20654c2e2be708495853e8da35c664247040c00bd10b9b13e5e86e6a808d

Эта подпись также проверяет указанные данные с использованием открытого ключа и должна быть воспроизводимой.