Я пытаюсь рассчитать вес входных данных 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 байта.
Чтобы рассчитать вес блока, вам нужно знать размер в байтах данных, не являющихся свидетелями, и размер в байтах данных-свидетелей.
С вводом 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 байт.
Различия между P2SH, 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 из 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.
Вес 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 имеет тот же стек-свидетель, что и 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 байта (или даже меньше)
Марч
SizeOfVarIntFor(RedeemScript)
что redeemscript длиннее 75 байт, не будет ли то же самое относиться к 251?SizeOfVarIntFor(SizeOfScriptSig)
SizeOfScriptSig
Эндрю Чоу
SizeOfScriptSig
, мы используем компактные целые числа без знака. csuint требуется только дополнительный байт поверх самого числа, когда самому числу требуется более 1 байта. Посмотреть, как работает csuint, можно здесь: bitcoin.org/en/…