Насколько различается вес входных данных с мультиподписью 2 из 3 для P2SH и P2SH-P2WSH?

Я пытаюсь рассчитать вес входных данных P2SH-P2WSH с мультиподписью 2 из 3. Я нашел связанный с этим вопрос Предсказать размер транзакции с несколькими подписями , который я рассчитал m=2, n=3здесь:

pubkeySize=33
sigSize=72

SizeOfRedeemScript = 1+n*(1+pubkeySize)+1+1
// 2-of-3: SizeOfRedeemScript = 1+3*(1+33)+1+1 = 105

SizeOfScriptSig = 1+m*(1+sigSize)+SizeOfPushDataFor(RedeemScript)+SizeOfRedeemScript
// 2-of-3: SizeOfScriptSig = 1+2*(1+72)+2+105 = 1 + 146 + 2 + 105 = 254

sizeOf(input) = 32+4+SizeOfCsuintFor(SizeOfScriptSig) + SizeOfScriptSig + 4
// 2-of-3: sizeOf(input) = 32+4+3+254+4 = 297

Размер ввода 2-из-3 в P2SH составляет от 293 до 297 байтов 1 . Таким образом, это будет соответствовать до 297*4 bytes = 1188 wu.

Как рассчитать соответствующий вес для входных данных P2SH-P2WSH с мультиподписью 2 из 3?


1 Обратите внимание, что если обе подписи имеют размер 71 байт, то scriptSig составляет 252 байта , что в качестве длины может быть закодировано в 1 байт , но в худшем случае обе подписи составляют 72 байта, а длина scriptSig требует 3 байта.

Ответы (2)

Чтобы рассчитать вес блока, вам нужно знать размер в байтах данных, не являющихся свидетелями, и размер в байтах данных-свидетелей.

С вводом P2SH-P2WSH ваш scriptSig всегда будет 36 байт. Это делает размер входных данных в байтах равным 36 + 36 + 4 = 76. Свидетели содержат ваши подписи и сценарии, поэтому свидетелем для этого ввода будет 1+m*(1 + sigSize) + SizeOfVarIntFor(RedeemScript) + SizeOfRedeemScript. Таким образом, для ввода мультисиг 2 из 3 у вас будет 1 + 2*(1 + 72) + 2 + 105 = 254размер в байтах вашего свидетеля.

Формула расчета веса блока такова base size * 3 + total size. Базовый размер — это размер всех данных, не являющихся свидетелями, поэтому ваш базовый размер составляет 76 байт. Общий размер — это размер всех данных, включая свидетелей, поэтому ваш общий размер будет равен 76 + 254 = 330. Подставив это в формулу, получим 76 * 3 + 330 = 558. Таким образом, вес мультиподписи P2SH-P2WSH 2-из-3 составляет 558.

* Обратите внимание, что SizeOfVarIntFor(RedeemScript)на самом деле это два байта, потому что вам нужно использовать OP_PUSHDATA1, поскольку длина сценария погашения превышает 75 байт.

Если бы это было два байта, потому SizeOfVarIntFor(RedeemScript)что redeemscript длиннее 75 байт, не будет ли то же самое относиться к 251? SizeOfVarIntFor(SizeOfScriptSig)SizeOfScriptSig
@Murch Нет. Есть два способа представления размера вещей в транзакциях. Внутри самого скрипта мы фактически используем коды операций pushdata. Нам нужно два байта для скриптов длиннее 75 байт, потому что тогда нам нужно использовать код операции OP_PUSHDATA1 перед байтом размера. Однако для размеров вещей вне сценариев, таких как SizeOfScriptSig, мы используем компактные целые числа без знака. csuint требуется только дополнительный байт поверх самого числа, когда самому числу требуется более 1 байта. Посмотреть, как работает csuint, можно здесь: bitcoin.org/en/…

Различия между P2SH, P2SH-P2WSH и P2WSH заключаются в следующем:

  • P2SH: у scriptPubKey есть программа P2SH. scriptSig предоставляет соответствующие аргументы сценария и сценарий погашения для выполнения программы P2SH.
  • P2SH-P2WSH: в scriptPubKey есть программа P2SH. scriptSig имеет программу-свидетель и перенаправляет ее в стек-свидетель для оценки. Стек-свидетель предоставляет аргументы сценария и сценарий-свидетель.
  • P2WSH: у scriptPubKey есть программа-свидетель, scriptSig пуст, а стек-свидетель предоставляет аргументы сценария и сценарий-свидетель.
  • Стек-свидетель идентичен для эквивалентных входных данных P2SH-P2WSH и P2WSH.

Таким образом, чтобы рассчитать размер мультиподписи P2SH-P2WSH, аргументы скрипта и скрипт погашения перемещаются в стек-свидетель в качестве аргументов скрипта и скрипта-свидетеля, и вам нужно добавить стоимость скрипта пересылки.

scriptSig в P2SH-P2WSH состоит из scriptLength witnessProgramLength witnessVersion hashLength hashили varInt PUSHBYTES OP_0 PUSHBYTES <hash>. Длина scriptSig может быть выражена в 1-байтовом varInt, поэтому scriptSig в сумме занимает 1 + 1 + 1 + 1 + 32 = 36 байт. +4 Б), scriptSig (36 Б) и nSequence (4 Б), что в сумме дает 76 Б.

Стек-свидетель имеет количество элементов-свидетелей (1 WU), три аргумента сценария, пустой фиктивный элемент, поскольку OP_CHECKMULTISIG извлекает дополнительный элемент из стека, и две подписи (1+2×(1+72) = 147 WU). ) и сценарий-свидетель witnessScriptLength OP_m n×(PUSHBYTES+pubkey) OP_n OP_CHECKMULTISIG(1+1+3×(1+33)+1+1 = 106 WU).

Таким образом, общий размер входа 2 из 3 P2SH-P2WSH составляет:

txid:vout:scriptSig:nSeq::witLength:scriptArgs:witScript
 32 +  4 +    36   +  4  +    1    +    147   +    106  = 76 + 254/4 = 139.5 vB 

Полная информация обо всех трех типах приведена ниже для вашего удобства.

П2Ш

Размер ввода с мультиподписью 2 из 3 на основе P2SH составляет 293, 296 или 297 байтов, как описано в вопросе.

PREVOUT:
  hash (32 bytes)
  index (4 bytes)
SCRIPTSIG:
  length (varInt 1 or 3 bytes)
  signatures¹ (1+2×(1+72²) bytes = 147 bytes)
    dummy-OP_0 
    m×(PUSHBYTES+sig)
  OP_PUSHDATA1 len(redeemscript) (2 bytes)
  redeemscript (1+3×(1+33)+1+1 = 105 bytes)
    OP_m n×(PUSHBYTES+pubkey) OP_n OP_CHECKMULTISIG
nSequence (4 bytes)

32 + 4 + 3 + 1 + 2×(1+72) + 2 + 1 + 3×(1+33) + 1 + 1 + 4 =
36 + 3 + 147 + 2 + 105 + 4 = 297 B

Так как подписи могут иметь размер 71 или 72 байта, получается, что для ввода требуется 1-байтовый varInt, чтобы выразить длину scriptSig для двух подписей с низким значением r. Если одна или обе подписи имеют высокое значение r, для выражения длины scriptSig требуется 3-байтовый varInt.

П2Ш-П2ВШ

Вес P2SH-P2WSH 2-из-3 составляет 556–558 WU, что соответствует 139,0–139,5 vB.

PREVOUT:
  hash (32 bytes)
  index (4 bytes)
SCRIPTSIG:
  length (varInt 1 byte)
  witness program: (1 + 1 + 1 + 32 = 35 bytes)
    length
    version (OP_0) 
    PUSHBYTES <32-byte hash>
nSequence (4 bytes)
WITNESS STACK:
  item count (1 WU)
  script arguments (1 + 2×(1+72²) WU)
    dummy-empty-element¹
    m×(varInt+sig)
  witnessScript (1+1+3×(1+33)+1+1 = 106 WU)
    length (varInt 1 WU)
    OP_m n×(PUSHBYTES+pubkey) OP_n OP_CHECKMULTISIG
  
32 + 4 + 1 + 1 + 1 + 1 + 32 + 4
+ [1 + 1 + 2×(1+72) + 1+1+3×(1+33)+1+1]/4
= 36 + 1 + 35 + 4 + [1 + 147 + 106]/4
= 76 + [254]/4
= 76 + 63.5
= 139.5 vB

P2WSH

P2WSH имеет тот же стек-свидетель, что и P2SH-P2WSH, поэтому он экономит ровно 35 B от обхода сценария погашения. Вес P2WSH 2-из-3 составляет 416–418 WU, что соответствует 104,0–104,5 vB.

PREVOUT:
  hash (32 bytes)
  index (4 bytes)
SCRIPTSIG:
  length (varInt 1 byte)
nSequence (4 bytes)
WITNESS STACK:
  item count (1 WU)
  script arguments (1 + 2×(1+72²) WU)
    dummy-empty-element¹ 
    m×(varInt+sig)
  witnessScript (1+1+3×(1+33)+1+1 = 106 WU)
    length (varInt 1 WU)
    OP_m n×(PUSHBYTES+pubkey) OP_n OP_CHECKMULTISIG

32 + 4 + 1 + 4
+ [1 + 1 + 2×(1+72) + 1 + 1 + 3×(1+33) + 1 + 1]/4
= 36 + 1 + 4 + [1 + 147 + 106]/4
= 41 + [254]/4
= 41 + 63.5 
= 104.5 vB

¹ OP_CHECKMULTISIG извлекает один дополнительный элемент из стека
² Подписи могут быть 71 или 72 байта (или даже меньше)