объяснить поля вывода decoderawtransaction и интерпретацию

Я пытаюсь получить информацию о необработанной транзакции в шестнадцатеричном формате до ее трансляции. Эта команда содержит несколько элементов в формате JSON. Я хотел бы более простое объяснение для них:

txid — хэш самой транзакции

hash - хэш самой транзакции. Если транзакция не является SegWit, txid == hash, в противном случае в SegWit-транзакциях хэш транзакции другой.

версия - это очевидно, что это такое, но как следует интерпретировать?

size - размер транзакции в байтах

vsize - взвешенный размер для segwit транзакций

locktime - время блокировки данной транзакции либо по высоте блока, либо по времени unix. OP_CLTV можно определить только из сценария погашения, а не из этого поля.

vin - это подмножество включает в себя все тратящиеся входы.

  • txid - txid расходуемого ввода.
  • воут - что это?
  • scriptSig - asm / hex - это включает в себя подпись(и) и redeemScript этого конкретного ввода. Есть ли разница между asm и hex?
  • последовательность - как это можно интерпретировать? Как можно определить, заблокирован ли ввод CSV или может быть заменен за плату (RBF)?

vout — это подмножество включает в себя все выходы транзакции:

  • value - количество этого вывода.
  • n - это похоже на количество/порядок выходов?
  • scriptPubKey - скрипт или pubkeyhash вывода
  • reqSigs - как это может быть известно заранее отправителю, только имея адрес?
  • типа - как это можно знать заранее?

Дополнительный вопрос:

  • Как можно определить количество каждого входа в подмножестве vin ?
  • Как можно проверить scriptSig, например: заблокирован ли ввод CLTV или CSV? Проверяет ли redeemScript (если p2sh) значение true (например, необходимое количество доступных подписей, другие правила IF/ELSE выполнены)?

Ответы (3)

Ваш пост немного длинный, в обмене стеками мы предпочитаем шотрт, легко отвечать на вопросы - смотрите здесь: https://bitcoin.stackexchange.com/help/how-to-ask

Вероятно, у вас есть пример интерпретации JSON в качестве эталона. Откуда оно у вас? Поскольку каждый может интерпретировать необработанную транзакцию, я думаю, что лучше всего ссылаться на исходную необработанную транзакцию с сайта bitcoin.org . Это двусмысленно. Это будет выглядеть так (без SegWit, чтобы упростить работу. SegWit только по запросу :-)

VERSION
TX_IN COUNT         (how many input this tx has)
 TX_IN[0...n]
  OutPoint hash     (the previous tx where funds come from)
  OutPoint index    (the n'th TX_IN)
  Script Length     (the length of the following Script Sig)
  Script Sig        (signature)
  Sequence          (a sequence field, originally intended to disable lock-time) 
TX_OUT COUNT        (how many outputs this tx has)
 TX_OUT[0...n]
  Value             (the value in Satoshis)
  PK_Script Length  (length of the following script)
  pk_script         (the script, which defines the condition, under which the funds can be spent)
LOCKTIME            (earliest time or earliest block when that transaction may be added to the block chain)

Сборка tx перед отправкой была довольно хорошо объяснена ответом @amaclin здесь .

Как можно определить количество каждого входа в подмножестве vin?

Программное обеспечение кошелька должно будет искать значения, когда хочет потратить новый tx. Поэтому требуется ссылка на предыдущий tx, где находится v_in. Если недостаточно для текущего потраченного, то будет использоваться другой v_in или даже другой tx с его v_in (количество TX_IN будет увеличено).

Как можно проверить scriptSig, например: заблокирован ли ввод CLTV или CSV?

Я не понимаю, что вы имеете в виду под этим. Scriptsig и CLTV/CSV не связаны напрямую со scriptsig. CLTV и CSV вошли в игру благодаря BIP-68 и BIP-112. CLTV (как и время блокировки) являются абсолютными временными блокировками, с CSV мы говорим об относительных временных блокировках. Так они определяют, когда выход транзакции может быть потрачен. Возможно, стоит поискать в BIP. Здесь также много информации на форуме и в bitcointalk.

Scriptsig (как правило) проверяется с помощью хэша и открытого ключа. Блог Кена Ширрифа (ссылка внизу) очень хорошо объясняет. Scriptsig доказывает, что у вас был закрытый ключ ("вы законный владелец") для проведения этой транзакции. Приватный ключ подписывает хэш tx, за которым следует публичный ключ. Там может быть больше, но я хочу остаться в целом. Вот пример того, как вы можете проверить подпись в системной оболочке unixoide с помощью openssl (биткойн всегда использует данные в шестнадцатеричном кодировании для создания хэшей, а openssl требует ключ в формате PEM):

sig=30450221009a29101094b283ae62a6fed68603c554ca3a624b9a78d83e8065edcf97ae231b02202cbed6e796ee6f4caf30edef8f5597a08a6be265d6601ad92283990b55c038fa
pk=03F5D0FB955F95DD6BE6115CE85661DB412EC6A08ABCBFCE7DA0BA8297C6CC0EC4
hash=4eb4dccd727e81315a9ff801c205efc62635471cf8668e42c1c8aebfb51500a3
printf $( echo $hash | sed 's/[[:xdigit:]]\{2\}/\\x&/g' ) > tmp_utx_dsha256.hex
echo "MDYwEAYHKoZIzj0CAQYFK4EEAAoDIgAD9dD7lV+V3WvmEVzoVmHbQS7GoIq8v859oLqCl8bMDsQ=" > cat pubkey.pem
printf $( echo $sig | sed 's/[[:xdigit:]]\{2\}/\\x&/g' ) > tmp_sig.hex
openssl pkeyutl <tmp_utx_dsha256.hex -verify -pubin -inkey pubkey.pem -sigfile tmp_sig.hex

Проверяет ли redeemScript (если p2sh) значение true (например, необходимое количество доступных подписей, другие правила IF/ELSE выполнены)?

Redeemscript — это, по сути, хэш «чего-то». Преимущество заключается в том, что он «скрывает» то, что предназначено, когда транзакция финансирования вводится в блокчейн. Когда вы создаете транзакцию расходов, раскрываются данные вашего скрипта p2sh. Обычно используется скрипт с мультиподписью. Но вы можете поместить в него любой тип кода, который бы определял условие, при котором средства могут быть потрачены (рядом с мультиподписью, любым типом смарт-контрактов, ...). На это есть ограничения. OPCODES, которые можно использовать, объясняются здесь . В bitcoin.org также есть пояснения по p2sh.

Я узнал все это из двух дополнительных ссылок: невероятно хорошо написанной книги «Мастерство Биткойн» от Андреаса и очень хорошего объяснения транзакций Кена Ширрифа .

txid — хэш самой транзакции

Действительно. Это хэш транзакции без включенных данных свидетеля (если они есть).

hash - хэш самой транзакции. Если транзакция не является SegWit, txid == hash, в противном случае в SegWit-транзакциях хэш транзакции другой.

Действительно. Это хэш транзакции с включенными данными свидетеля (если они есть). Вычисляемая сериализация определена в BIP144 .

версия - это очевидно, что это такое, но как следует интерпретировать?

Он сообщает содержимое поля транзакции nVersion.

В настоящее время определены два номера версии транзакции:

  • 1: исходный номер версии
  • 2: определено в BIP68 . Поля транзакций с этим номером версии (или выше) интерпретируются nSequenceв соответствии с новыми правилами, указанными в BIP68.
  • Любые другие номера версий являются нестандартными (не будут передаваться обычным программным обеспечением узлов в сети), но разрешены правилами блокировки. 0 имеет то же значение, что и 1; 3 и выше имеют то же значение, что и 2.

size - размер транзакции в байтах

Действительно. Это размер сериализации транзакции.

vsize - взвешенный размер для segwit транзакций

Действительно. Это размер сериализации, при котором данные-свидетели не учитываются в 4 раза, как указано в BIP141 .

locktime - время блокировки данной транзакции либо по высоте блока, либо по времени unix. OP_CLTV можно определить только из сценария погашения, а не из этого поля.

Действительно. Он сообщает значение поля транзакции nLocktime. Это время или высота, до которой транзакция не может быть включена в блок. Так, например, транзакция с locktime700000 может быть включена только в блоки высотой 700001 или выше.

Код OP_CHECKLOCKTIMEVERIFYоперации (также OP_CLTVизвестный как определенный в BIP65 ) обеспечивает способ принудительного применения ограничений в nLocktimeполе расходной транзакции из внутренних скриптов и, таким образом, косвенно на время, когда выходные данные могут быть потрачены. Он доступен во всех конструкциях скриптов (голый, P2SH, P2WSH, ...), но будет нестандартным в голых.

vin - это подмножество включает в себя все тратящиеся входы.

Это массив, содержащий информацию обо всех входах транзакций, которые хранятся в его vinполе.

  • txid - txid расходуемого ввода.

Более конкретно, это hashзначение поля входа транзакции prevout, которое содержит txid транзакции, которая создала UTXO, расходуемый этим входом.

  • воут - что это?

Это nзначение поля ввода транзакции prevout. Он сообщает, какой индекс в массиве создающей транзакции voutтратится.

  • scriptSig - asm / hex - это включает в себя подпись(и) и redeemScript этого конкретного ввода. Есть ли разница между asm и hex?

Действительно. Шестнадцатеричное значение — это именно то, что хранится в транзакции. Значение asm представляет собой более удобочитаемую расшифровку этих данных.

  • последовательность - как это можно интерпретировать? Как можно определить, заблокирован ли ввод CSV или может быть заменен за плату (RBF)?

Это значение поля транзакции nSequence.

Современное значение имеет двоякое значение:

  • Всякий раз, когда транзакция имеет nVersion2 или выше, а nSequenceзначение меньше 2 2 , применяются правила BIP68 , которые накладывают ограничения на то, как давно должны быть потрачены выходные данные, прежде чем эта транзакция будет действительной (по высоте или времени). Код операции BIP112OP_CHECKSEQUENCEVERIFY (также известный как OP_CSV) предоставляет средства в сценарии для наложения ограничений на nSequenceзначение (и, следовательно, косвенно на относительное время, которое может быть потрачено на вывод).
  • BIP125 определяет потенциальную политику (не правило консенсуса) для узлов в отношении замены транзакций в мемпуле. В частности, он разрешает замену любой транзакции, nSequenceзначение которой не равно 0xFFFFFFF или 0xFFFFFFFE. Это относится к любому вводу транзакции с использованием относительного времени блокировки, как обсуждалось в пункте выше. Обратите внимание, что современные узлы на момент написания не полностью реализуют правила политики BIP125 , хотя и не таким образом, чтобы это описание было недействительным.

vout — это подмножество включает в себя все выходы транзакции:

Это массив, содержащий информацию обо всех выходах транзакций, которые хранятся в его voutполе.

  • value - количество этого вывода.

Действительно.

  • n - это похоже на количество/порядок выходов?

Аналог поля vout во входных данных. Когда вход тратит определенный UTXO, созданный этим выходом, он должен ссылаться на txid и nполе этой транзакции.

  • scriptPubKey - скрипт или pubkeyhash вывода

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

  • reqSigs - как это может быть известно заранее отправителю, только имея адрес?

Можно, но только для голых multisig-скриптов (где полный скрипт хранится в выводе напрямую, а не через redeemScript), которые устарели и нестандартны как написание. По этой причине поле reqSigs также устарело. Это просто сбивает с толку.

  • типа - как это можно знать заранее?

Это тип вывода . например, он может определить разницу между выводом P2PKH или P2SH. Он не может знать, что такое сценарий вывода P2SH, пока он не будет израсходован.

  • Как можно определить количество каждого входа в подмножестве vin?

Он просматривается в базе данных наборов UTXO при трате времени с использованием полей txidи , voutуказанных в выходных данных RPC. Эти два уникальных идентификатора идентифицируют выход транзакции (номер voutтранзакции, чей txid равен txid), а набор UTXO запоминает его поля amountи .scriptPubKey

  • Как можно проверить scriptSig, например: заблокирован ли ввод CLTV или CSV? Проверяет ли redeemScript (если p2sh) значение true (например, необходимое количество доступных подписей, другие правила IF/ELSE выполнены)?

Выполнение происходит примерно следующим образом:

  • Сначала scriptSigвыполняется. Окончательное состояние стека запоминается. Если это не удается, транзакция недействительна.
  • Затем scriptPubKeyвыполняется расходуемый вывод с предыдущим окончательным состоянием стека в качестве начального состояния. Это scriptPubKeyищется в базе данных UTXO, как указано выше. Итак, что это эффективно делает, так это запускает сценарий блокировки с scriptSigвходом as; если это не удается, транзакция недействительна.
  • Затем, в качестве специального шага, если он точно scriptPubKeyсоответствует шаблону BIP16 (P2SH), срабатывает дополнительное правило: последний элемент scriptSig обрабатывается как другой сценарий и выполняется со всеми элементами scriptSig, кроме последнего, в качестве входных данных.

Аналогичные правила применяются к расходам P2WSH (BIP141) и P2TR (BIP341).

С биткойн-ядром вы бы использовалиdecoderawtransaction

https://en.bitcoin.it/wiki/Raw_transactions#decoderawtransaction_.3Chex_string.3E

Пример с моим узлом

decoderawtransaction 01000000000101502c5d0d5e7e869ff1b40cc1542695fb35830355861f61932645fa1b1a149a5d0e000000171600149a1c78a507689f6f54b847ad1cef1e614ee23f1effffffff01c8f703000000000017a914691ad0b9182c753a26bed191e470b85236b67a878702483045022100817d7d87af9568c025e5dac8bc2b27bdac7181779b81ed5dc8a468f970c33124022059e09b0b5f48516b01ed2262084c8ba1a58a250b3f2e39a69b890f68237e8cb5012103a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bd00000000



{
  "txid": "1c5cb1487867459952d78624577788723f7d11d8ba39d211e524a9527d683152",
  "hash": "a660d4e8f9f9fc18866a38bac30f25ceef5ecfc8eaf640fc93004b3ea8763d9f",
  "version": 1,
  "size": 216,
  "vsize": 134,
  "weight": 534,
  "locktime": 0,
  "vin": [
    {
      "txid": "5d9a141a1bfa452693611f8655038335fb952654c10cb4f19f867e5e0d5d2c50",
      "vout": 14,
      "scriptSig": {
        "asm": "00149a1c78a507689f6f54b847ad1cef1e614ee23f1e",
        "hex": "1600149a1c78a507689f6f54b847ad1cef1e614ee23f1e"
      },
      "txinwitness": [
        "3045022100817d7d87af9568c025e5dac8bc2b27bdac7181779b81ed5dc8a468f970c33124022059e09b0b5f48516b01ed2262084c8ba1a58a250b3f2e39a69b890f68237e8cb501",
        "03a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bd"
      ],
      "sequence": 4294967295
    }
  ],
  "vout": [
    {
      "value": 0.00260040,
      "n": 0,
      "scriptPubKey": {
        "asm": "OP_HASH160 691ad0b9182c753a26bed191e470b85236b67a87 OP_EQUAL",
        "hex": "a914691ad0b9182c753a26bed191e470b85236b67a8787",
        "reqSigs": 1,
        "type": "scripthash",
        "addresses": [
          "3BGkzr6ioLszJjqX2msqXjqDAFdUVtBY2T"
        ]
      }
    }
  ]
}