Я следил за BIP16 при создании транзакции P2SH. Я хочу создать простой (одна подпись) P2SH. Я получаю сообщение об ошибке при попытке передать tx. Ошибка16: mandatory-script-verify-flag-failed (Signature must be zero for failed CHECK(MULTI)SIG operation)
Чтобы было ясно, я не пытаюсь использовать мультиподпись. То, что я делаю, лучше всего можно описать как P2SH-P2PK
, хотя я не встречал этого термина. Это единственный пример, приведенный в BIP16, так что это должно работать.
Вот что я пробовал (тестнет):
private key: BB2AC60BC518C0E239D5AF9D8D051A6BDFD0D931268DCA70C59E5992
public key: 039f53e45f8f18b8ed294378bda342eff69b2053debf27fbede7d2d6bd84be6235
(compressed)
redeemScript: [{pubKeySize,pubKey}] [OP_CHECKSIG]
21039F53E45F8F18B8ED294378BDA342EFF69B2053DEBF27FBEDE7D2D6BD84BE6235AC
redeemScriptHash: RIPEMD160(SHA256(redeemScript))
323D0E8A083E98010299109337850D05DD6157F7
p2shAddress: Base58Check(0xC4 + redeemScriptHash) (C4 for testnet)
2MwprvB9tUMtX4vK8zJK8K329fNu79CJgR7
Вышеупомянутый адрес имеет два UTOX в тестовой сети:
UTXO1: e434a13cac79dc3d26e7279bff05c0f071a2df03e2ba6ca13c88f0e82dca9998:0
UTXO2: 9b4943e7ab5f4512e42c94254eb6aab4c6823ce06d4ff816b7ce4fda155a2571:0
Теперь я хочу потратить оба UTXO и сохранить следующие результаты:
Out1: 2MwprvB9tUMtX4vK8zJK8K329fNu79CJgR7 34000000 Satoshis
Out2: 2N8hwP1WmJrFF5QWABn38y63uYLhnJYJYTF 100000000 Satoshis
Я создал tx следующим образом:
Создавать неподписанные транзакции со всеми пустыми scriptSigs
Для каждого ввода для подписи установите для его scriptSig значение redeemScript: 21039F53E45F8F18B8ED294378BDA342EFF69B2053DEBF27FBEDE7D2D6BD84BE6235AC
, оставив остальные scriptSig пустыми.
Сериализуйте новый tx и добавьте байты SIGHASHALL (0x01) в 4 байта с прямым порядком байтов.
Удвойте Sha256 выше и подпишите полученное значение. Добавьте один байт 0x01 в подпись, чтобы указать SIGHASH_ALL. Пусть sig
будет полученное значение.
Установите scriptSig как:
[0x00] [{sigSize, sig}] [{pubKeySize, pubKey}] [OP_CHECKSIG]
Я предполагаю, что будет использоваться следующий scriptPubKey:
[OP_HASH160] [{scriptHashSize, scriptHash}] [OP_EQUAL]
Ниже приведены k
значения r
и s
для подписи каждого входа:
Вход 1:
k = 98790447509501799195296257240616657470656053786701275200434341714298778299820
r = 96398386359095408146340664941016369169423137684113382189227162443480418477689
s = 62903510511574365450545635776206168644738316078298063260649088246548574249129
Вход 2:
k = 109372172176680138721552873719725202562296645126925021083510279924852033069204
r = 105162394984132461723584277789901247831150698039237112243693144757926439529504
s = 62903510511574365450545635776206168644738316078298063260649088246548574249129
После этого я получаю следующую ошибку в bitcoind для отправки tx:
error code: -26
error message:
16: mandatory-script-verify-flag-failed
(Signature must be zero for failed CHECK(MULTI)SIG operation)
Что я делаю неправильно?
РЕДАКТИРОВАТЬ: благодаря ответу arubi я обнаружил две проблемы с вышеуказанными шагами. Во-первых, я ошибался, не redeemScript
кодируя данные стека. Второе, что я делал неправильно , это вставлял [0x00]
. scriptSig
После исправления шаг 5 должен быть:
Установите redeemScript
как[{pubKeySize, pubKey}] [OP_CHECKSIG]
Установите scriptSig
как[{sigSize, sig}] [{redeemScriptSize, redeemScript}]
Проблема в том, что scriptsig содержит фактический redeemScript вместо сериализованного скрипта в качестве push-уведомления. Вторая ошибка, redeemscript содержит постороннее 0x00
значение, которого быть не должно, так как это простой файл CHECKSIG
.
аруби
0x00
значение, оставленное в стеке, не делает транзакцию недействительной, скорее, оно не будет перехвачено локальной политикой перед ретрансляцией, поскольку оно не соответствуетcleanstack
правилу.Jus12
0x00
, будет считаться действительным?аруби
OP_CHECKSIG
который выполняется последним, поместит значение, которое оценивается как True (0x01
в данном случае), на вершину стека. Стек будет таким: 0x01 0x00 Заставить весь скрипт оценить как True.