mirror of
https://github.com/kaspanet/kaspad.git
synced 2025-06-05 21:56:50 +00:00
[DEV-14] Removed SegWit from txscript package!
This commit is contained in:
parent
cea07f3b98
commit
e3079c7e79
@ -71,8 +71,7 @@ out:
|
||||
sigScript := txIn.SignatureScript
|
||||
pkScript := utxo.PkScript()
|
||||
vm, err := txscript.NewEngine(pkScript, txVI.tx.MsgTx(),
|
||||
txVI.txInIndex, v.flags, v.sigCache, &txscript.TxSigHashes{},
|
||||
utxo.Amount())
|
||||
txVI.txInIndex, v.flags, v.sigCache)
|
||||
if err != nil {
|
||||
str := fmt.Sprintf("failed to parse input "+
|
||||
"%s:%d which references output %v - "+
|
||||
|
@ -1253,12 +1253,6 @@
|
||||
["0x17 0x3014021077777777777777777777777777777777020001", "0 CHECKSIG NOT", "DERSIG", "SIG_DER", "Zero-length S is incorrectly encoded for DERSIG"],
|
||||
["0x27 0x302402107777777777777777777777777777777702108777777777777777777777777777777701", "0 CHECKSIG NOT", "DERSIG", "SIG_DER", "Negative S is incorrectly encoded for DERSIG"],
|
||||
|
||||
["Some basic segwit checks"],
|
||||
[["00", 0.00000000 ], "", "0 0x206e340b9cffb37a989ca544e6bb780a2c78901d3fb33738768511a30617afa01d", "P2SH,WITNESS", "EVAL_FALSE", "Invalid witness script"],
|
||||
[["51", 0.00000000 ], "", "0 0x206e340b9cffb37a989ca544e6bb780a2c78901d3fb33738768511a30617afa01d", "P2SH,WITNESS", "WITNESS_PROGRAM_MISMATCH", "Witness script hash mismatch"],
|
||||
[["00", 0.00000000 ], "", "0 0x206e340b9cffb37a989ca544e6bb780a2c78901d3fb33738768511a30617afa01d", "", "OK", "Invalid witness script without WITNESS"],
|
||||
[["51", 0.00000000 ], "", "0 0x206e340b9cffb37a989ca544e6bb780a2c78901d3fb33738768511a30617afa01d", "", "OK", "Witness script hash mismatch without WITNESS"],
|
||||
|
||||
["Automatically generated test cases"],
|
||||
[
|
||||
"0x47 0x304402200a5c6163f07b8d3b013c4d1d6dba25e780b39658d79ba37af7057a3b7f15ffa102201fd9b4eaa9943f734928b99a83592c2e7bf342ea2680f6a2bb705167966b742001",
|
||||
@ -1856,655 +1850,6 @@
|
||||
"P2SH with CLEANSTACK"
|
||||
],
|
||||
|
||||
["Testing with uncompressed keys in witness v0 without WITNESS_PUBKEYTYPE"],
|
||||
[
|
||||
[
|
||||
"304402200d461c140cfdfcf36b94961db57ae8c18d1cb80e9d95a9e47ac22470c1bf125502201c8dc1cbfef6a3ef90acbbb992ca22fe9466ee6f9d4898eda277a7ac3ab4b25101",
|
||||
"410479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8ac",
|
||||
0.00000001
|
||||
],
|
||||
"",
|
||||
"0 0x20 0xb95237b48faaa69eb078e1170be3b5cbb3fddf16d0a991e14ad274f7b33a4f64",
|
||||
"P2SH,WITNESS",
|
||||
"OK",
|
||||
"Basic P2WSH"
|
||||
],
|
||||
[
|
||||
[
|
||||
"304402201e7216e5ccb3b61d46946ec6cc7e8c4e0117d13ac2fd4b152197e4805191c74202203e9903e33e84d9ee1dd13fb057afb7ccfb47006c23f6a067185efbc9dd780fc501",
|
||||
"0479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8",
|
||||
0.00000001
|
||||
],
|
||||
"",
|
||||
"0 0x14 0x91b24bf9f5288532960ac687abb035127b1d28a5",
|
||||
"P2SH,WITNESS",
|
||||
"OK",
|
||||
"Basic P2WPKH"
|
||||
],
|
||||
[
|
||||
[
|
||||
"3044022066e02c19a513049d49349cf5311a1b012b7c4fae023795a18ab1d91c23496c22022025e216342c8e07ce8ef51e8daee88f84306a9de66236cab230bb63067ded1ad301",
|
||||
"410479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8ac",
|
||||
0.00000001
|
||||
],
|
||||
"0x22 0x0020b95237b48faaa69eb078e1170be3b5cbb3fddf16d0a991e14ad274f7b33a4f64",
|
||||
"HASH160 0x14 0xf386c2ba255cc56d20cfa6ea8b062f8b59945518 EQUAL",
|
||||
"P2SH,WITNESS",
|
||||
"OK",
|
||||
"Basic P2SH(P2WSH)"
|
||||
],
|
||||
[
|
||||
[
|
||||
"304402200929d11561cd958460371200f82e9cae64c727a495715a31828e27a7ad57b36d0220361732ced04a6f97351ecca21a56d0b8cd4932c1da1f8f569a2b68e5e48aed7801",
|
||||
"0479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8",
|
||||
0.00000001
|
||||
],
|
||||
"0x16 0x001491b24bf9f5288532960ac687abb035127b1d28a5",
|
||||
"HASH160 0x14 0x17743beb429c55c942d2ec703b98c4d57c2df5c6 EQUAL",
|
||||
"P2SH,WITNESS",
|
||||
"OK",
|
||||
"Basic P2SH(P2WPKH)"
|
||||
],
|
||||
[
|
||||
[
|
||||
"304402202589f0512cb2408fb08ed9bd24f85eb3059744d9e4f2262d0b7f1338cff6e8b902206c0978f449693e0578c71bc543b11079fd0baae700ee5e9a6bee94db490af9fc01",
|
||||
"41048282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f5150811f8a8098557dfe45e8256e830b60ace62d613ac2f7b17bed31b6eaff6e26cafac",
|
||||
0.00000000
|
||||
],
|
||||
"",
|
||||
"0 0x20 0xac8ebd9e52c17619a381fa4f71aebb696087c6ef17c960fd0587addad99c0610",
|
||||
"P2SH,WITNESS",
|
||||
"EVAL_FALSE",
|
||||
"Basic P2WSH with the wrong key"
|
||||
],
|
||||
[
|
||||
[
|
||||
"304402206ef7fdb2986325d37c6eb1a8bb24aeb46dede112ed8fc76c7d7500b9b83c0d3d02201edc2322c794fe2d6b0bd73ed319e714aa9b86d8891961530d5c9b7156b60d4e01",
|
||||
"048282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f5150811f8a8098557dfe45e8256e830b60ace62d613ac2f7b17bed31b6eaff6e26caf",
|
||||
0.00000000
|
||||
],
|
||||
"",
|
||||
"0 0x14 0x7cf9c846cd4882efec4bf07e44ebdad495c94f4b",
|
||||
"P2SH,WITNESS",
|
||||
"EVAL_FALSE",
|
||||
"Basic P2WPKH with the wrong key"
|
||||
],
|
||||
[
|
||||
[
|
||||
"30440220069ea3581afaf8187f63feee1fd2bd1f9c0dc71ea7d6e8a8b07ee2ebcf824bf402201a4fdef4c532eae59223be1eda6a397fc835142d4ddc6c74f4aa85b766a5c16f01",
|
||||
"41048282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f5150811f8a8098557dfe45e8256e830b60ace62d613ac2f7b17bed31b6eaff6e26cafac",
|
||||
0.00000000
|
||||
],
|
||||
"0x22 0x0020ac8ebd9e52c17619a381fa4f71aebb696087c6ef17c960fd0587addad99c0610",
|
||||
"HASH160 0x14 0x61039a003883787c0d6ebc66d97fdabe8e31449d EQUAL",
|
||||
"P2SH,WITNESS",
|
||||
"EVAL_FALSE",
|
||||
"Basic P2SH(P2WSH) with the wrong key"
|
||||
],
|
||||
[
|
||||
[
|
||||
"304402204209e49457c2358f80d0256bc24535b8754c14d08840fc4be762d6f5a0aed80b02202eaf7d8fc8d62f60c67adcd99295528d0e491ae93c195cec5a67e7a09532a88001",
|
||||
"048282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f5150811f8a8098557dfe45e8256e830b60ace62d613ac2f7b17bed31b6eaff6e26caf",
|
||||
0.00000000
|
||||
],
|
||||
"0x16 0x00147cf9c846cd4882efec4bf07e44ebdad495c94f4b",
|
||||
"HASH160 0x14 0x4e0c2aed91315303fc6a1dc4c7bc21c88f75402e EQUAL",
|
||||
"P2SH,WITNESS",
|
||||
"EVAL_FALSE",
|
||||
"Basic P2SH(P2WPKH) with the wrong key"
|
||||
],
|
||||
[
|
||||
[
|
||||
"304402202589f0512cb2408fb08ed9bd24f85eb3059744d9e4f2262d0b7f1338cff6e8b902206c0978f449693e0578c71bc543b11079fd0baae700ee5e9a6bee94db490af9fc01",
|
||||
"41048282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f5150811f8a8098557dfe45e8256e830b60ace62d613ac2f7b17bed31b6eaff6e26cafac",
|
||||
0.00000000
|
||||
],
|
||||
"",
|
||||
"0 0x20 0xac8ebd9e52c17619a381fa4f71aebb696087c6ef17c960fd0587addad99c0610",
|
||||
"P2SH",
|
||||
"OK",
|
||||
"Basic P2WSH with the wrong key but no WITNESS"
|
||||
],
|
||||
[
|
||||
[
|
||||
"304402206ef7fdb2986325d37c6eb1a8bb24aeb46dede112ed8fc76c7d7500b9b83c0d3d02201edc2322c794fe2d6b0bd73ed319e714aa9b86d8891961530d5c9b7156b60d4e01",
|
||||
"048282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f5150811f8a8098557dfe45e8256e830b60ace62d613ac2f7b17bed31b6eaff6e26caf",
|
||||
0.00000000
|
||||
],
|
||||
"",
|
||||
"0 0x14 0x7cf9c846cd4882efec4bf07e44ebdad495c94f4b",
|
||||
"P2SH",
|
||||
"OK",
|
||||
"Basic P2WPKH with the wrong key but no WITNESS"
|
||||
],
|
||||
[
|
||||
[
|
||||
"30440220069ea3581afaf8187f63feee1fd2bd1f9c0dc71ea7d6e8a8b07ee2ebcf824bf402201a4fdef4c532eae59223be1eda6a397fc835142d4ddc6c74f4aa85b766a5c16f01",
|
||||
"41048282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f5150811f8a8098557dfe45e8256e830b60ace62d613ac2f7b17bed31b6eaff6e26cafac",
|
||||
0.00000000
|
||||
],
|
||||
"0x22 0x0020ac8ebd9e52c17619a381fa4f71aebb696087c6ef17c960fd0587addad99c0610",
|
||||
"HASH160 0x14 0x61039a003883787c0d6ebc66d97fdabe8e31449d EQUAL",
|
||||
"P2SH",
|
||||
"OK",
|
||||
"Basic P2SH(P2WSH) with the wrong key but no WITNESS"
|
||||
],
|
||||
[
|
||||
[
|
||||
"304402204209e49457c2358f80d0256bc24535b8754c14d08840fc4be762d6f5a0aed80b02202eaf7d8fc8d62f60c67adcd99295528d0e491ae93c195cec5a67e7a09532a88001",
|
||||
"048282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f5150811f8a8098557dfe45e8256e830b60ace62d613ac2f7b17bed31b6eaff6e26caf",
|
||||
0.00000000
|
||||
],
|
||||
"0x16 0x00147cf9c846cd4882efec4bf07e44ebdad495c94f4b",
|
||||
"HASH160 0x14 0x4e0c2aed91315303fc6a1dc4c7bc21c88f75402e EQUAL",
|
||||
"P2SH",
|
||||
"OK",
|
||||
"Basic P2SH(P2WPKH) with the wrong key but no WITNESS"
|
||||
],
|
||||
[
|
||||
[
|
||||
"3044022066faa86e74e8b30e82691b985b373de4f9e26dc144ec399c4f066aa59308e7c202204712b86f28c32503faa051dbeabff2c238ece861abc36c5e0b40b1139ca222f001",
|
||||
"410479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8ac",
|
||||
0.00000000
|
||||
],
|
||||
"",
|
||||
"0 0x20 0xb95237b48faaa69eb078e1170be3b5cbb3fddf16d0a991e14ad274f7b33a4f64",
|
||||
"P2SH,WITNESS",
|
||||
"EVAL_FALSE",
|
||||
"Basic P2WSH with wrong value"
|
||||
],
|
||||
[
|
||||
[
|
||||
"304402203b3389b87448d7dfdb5e82fb854fcf92d7925f9938ea5444e36abef02c3d6a9602202410bc3265049abb07fd2e252c65ab7034d95c9d5acccabe9fadbdc63a52712601",
|
||||
"0479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8",
|
||||
0.00000000
|
||||
],
|
||||
"",
|
||||
"0 0x14 0x91b24bf9f5288532960ac687abb035127b1d28a5",
|
||||
"P2SH,WITNESS",
|
||||
"EVAL_FALSE",
|
||||
"Basic P2WPKH with wrong value"
|
||||
],
|
||||
[
|
||||
[
|
||||
"3044022000a30c4cfc10e4387be528613575434826ad3c15587475e0df8ce3b1746aa210022008149265e4f8e9dafe1f3ea50d90cb425e9e40ea7ebdd383069a7cfa2b77004701",
|
||||
"410479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8ac",
|
||||
0.00000000
|
||||
],
|
||||
"0x22 0x0020b95237b48faaa69eb078e1170be3b5cbb3fddf16d0a991e14ad274f7b33a4f64",
|
||||
"HASH160 0x14 0xf386c2ba255cc56d20cfa6ea8b062f8b59945518 EQUAL",
|
||||
"P2SH,WITNESS",
|
||||
"EVAL_FALSE",
|
||||
"Basic P2SH(P2WSH) with wrong value"
|
||||
],
|
||||
[
|
||||
[
|
||||
"304402204fc3a2cd61a47913f2a5f9107d0ad4a504c7b31ee2d6b3b2f38c2b10ee031e940220055d58b7c3c281aaa381d8f486ac0f3e361939acfd568046cb6a311cdfa974cf01",
|
||||
"0479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8",
|
||||
0.00000000
|
||||
],
|
||||
"0x16 0x001491b24bf9f5288532960ac687abb035127b1d28a5",
|
||||
"HASH160 0x14 0x17743beb429c55c942d2ec703b98c4d57c2df5c6 EQUAL",
|
||||
"P2SH,WITNESS",
|
||||
"EVAL_FALSE",
|
||||
"Basic P2SH(P2WPKH) with wrong value"
|
||||
],
|
||||
[
|
||||
[
|
||||
"304402205ae57ae0534c05ca9981c8a6cdf353b505eaacb7375f96681a2d1a4ba6f02f84022056248e68643b7d8ce7c7d128c9f1f348bcab8be15d094ad5cadd24251a28df8001",
|
||||
"0479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8",
|
||||
0.00000000
|
||||
],
|
||||
"",
|
||||
"1 0x14 0x91b24bf9f5288532960ac687abb035127b1d28a5",
|
||||
"DISCOURAGE_UPGRADABLE_WITNESS_PROGRAM,P2SH,WITNESS",
|
||||
"DISCOURAGE_UPGRADABLE_WITNESS_PROGRAM",
|
||||
"P2WPKH with future witness version"
|
||||
],
|
||||
[
|
||||
[
|
||||
"3044022064100ca0e2a33332136775a86cd83d0230e58b9aebb889c5ac952abff79a46ef02205f1bf900e022039ad3091bdaf27ac2aef3eae9ed9f190d821d3e508405b9513101",
|
||||
"0479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8",
|
||||
0.00000000
|
||||
],
|
||||
"",
|
||||
"0 0x1f 0xb34b78da162751647974d5cb7410aa428ad339dbf7d1e16e833f68a0cbf1c3",
|
||||
"P2SH,WITNESS",
|
||||
"WITNESS_PROGRAM_WRONG_LENGTH",
|
||||
"P2WPKH with wrong witness program length"
|
||||
],
|
||||
[
|
||||
"",
|
||||
"0 0x20 0xb95237b48faaa69eb078e1170be3b5cbb3fddf16d0a991e14ad274f7b33a4f64",
|
||||
"P2SH,WITNESS",
|
||||
"WITNESS_PROGRAM_WITNESS_EMPTY",
|
||||
"P2WSH with empty witness"
|
||||
],
|
||||
[
|
||||
[
|
||||
"3044022039105b995a5f448639a997a5c90fda06f50b49df30c3bdb6663217bf79323db002206fecd54269dec569fcc517178880eb58bb40f381a282bb75766ff3637d5f4b4301",
|
||||
"400479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8ac",
|
||||
0.00000000
|
||||
],
|
||||
"",
|
||||
"0 0x20 0xb95237b48faaa69eb078e1170be3b5cbb3fddf16d0a991e14ad274f7b33a4f64",
|
||||
"P2SH,WITNESS",
|
||||
"WITNESS_PROGRAM_MISMATCH",
|
||||
"P2WSH with witness program mismatch"
|
||||
],
|
||||
[
|
||||
[
|
||||
"304402201a96950593cb0af32d080b0f193517f4559241a8ebd1e95e414533ad64a3f423022047f4f6d3095c23235bdff3aeff480d0529c027a3f093cb265b7cbf148553b85101",
|
||||
"0479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8",
|
||||
"",
|
||||
0.00000000
|
||||
],
|
||||
"",
|
||||
"0 0x14 0x91b24bf9f5288532960ac687abb035127b1d28a5",
|
||||
"P2SH,WITNESS",
|
||||
"WITNESS_PROGRAM_MISMATCH",
|
||||
"P2WPKH with witness program mismatch"
|
||||
],
|
||||
[
|
||||
[
|
||||
"304402201a96950593cb0af32d080b0f193517f4559241a8ebd1e95e414533ad64a3f423022047f4f6d3095c23235bdff3aeff480d0529c027a3f093cb265b7cbf148553b85101",
|
||||
"0479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8",
|
||||
0.00000000
|
||||
],
|
||||
"11",
|
||||
"0 0x14 0x91b24bf9f5288532960ac687abb035127b1d28a5",
|
||||
"P2SH,WITNESS",
|
||||
"WITNESS_MALLEATED",
|
||||
"P2WPKH with non-empty scriptSig"
|
||||
],
|
||||
[
|
||||
[
|
||||
"304402204209e49457c2358f80d0256bc24535b8754c14d08840fc4be762d6f5a0aed80b02202eaf7d8fc8d62f60c67adcd99295528d0e491ae93c195cec5a67e7a09532a88001",
|
||||
"048282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f5150811f8a8098557dfe45e8256e830b60ace62d613ac2f7b17bed31b6eaff6e26caf",
|
||||
0.00000000
|
||||
],
|
||||
"11 0x16 0x00147cf9c846cd4882efec4bf07e44ebdad495c94f4b",
|
||||
"HASH160 0x14 0x4e0c2aed91315303fc6a1dc4c7bc21c88f75402e EQUAL",
|
||||
"P2SH,WITNESS",
|
||||
"WITNESS_MALLEATED_P2SH",
|
||||
"P2SH(P2WPKH) with superfluous push in scriptSig"
|
||||
],
|
||||
[
|
||||
[
|
||||
"",
|
||||
0.00000000
|
||||
],
|
||||
"0x47 0x304402200a5c6163f07b8d3b013c4d1d6dba25e780b39658d79ba37af7057a3b7f15ffa102201fd9b4eaa9943f734928b99a83592c2e7bf342ea2680f6a2bb705167966b742001",
|
||||
"0x41 0x0479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8 CHECKSIG",
|
||||
"P2SH,WITNESS",
|
||||
"WITNESS_UNEXPECTED",
|
||||
"P2PK with witness"
|
||||
],
|
||||
|
||||
["Testing with compressed keys in witness v0 with WITNESS_PUBKEYTYPE"],
|
||||
[
|
||||
[
|
||||
"304402204256146fcf8e73b0fd817ffa2a4e408ff0418ff987dd08a4f485b62546f6c43c02203f3c8c3e2febc051e1222867f5f9d0eaf039d6792911c10940aa3cc74123378e01",
|
||||
"210279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798ac",
|
||||
0.00000001
|
||||
],
|
||||
"",
|
||||
"0 0x20 0x1863143c14c5166804bd19203356da136c985678cd4d27a1b8c6329604903262",
|
||||
"P2SH,WITNESS,WITNESS_PUBKEYTYPE",
|
||||
"OK",
|
||||
"Basic P2WSH with compressed key"
|
||||
],
|
||||
[
|
||||
[
|
||||
"304402204edf27486f11432466b744df533e1acac727e0c83e5f912eb289a3df5bf8035f022075809fdd876ede40ad21667eba8b7e96394938f9c9c50f11b6a1280cce2cea8601",
|
||||
"0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798",
|
||||
0.00000001
|
||||
],
|
||||
"",
|
||||
"0 0x14 0x751e76e8199196d454941c45d1b3a323f1433bd6",
|
||||
"P2SH,WITNESS,WITNESS_PUBKEYTYPE",
|
||||
"OK",
|
||||
"Basic P2WPKH with compressed key"
|
||||
],
|
||||
[
|
||||
[
|
||||
"304402203a549090cc46bce1e5e95c4922ea2c12747988e0207b04c42f81cdbe87bb1539022050f57a245b875fd5119c419aaf050bcdf41384f0765f04b809e5bced1fe7093d01",
|
||||
"210279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798ac",
|
||||
0.00000001
|
||||
],
|
||||
"0x22 0x00201863143c14c5166804bd19203356da136c985678cd4d27a1b8c6329604903262",
|
||||
"HASH160 0x14 0xe4300531190587e3880d4c3004f5355d88ff928d EQUAL",
|
||||
"P2SH,WITNESS,WITNESS_PUBKEYTYPE",
|
||||
"OK",
|
||||
"Basic P2SH(P2WSH) with compressed key"
|
||||
],
|
||||
[
|
||||
[
|
||||
"304402201bc0d53046827f4a35a3166e33e3b3366c4085540dc383b95d21ed2ab11e368a0220333e78c6231214f5f8e59621e15d7eeab0d4e4d0796437e00bfbd2680c5f9c1701",
|
||||
"0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798",
|
||||
0.00000001
|
||||
],
|
||||
"0x16 0x0014751e76e8199196d454941c45d1b3a323f1433bd6",
|
||||
"HASH160 0x14 0xbcfeb728b584253d5f3f70bcb780e9ef218a68f4 EQUAL",
|
||||
"P2SH,WITNESS,WITNESS_PUBKEYTYPE",
|
||||
"OK",
|
||||
"Basic P2SH(P2WPKH) with compressed key"
|
||||
],
|
||||
|
||||
["Testing with uncompressed keys in witness v0 with WITNESS_PUBKEYTYPE"],
|
||||
[
|
||||
[
|
||||
"304402200d461c140cfdfcf36b94961db57ae8c18d1cb80e9d95a9e47ac22470c1bf125502201c8dc1cbfef6a3ef90acbbb992ca22fe9466ee6f9d4898eda277a7ac3ab4b25101",
|
||||
"410479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8ac",
|
||||
0.00000001
|
||||
],
|
||||
"",
|
||||
"0 0x20 0xb95237b48faaa69eb078e1170be3b5cbb3fddf16d0a991e14ad274f7b33a4f64",
|
||||
"P2SH,WITNESS,WITNESS_PUBKEYTYPE",
|
||||
"WITNESS_PUBKEYTYPE",
|
||||
"Basic P2WSH"
|
||||
],
|
||||
[
|
||||
[
|
||||
"304402201e7216e5ccb3b61d46946ec6cc7e8c4e0117d13ac2fd4b152197e4805191c74202203e9903e33e84d9ee1dd13fb057afb7ccfb47006c23f6a067185efbc9dd780fc501",
|
||||
"0479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8",
|
||||
0.00000001
|
||||
],
|
||||
"",
|
||||
"0 0x14 0x91b24bf9f5288532960ac687abb035127b1d28a5",
|
||||
"P2SH,WITNESS,WITNESS_PUBKEYTYPE",
|
||||
"WITNESS_PUBKEYTYPE",
|
||||
"Basic P2WPKH"
|
||||
],
|
||||
[
|
||||
[
|
||||
"3044022066e02c19a513049d49349cf5311a1b012b7c4fae023795a18ab1d91c23496c22022025e216342c8e07ce8ef51e8daee88f84306a9de66236cab230bb63067ded1ad301",
|
||||
"410479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8ac",
|
||||
0.00000001
|
||||
],
|
||||
"0x22 0x0020b95237b48faaa69eb078e1170be3b5cbb3fddf16d0a991e14ad274f7b33a4f64",
|
||||
"HASH160 0x14 0xf386c2ba255cc56d20cfa6ea8b062f8b59945518 EQUAL",
|
||||
"P2SH,WITNESS,WITNESS_PUBKEYTYPE",
|
||||
"WITNESS_PUBKEYTYPE",
|
||||
"Basic P2SH(P2WSH)"
|
||||
],
|
||||
[
|
||||
[
|
||||
"304402200929d11561cd958460371200f82e9cae64c727a495715a31828e27a7ad57b36d0220361732ced04a6f97351ecca21a56d0b8cd4932c1da1f8f569a2b68e5e48aed7801",
|
||||
"0479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8",
|
||||
0.00000001
|
||||
],
|
||||
"0x16 0x001491b24bf9f5288532960ac687abb035127b1d28a5",
|
||||
"HASH160 0x14 0x17743beb429c55c942d2ec703b98c4d57c2df5c6 EQUAL",
|
||||
"P2SH,WITNESS,WITNESS_PUBKEYTYPE",
|
||||
"WITNESS_PUBKEYTYPE",
|
||||
"Basic P2SH(P2WPKH)"
|
||||
],
|
||||
|
||||
["Testing P2WSH multisig with compressed keys"],
|
||||
[
|
||||
[
|
||||
"",
|
||||
"304402207eb8a59b5c65fc3f6aeef77066556ed5c541948a53a3ba7f7c375b8eed76ee7502201e036a7a9a98ff919ff94dc905d67a1ec006f79ef7cff0708485c8bb79dce38e01",
|
||||
"5121038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508210279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f8179852ae",
|
||||
0.00000001
|
||||
],
|
||||
"",
|
||||
"0 0x20 0x06c24420938f0fa3c1cb2707d867154220dca365cdbfa0dd2a83854730221460",
|
||||
"P2SH,WITNESS,WITNESS_PUBKEYTYPE",
|
||||
"OK",
|
||||
"P2WSH CHECKMULTISIG with compressed keys"
|
||||
],
|
||||
[
|
||||
[
|
||||
"",
|
||||
"3044022033706aed33b8155d5486df3b9bca8cdd3bd4bdb5436dce46d72cdaba51d22b4002203626e94fe53a178af46624f17315c6931f20a30b103f5e044e1eda0c3fe185c601",
|
||||
"5121038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508210279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f8179852ae",
|
||||
0.00000001
|
||||
],
|
||||
"0x22 0x002006c24420938f0fa3c1cb2707d867154220dca365cdbfa0dd2a83854730221460",
|
||||
"HASH160 0x14 0x26282aad7c29369d15fed062a778b6100d31a340 EQUAL",
|
||||
"P2SH,WITNESS,WITNESS_PUBKEYTYPE",
|
||||
"OK",
|
||||
"P2SH(P2WSH) CHECKMULTISIG with compressed keys"
|
||||
],
|
||||
[
|
||||
[
|
||||
"",
|
||||
"304402204048b7371ab1c544362efb89af0c80154747d665aa4fcfb2edfd2d161e57b42e02207e043748e96637080ffc3acbd4dcc6fee1e58d30f6d1269535f32188e5ddae7301",
|
||||
"5121038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508210279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f8179852ae",
|
||||
0.00000001
|
||||
],
|
||||
"",
|
||||
"0 0x20 0x06c24420938f0fa3c1cb2707d867154220dca365cdbfa0dd2a83854730221460",
|
||||
"P2SH,WITNESS,WITNESS_PUBKEYTYPE",
|
||||
"OK",
|
||||
"P2WSH CHECKMULTISIG with compressed keys"
|
||||
],
|
||||
[
|
||||
[
|
||||
"",
|
||||
"3044022073902ef0b8a554c36c44cc03c1b64df96ce2914ebcf946f5bb36078fd5245cdf02205b148f1ba127065fb8c83a5a9576f2dcd111739788ed4bb3ee08b2bd3860c91c01",
|
||||
"5121038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508210279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f8179852ae",
|
||||
0.00000001
|
||||
],
|
||||
"0x22 0x002006c24420938f0fa3c1cb2707d867154220dca365cdbfa0dd2a83854730221460",
|
||||
"HASH160 0x14 0x26282aad7c29369d15fed062a778b6100d31a340 EQUAL",
|
||||
"P2SH,WITNESS,WITNESS_PUBKEYTYPE",
|
||||
"OK",
|
||||
"P2SH(P2WSH) CHECKMULTISIG with compressed keys"
|
||||
],
|
||||
|
||||
["Testing P2WSH multisig with compressed and uncompressed keys (first key being the key closer to the top of stack)"],
|
||||
[
|
||||
[
|
||||
"",
|
||||
"304402202d092ededd1f060609dbf8cb76950634ff42b3e62cf4adb69ab92397b07d742302204ff886f8d0817491a96d1daccdcc820f6feb122ee6230143303100db37dfa79f01",
|
||||
"5121038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508410479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b852ae",
|
||||
0.00000001
|
||||
],
|
||||
"",
|
||||
"0 0x20 0x08a6665ebfd43b02323423e764e185d98d1587f903b81507dbb69bfc41005efa",
|
||||
"P2SH,WITNESS",
|
||||
"OK",
|
||||
"P2WSH CHECKMULTISIG with first key uncompressed and signing with the first key"
|
||||
],
|
||||
[
|
||||
[
|
||||
"",
|
||||
"304402202dd7e91243f2235481ffb626c3b7baf2c859ae3a5a77fb750ef97b99a8125dc002204960de3d3c3ab9496e218ec57e5240e0e10a6f9546316fe240c216d45116d29301",
|
||||
"5121038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508410479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b852ae",
|
||||
0.00000001
|
||||
],
|
||||
"0x22 0x002008a6665ebfd43b02323423e764e185d98d1587f903b81507dbb69bfc41005efa",
|
||||
"HASH160 0x14 0x6f5ecd4b83b77f3c438f5214eff96454934fc5d1 EQUAL",
|
||||
"P2SH,WITNESS",
|
||||
"OK",
|
||||
"P2SH(P2WSH) CHECKMULTISIG first key uncompressed and signing with the first key"
|
||||
],
|
||||
[
|
||||
[
|
||||
"",
|
||||
"304402202d092ededd1f060609dbf8cb76950634ff42b3e62cf4adb69ab92397b07d742302204ff886f8d0817491a96d1daccdcc820f6feb122ee6230143303100db37dfa79f01",
|
||||
"5121038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508410479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b852ae",
|
||||
0.00000001
|
||||
],
|
||||
"",
|
||||
"0 0x20 0x08a6665ebfd43b02323423e764e185d98d1587f903b81507dbb69bfc41005efa",
|
||||
"P2SH,WITNESS,WITNESS_PUBKEYTYPE",
|
||||
"WITNESS_PUBKEYTYPE",
|
||||
"P2WSH CHECKMULTISIG with first key uncompressed and signing with the first key"
|
||||
],
|
||||
[
|
||||
[
|
||||
"",
|
||||
"304402202dd7e91243f2235481ffb626c3b7baf2c859ae3a5a77fb750ef97b99a8125dc002204960de3d3c3ab9496e218ec57e5240e0e10a6f9546316fe240c216d45116d29301",
|
||||
"5121038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508410479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b852ae",
|
||||
0.00000001
|
||||
],
|
||||
"0x22 0x002008a6665ebfd43b02323423e764e185d98d1587f903b81507dbb69bfc41005efa",
|
||||
"HASH160 0x14 0x6f5ecd4b83b77f3c438f5214eff96454934fc5d1 EQUAL",
|
||||
"P2SH,WITNESS,WITNESS_PUBKEYTYPE",
|
||||
"WITNESS_PUBKEYTYPE",
|
||||
"P2SH(P2WSH) CHECKMULTISIG with first key uncompressed and signing with the first key"
|
||||
],
|
||||
[
|
||||
[
|
||||
"",
|
||||
"304402201e9e6f7deef5b2f21d8223c5189b7d5e82d237c10e97165dd08f547c4e5ce6ed02206796372eb1cc6acb52e13ee2d7f45807780bf96b132cb6697f69434be74b1af901",
|
||||
"5121038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508410479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b852ae",
|
||||
0.00000001
|
||||
],
|
||||
"",
|
||||
"0 0x20 0x08a6665ebfd43b02323423e764e185d98d1587f903b81507dbb69bfc41005efa",
|
||||
"P2SH,WITNESS",
|
||||
"OK",
|
||||
"P2WSH CHECKMULTISIG with first key uncompressed and signing with the second key"
|
||||
],
|
||||
[
|
||||
[
|
||||
"",
|
||||
"3044022045e667f3f0f3147b95597a24babe9afecea1f649fd23637dfa7ed7e9f3ac18440220295748e81005231135289fe3a88338dabba55afa1bdb4478691337009d82b68d01",
|
||||
"5121038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508410479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b852ae",
|
||||
0.00000001
|
||||
],
|
||||
"0x22 0x002008a6665ebfd43b02323423e764e185d98d1587f903b81507dbb69bfc41005efa",
|
||||
"HASH160 0x14 0x6f5ecd4b83b77f3c438f5214eff96454934fc5d1 EQUAL",
|
||||
"P2SH,WITNESS",
|
||||
"OK",
|
||||
"P2SH(P2WSH) CHECKMULTISIG with first key uncompressed and signing with the second key"
|
||||
],
|
||||
[
|
||||
[
|
||||
"",
|
||||
"304402201e9e6f7deef5b2f21d8223c5189b7d5e82d237c10e97165dd08f547c4e5ce6ed02206796372eb1cc6acb52e13ee2d7f45807780bf96b132cb6697f69434be74b1af901",
|
||||
"5121038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508410479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b852ae",
|
||||
0.00000001
|
||||
],
|
||||
"",
|
||||
"0 0x20 0x08a6665ebfd43b02323423e764e185d98d1587f903b81507dbb69bfc41005efa",
|
||||
"P2SH,WITNESS,WITNESS_PUBKEYTYPE",
|
||||
"WITNESS_PUBKEYTYPE",
|
||||
"P2WSH CHECKMULTISIG with first key uncompressed and signing with the second key"
|
||||
],
|
||||
[
|
||||
[
|
||||
"",
|
||||
"3044022045e667f3f0f3147b95597a24babe9afecea1f649fd23637dfa7ed7e9f3ac18440220295748e81005231135289fe3a88338dabba55afa1bdb4478691337009d82b68d01",
|
||||
"5121038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508410479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b852ae",
|
||||
0.00000001
|
||||
],
|
||||
"0x22 0x002008a6665ebfd43b02323423e764e185d98d1587f903b81507dbb69bfc41005efa",
|
||||
"HASH160 0x14 0x6f5ecd4b83b77f3c438f5214eff96454934fc5d1 EQUAL",
|
||||
"P2SH,WITNESS,WITNESS_PUBKEYTYPE",
|
||||
"WITNESS_PUBKEYTYPE",
|
||||
"P2SH(P2WSH) CHECKMULTISIG with first key uncompressed and signing with the second key"
|
||||
],
|
||||
[
|
||||
[
|
||||
"",
|
||||
"3044022046f5367a261fd8f8d7de6eb390491344f8ec2501638fb9a1095a0599a21d3f4c02205c1b3b51d20091c5f1020841bbca87b44ebe25405c64e4acf758f2eae8665f8401",
|
||||
"5141048282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f5150811f8a8098557dfe45e8256e830b60ace62d613ac2f7b17bed31b6eaff6e26caf210279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f8179852ae",
|
||||
0.00000001
|
||||
],
|
||||
"",
|
||||
"0 0x20 0x230828ed48871f0f362ce9432aa52f620f442cc8d9ce7a8b5e798365595a38bb",
|
||||
"P2SH,WITNESS",
|
||||
"OK",
|
||||
"P2WSH CHECKMULTISIG with second key uncompressed and signing with the first key"
|
||||
],
|
||||
[
|
||||
[
|
||||
"",
|
||||
"3044022053e210e4fb1881e6092fd75c3efc5163105599e246ded661c0ee2b5682cc2d6c02203a26b7ada8682a095b84c6d1b881637000b47d761fc837c4cee33555296d63f101",
|
||||
"5141048282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f5150811f8a8098557dfe45e8256e830b60ace62d613ac2f7b17bed31b6eaff6e26caf210279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f8179852ae",
|
||||
0.00000001
|
||||
],
|
||||
"0x22 0x0020230828ed48871f0f362ce9432aa52f620f442cc8d9ce7a8b5e798365595a38bb",
|
||||
"HASH160 0x14 0x3478e7019ce61a68148f87549579b704cbe4c393 EQUAL",
|
||||
"P2SH,WITNESS",
|
||||
"OK",
|
||||
"P2SH(P2WSH) CHECKMULTISIG second key uncompressed and signing with the first key"
|
||||
],
|
||||
[
|
||||
[
|
||||
"",
|
||||
"3044022046f5367a261fd8f8d7de6eb390491344f8ec2501638fb9a1095a0599a21d3f4c02205c1b3b51d20091c5f1020841bbca87b44ebe25405c64e4acf758f2eae8665f8401",
|
||||
"5141048282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f5150811f8a8098557dfe45e8256e830b60ace62d613ac2f7b17bed31b6eaff6e26caf210279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f8179852ae",
|
||||
0.00000001
|
||||
],
|
||||
"",
|
||||
"0 0x20 0x230828ed48871f0f362ce9432aa52f620f442cc8d9ce7a8b5e798365595a38bb",
|
||||
"P2SH,WITNESS,WITNESS_PUBKEYTYPE",
|
||||
"OK",
|
||||
"P2WSH CHECKMULTISIG with second key uncompressed and signing with the first key should pass as the uncompressed key is not used"
|
||||
],
|
||||
[
|
||||
[
|
||||
"",
|
||||
"3044022053e210e4fb1881e6092fd75c3efc5163105599e246ded661c0ee2b5682cc2d6c02203a26b7ada8682a095b84c6d1b881637000b47d761fc837c4cee33555296d63f101",
|
||||
"5141048282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f5150811f8a8098557dfe45e8256e830b60ace62d613ac2f7b17bed31b6eaff6e26caf210279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f8179852ae",
|
||||
0.00000001
|
||||
],
|
||||
"0x22 0x0020230828ed48871f0f362ce9432aa52f620f442cc8d9ce7a8b5e798365595a38bb",
|
||||
"HASH160 0x14 0x3478e7019ce61a68148f87549579b704cbe4c393 EQUAL",
|
||||
"P2SH,WITNESS,WITNESS_PUBKEYTYPE",
|
||||
"OK",
|
||||
"P2SH(P2WSH) CHECKMULTISIG with second key uncompressed and signing with the first key should pass as the uncompressed key is not used"
|
||||
],
|
||||
[
|
||||
[
|
||||
"",
|
||||
"304402206c6d9f5daf85b54af2a93ec38b15ab27f205dbf5c735365ff12451e43613d1f40220736a44be63423ed5ebf53491618b7cc3d8a5093861908da853739c73717938b701",
|
||||
"5141048282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f5150811f8a8098557dfe45e8256e830b60ace62d613ac2f7b17bed31b6eaff6e26caf210279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f8179852ae",
|
||||
0.00000001
|
||||
],
|
||||
"",
|
||||
"0 0x20 0x230828ed48871f0f362ce9432aa52f620f442cc8d9ce7a8b5e798365595a38bb",
|
||||
"P2SH,WITNESS",
|
||||
"OK",
|
||||
"P2WSH CHECKMULTISIG with second key uncompressed and signing with the second key"
|
||||
],
|
||||
[
|
||||
[
|
||||
"",
|
||||
"30440220687871bc6144012d75baf585bb26ce13997f7d8c626f4d8825b069c3b2d064470220108936fe1c57327764782253e99090b09c203ec400ed35ce9e026ce2ecf842a001",
|
||||
"5141048282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f5150811f8a8098557dfe45e8256e830b60ace62d613ac2f7b17bed31b6eaff6e26caf210279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f8179852ae",
|
||||
0.00000001
|
||||
],
|
||||
"0x22 0x0020230828ed48871f0f362ce9432aa52f620f442cc8d9ce7a8b5e798365595a38bb",
|
||||
"HASH160 0x14 0x3478e7019ce61a68148f87549579b704cbe4c393 EQUAL",
|
||||
"P2SH,WITNESS",
|
||||
"OK",
|
||||
"P2SH(P2WSH) CHECKMULTISIG with second key uncompressed and signing with the second key"
|
||||
],
|
||||
[
|
||||
[
|
||||
"",
|
||||
"304402206c6d9f5daf85b54af2a93ec38b15ab27f205dbf5c735365ff12451e43613d1f40220736a44be63423ed5ebf53491618b7cc3d8a5093861908da853739c73717938b701",
|
||||
"5141048282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f5150811f8a8098557dfe45e8256e830b60ace62d613ac2f7b17bed31b6eaff6e26caf210279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f8179852ae",
|
||||
0.00000001
|
||||
],
|
||||
"",
|
||||
"0 0x20 0x230828ed48871f0f362ce9432aa52f620f442cc8d9ce7a8b5e798365595a38bb",
|
||||
"P2SH,WITNESS,WITNESS_PUBKEYTYPE",
|
||||
"WITNESS_PUBKEYTYPE",
|
||||
"P2WSH CHECKMULTISIG with second key uncompressed and signing with the second key"
|
||||
],
|
||||
[
|
||||
[
|
||||
"",
|
||||
"30440220687871bc6144012d75baf585bb26ce13997f7d8c626f4d8825b069c3b2d064470220108936fe1c57327764782253e99090b09c203ec400ed35ce9e026ce2ecf842a001",
|
||||
"5141048282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f5150811f8a8098557dfe45e8256e830b60ace62d613ac2f7b17bed31b6eaff6e26caf210279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f8179852ae",
|
||||
0.00000001
|
||||
],
|
||||
"0x22 0x0020230828ed48871f0f362ce9432aa52f620f442cc8d9ce7a8b5e798365595a38bb",
|
||||
"HASH160 0x14 0x3478e7019ce61a68148f87549579b704cbe4c393 EQUAL",
|
||||
"P2SH,WITNESS,WITNESS_PUBKEYTYPE",
|
||||
"WITNESS_PUBKEYTYPE",
|
||||
"P2SH(P2WSH) CHECKMULTISIG with second key uncompressed and signing with the second key"
|
||||
],
|
||||
|
||||
["CHECKSEQUENCEVERIFY tests"],
|
||||
["", "CHECKSEQUENCEVERIFY", "CHECKSEQUENCEVERIFY", "INVALID_STACK_OPERATION", "CSV automatically fails on a empty stack"],
|
||||
["-1", "CHECKSEQUENCEVERIFY", "CHECKSEQUENCEVERIFY", "NEGATIVE_LOCKTIME", "CSV automatically fails if stack top is negative"],
|
||||
@ -2513,88 +1858,6 @@
|
||||
["4294967296", "CHECKSEQUENCEVERIFY", "CHECKSEQUENCEVERIFY", "UNSATISFIED_LOCKTIME",
|
||||
"CSV fails if stack top bit 1 << 31 is not set, and tx version < 2"],
|
||||
|
||||
["MINIMALIF tests"],
|
||||
["MINIMALIF is not applied to non-segwit scripts"],
|
||||
["1", "IF 1 ENDIF", "P2SH,WITNESS,MINIMALIF", "OK"],
|
||||
["2", "IF 1 ENDIF", "P2SH,WITNESS,MINIMALIF", "OK"],
|
||||
["0x02 0x0100", "IF 1 ENDIF", "P2SH,WITNESS,MINIMALIF", "OK"],
|
||||
["0", "IF 1 ENDIF", "P2SH,WITNESS,MINIMALIF", "EVAL_FALSE"],
|
||||
["0x01 0x00", "IF 1 ENDIF", "P2SH,WITNESS,MINIMALIF", "EVAL_FALSE"],
|
||||
["1", "NOTIF 1 ENDIF", "P2SH,WITNESS,MINIMALIF", "EVAL_FALSE"],
|
||||
["2", "NOTIF 1 ENDIF", "P2SH,WITNESS,MINIMALIF", "EVAL_FALSE"],
|
||||
["0x02 0x0100", "NOTIF 1 ENDIF", "P2SH,WITNESS,MINIMALIF", "EVAL_FALSE"],
|
||||
["0", "NOTIF 1 ENDIF", "P2SH,WITNESS,MINIMALIF", "OK"],
|
||||
["0x01 0x00", "NOTIF 1 ENDIF", "P2SH,WITNESS,MINIMALIF", "OK"],
|
||||
["Normal P2SH IF 1 ENDIF"],
|
||||
["1 0x03 0x635168", "HASH160 0x14 0xe7309652a8e3f600f06f5d8d52d6df03d2176cc3 EQUAL", "P2SH,WITNESS,MINIMALIF", "OK"],
|
||||
["2 0x03 0x635168", "HASH160 0x14 0xe7309652a8e3f600f06f5d8d52d6df03d2176cc3 EQUAL", "P2SH,WITNESS,MINIMALIF", "OK"],
|
||||
["0x02 0x0100 0x03 0x635168", "HASH160 0x14 0xe7309652a8e3f600f06f5d8d52d6df03d2176cc3 EQUAL", "P2SH,WITNESS,MINIMALIF", "OK"],
|
||||
["0 0x03 0x635168", "HASH160 0x14 0xe7309652a8e3f600f06f5d8d52d6df03d2176cc3 EQUAL", "P2SH,WITNESS,MINIMALIF", "EVAL_FALSE"],
|
||||
["0x01 0x00 0x03 0x635168", "HASH160 0x14 0xe7309652a8e3f600f06f5d8d52d6df03d2176cc3 EQUAL", "P2SH,WITNESS,MINIMALIF", "EVAL_FALSE"],
|
||||
["0x03 0x635168", "HASH160 0x14 0xe7309652a8e3f600f06f5d8d52d6df03d2176cc3 EQUAL", "P2SH,WITNESS,MINIMALIF", "UNBALANCED_CONDITIONAL"],
|
||||
["Normal P2SH NOTIF 1 ENDIF"],
|
||||
["1 0x03 0x645168", "HASH160 0x14 0x0c3f8fe3d6ca266e76311ecda544c67d15fdd5b0 EQUAL", "P2SH,WITNESS,MINIMALIF", "EVAL_FALSE"],
|
||||
["2 0x03 0x645168", "HASH160 0x14 0x0c3f8fe3d6ca266e76311ecda544c67d15fdd5b0 EQUAL", "P2SH,WITNESS,MINIMALIF", "EVAL_FALSE"],
|
||||
["0x02 0x0100 0x03 0x645168", "HASH160 0x14 0x0c3f8fe3d6ca266e76311ecda544c67d15fdd5b0 EQUAL", "P2SH,WITNESS,MINIMALIF", "EVAL_FALSE"],
|
||||
["0 0x03 0x645168", "HASH160 0x14 0x0c3f8fe3d6ca266e76311ecda544c67d15fdd5b0 EQUAL", "P2SH,WITNESS,MINIMALIF", "OK"],
|
||||
["0x01 0x00 0x03 0x645168", "HASH160 0x14 0x0c3f8fe3d6ca266e76311ecda544c67d15fdd5b0 EQUAL", "P2SH,WITNESS,MINIMALIF", "OK"],
|
||||
["0x03 0x645168", "HASH160 0x14 0x0c3f8fe3d6ca266e76311ecda544c67d15fdd5b0 EQUAL", "P2SH,WITNESS,MINIMALIF", "UNBALANCED_CONDITIONAL"],
|
||||
["P2WSH IF 1 ENDIF"],
|
||||
[["01", "635168", 0.00000001], "", "0 0x20 0xc7eaf06d5ae01a58e376e126eb1e6fab2036076922b96b2711ffbec1e590665d", "P2SH,WITNESS", "OK"],
|
||||
[["02", "635168", 0.00000001], "", "0 0x20 0xc7eaf06d5ae01a58e376e126eb1e6fab2036076922b96b2711ffbec1e590665d", "P2SH,WITNESS", "OK"],
|
||||
[["0100", "635168", 0.00000001], "", "0 0x20 0xc7eaf06d5ae01a58e376e126eb1e6fab2036076922b96b2711ffbec1e590665d", "P2SH,WITNESS", "OK"],
|
||||
[["", "635168", 0.00000001], "", "0 0x20 0xc7eaf06d5ae01a58e376e126eb1e6fab2036076922b96b2711ffbec1e590665d", "P2SH,WITNESS", "EVAL_FALSE"],
|
||||
[["00", "635168", 0.00000001], "", "0 0x20 0xc7eaf06d5ae01a58e376e126eb1e6fab2036076922b96b2711ffbec1e590665d", "P2SH,WITNESS", "EVAL_FALSE"],
|
||||
[["01", "635168", 0.00000001], "", "0 0x20 0xc7eaf06d5ae01a58e376e126eb1e6fab2036076922b96b2711ffbec1e590665d", "P2SH,WITNESS,MINIMALIF", "OK"],
|
||||
[["02", "635168", 0.00000001], "", "0 0x20 0xc7eaf06d5ae01a58e376e126eb1e6fab2036076922b96b2711ffbec1e590665d", "P2SH,WITNESS,MINIMALIF", "MINIMALIF"],
|
||||
[["0100", "635168", 0.00000001], "", "0 0x20 0xc7eaf06d5ae01a58e376e126eb1e6fab2036076922b96b2711ffbec1e590665d", "P2SH,WITNESS,MINIMALIF", "MINIMALIF"],
|
||||
[["", "635168", 0.00000001], "", "0 0x20 0xc7eaf06d5ae01a58e376e126eb1e6fab2036076922b96b2711ffbec1e590665d", "P2SH,WITNESS,MINIMALIF", "EVAL_FALSE"],
|
||||
[["00", "635168", 0.00000001], "", "0 0x20 0xc7eaf06d5ae01a58e376e126eb1e6fab2036076922b96b2711ffbec1e590665d", "P2SH,WITNESS,MINIMALIF", "MINIMALIF"],
|
||||
[["635168", 0.00000001], "", "0 0x20 0xc7eaf06d5ae01a58e376e126eb1e6fab2036076922b96b2711ffbec1e590665d", "P2SH,WITNESS", "UNBALANCED_CONDITIONAL"],
|
||||
[["635168", 0.00000001], "", "0 0x20 0xc7eaf06d5ae01a58e376e126eb1e6fab2036076922b96b2711ffbec1e590665d", "P2SH,WITNESS,MINIMALIF", "UNBALANCED_CONDITIONAL"],
|
||||
["P2WSH NOTIF 1 ENDIF"],
|
||||
[["01", "645168", 0.00000001], "", "0 0x20 0xf913eacf2e38a5d6fc3a8311d72ae704cb83866350a984dd3e5eb76d2a8c28e8", "P2SH,WITNESS", "EVAL_FALSE"],
|
||||
[["02", "645168", 0.00000001], "", "0 0x20 0xf913eacf2e38a5d6fc3a8311d72ae704cb83866350a984dd3e5eb76d2a8c28e8", "P2SH,WITNESS", "EVAL_FALSE"],
|
||||
[["0100", "645168", 0.00000001], "", "0 0x20 0xf913eacf2e38a5d6fc3a8311d72ae704cb83866350a984dd3e5eb76d2a8c28e8", "P2SH,WITNESS", "EVAL_FALSE"],
|
||||
[["", "645168", 0.00000001], "", "0 0x20 0xf913eacf2e38a5d6fc3a8311d72ae704cb83866350a984dd3e5eb76d2a8c28e8", "P2SH,WITNESS", "OK"],
|
||||
[["00", "645168", 0.00000001], "", "0 0x20 0xf913eacf2e38a5d6fc3a8311d72ae704cb83866350a984dd3e5eb76d2a8c28e8", "P2SH,WITNESS", "OK"],
|
||||
[["01", "645168", 0.00000001], "", "0 0x20 0xf913eacf2e38a5d6fc3a8311d72ae704cb83866350a984dd3e5eb76d2a8c28e8", "P2SH,WITNESS,MINIMALIF", "EVAL_FALSE"],
|
||||
[["02", "645168", 0.00000001], "", "0 0x20 0xf913eacf2e38a5d6fc3a8311d72ae704cb83866350a984dd3e5eb76d2a8c28e8", "P2SH,WITNESS,MINIMALIF", "MINIMALIF"],
|
||||
[["0100", "645168", 0.00000001], "", "0 0x20 0xf913eacf2e38a5d6fc3a8311d72ae704cb83866350a984dd3e5eb76d2a8c28e8", "P2SH,WITNESS,MINIMALIF", "MINIMALIF"],
|
||||
[["", "645168", 0.00000001], "", "0 0x20 0xf913eacf2e38a5d6fc3a8311d72ae704cb83866350a984dd3e5eb76d2a8c28e8", "P2SH,WITNESS,MINIMALIF", "OK"],
|
||||
[["00", "645168", 0.00000001], "", "0 0x20 0xf913eacf2e38a5d6fc3a8311d72ae704cb83866350a984dd3e5eb76d2a8c28e8", "P2SH,WITNESS,MINIMALIF", "MINIMALIF"],
|
||||
[["645168", 0.00000001], "", "0 0x20 0xf913eacf2e38a5d6fc3a8311d72ae704cb83866350a984dd3e5eb76d2a8c28e8", "P2SH,WITNESS", "UNBALANCED_CONDITIONAL"],
|
||||
[["645168", 0.00000001], "", "0 0x20 0xf913eacf2e38a5d6fc3a8311d72ae704cb83866350a984dd3e5eb76d2a8c28e8", "P2SH,WITNESS,MINIMALIF", "UNBALANCED_CONDITIONAL"],
|
||||
|
||||
|
||||
|
||||
["P2SH-P2WSH IF 1 ENDIF"],
|
||||
[["01", "635168", 0.00000001], "0x22 0x0020c7eaf06d5ae01a58e376e126eb1e6fab2036076922b96b2711ffbec1e590665d", "HASH160 0x14 0x9b27ee6d9010c21bf837b334d043be5d150e7ba7 EQUAL", "P2SH,WITNESS", "OK"],
|
||||
[["02", "635168", 0.00000001], "0x22 0x0020c7eaf06d5ae01a58e376e126eb1e6fab2036076922b96b2711ffbec1e590665d", "HASH160 0x14 0x9b27ee6d9010c21bf837b334d043be5d150e7ba7 EQUAL", "P2SH,WITNESS", "OK"],
|
||||
[["0100", "635168", 0.00000001], "0x22 0x0020c7eaf06d5ae01a58e376e126eb1e6fab2036076922b96b2711ffbec1e590665d", "HASH160 0x14 0x9b27ee6d9010c21bf837b334d043be5d150e7ba7 EQUAL", "P2SH,WITNESS", "OK"],
|
||||
[["", "635168", 0.00000001], "0x22 0x0020c7eaf06d5ae01a58e376e126eb1e6fab2036076922b96b2711ffbec1e590665d", "HASH160 0x14 0x9b27ee6d9010c21bf837b334d043be5d150e7ba7 EQUAL", "P2SH,WITNESS", "EVAL_FALSE"],
|
||||
[["00", "635168", 0.00000001], "0x22 0x0020c7eaf06d5ae01a58e376e126eb1e6fab2036076922b96b2711ffbec1e590665d", "HASH160 0x14 0x9b27ee6d9010c21bf837b334d043be5d150e7ba7 EQUAL", "P2SH,WITNESS", "EVAL_FALSE"],
|
||||
[["01", "635168", 0.00000001], "0x22 0x0020c7eaf06d5ae01a58e376e126eb1e6fab2036076922b96b2711ffbec1e590665d", "HASH160 0x14 0x9b27ee6d9010c21bf837b334d043be5d150e7ba7 EQUAL", "P2SH,WITNESS,MINIMALIF", "OK"],
|
||||
[["02", "635168", 0.00000001], "0x22 0x0020c7eaf06d5ae01a58e376e126eb1e6fab2036076922b96b2711ffbec1e590665d", "HASH160 0x14 0x9b27ee6d9010c21bf837b334d043be5d150e7ba7 EQUAL", "P2SH,WITNESS,MINIMALIF", "MINIMALIF"],
|
||||
[["0100", "635168", 0.00000001], "0x22 0x0020c7eaf06d5ae01a58e376e126eb1e6fab2036076922b96b2711ffbec1e590665d", "HASH160 0x14 0x9b27ee6d9010c21bf837b334d043be5d150e7ba7 EQUAL", "P2SH,WITNESS,MINIMALIF", "MINIMALIF"],
|
||||
[["", "635168", 0.00000001], "0x22 0x0020c7eaf06d5ae01a58e376e126eb1e6fab2036076922b96b2711ffbec1e590665d", "HASH160 0x14 0x9b27ee6d9010c21bf837b334d043be5d150e7ba7 EQUAL", "P2SH,WITNESS,MINIMALIF", "EVAL_FALSE"],
|
||||
[["00", "635168", 0.00000001], "0x22 0x0020c7eaf06d5ae01a58e376e126eb1e6fab2036076922b96b2711ffbec1e590665d", "HASH160 0x14 0x9b27ee6d9010c21bf837b334d043be5d150e7ba7 EQUAL", "P2SH,WITNESS,MINIMALIF", "MINIMALIF"],
|
||||
[["635168", 0.00000001], "0x22 0x0020c7eaf06d5ae01a58e376e126eb1e6fab2036076922b96b2711ffbec1e590665d", "HASH160 0x14 0x9b27ee6d9010c21bf837b334d043be5d150e7ba7 EQUAL", "P2SH,WITNESS", "UNBALANCED_CONDITIONAL"],
|
||||
[["635168", 0.00000001], "0x22 0x0020c7eaf06d5ae01a58e376e126eb1e6fab2036076922b96b2711ffbec1e590665d", "HASH160 0x14 0x9b27ee6d9010c21bf837b334d043be5d150e7ba7 EQUAL", "P2SH,WITNESS,MINIMALIF", "UNBALANCED_CONDITIONAL"],
|
||||
["P2SH-P2WSH NOTIF 1 ENDIF"],
|
||||
[["01", "645168", 0.00000001], "0x22 0x0020f913eacf2e38a5d6fc3a8311d72ae704cb83866350a984dd3e5eb76d2a8c28e8", "HASH160 0x14 0xdbb7d1c0a56b7a9c423300c8cca6e6e065baf1dc EQUAL", "P2SH,WITNESS", "EVAL_FALSE"],
|
||||
[["02", "645168", 0.00000001], "0x22 0x0020f913eacf2e38a5d6fc3a8311d72ae704cb83866350a984dd3e5eb76d2a8c28e8", "HASH160 0x14 0xdbb7d1c0a56b7a9c423300c8cca6e6e065baf1dc EQUAL", "P2SH,WITNESS", "EVAL_FALSE"],
|
||||
[["0100", "645168", 0.00000001], "0x22 0x0020f913eacf2e38a5d6fc3a8311d72ae704cb83866350a984dd3e5eb76d2a8c28e8", "HASH160 0x14 0xdbb7d1c0a56b7a9c423300c8cca6e6e065baf1dc EQUAL", "P2SH,WITNESS", "EVAL_FALSE"],
|
||||
[["", "645168", 0.00000001], "0x22 0x0020f913eacf2e38a5d6fc3a8311d72ae704cb83866350a984dd3e5eb76d2a8c28e8", "HASH160 0x14 0xdbb7d1c0a56b7a9c423300c8cca6e6e065baf1dc EQUAL", "P2SH,WITNESS", "OK"],
|
||||
[["00", "645168", 0.00000001], "0x22 0x0020f913eacf2e38a5d6fc3a8311d72ae704cb83866350a984dd3e5eb76d2a8c28e8", "HASH160 0x14 0xdbb7d1c0a56b7a9c423300c8cca6e6e065baf1dc EQUAL", "P2SH,WITNESS", "OK"],
|
||||
[["01", "645168", 0.00000001], "0x22 0x0020f913eacf2e38a5d6fc3a8311d72ae704cb83866350a984dd3e5eb76d2a8c28e8", "HASH160 0x14 0xdbb7d1c0a56b7a9c423300c8cca6e6e065baf1dc EQUAL", "P2SH,WITNESS,MINIMALIF", "EVAL_FALSE"],
|
||||
[["02", "645168", 0.00000001], "0x22 0x0020f913eacf2e38a5d6fc3a8311d72ae704cb83866350a984dd3e5eb76d2a8c28e8", "HASH160 0x14 0xdbb7d1c0a56b7a9c423300c8cca6e6e065baf1dc EQUAL", "P2SH,WITNESS,MINIMALIF", "MINIMALIF"],
|
||||
[["0100", "645168", 0.00000001], "0x22 0x0020f913eacf2e38a5d6fc3a8311d72ae704cb83866350a984dd3e5eb76d2a8c28e8", "HASH160 0x14 0xdbb7d1c0a56b7a9c423300c8cca6e6e065baf1dc EQUAL", "P2SH,WITNESS,MINIMALIF", "MINIMALIF"],
|
||||
[["", "645168", 0.00000001], "0x22 0x0020f913eacf2e38a5d6fc3a8311d72ae704cb83866350a984dd3e5eb76d2a8c28e8", "HASH160 0x14 0xdbb7d1c0a56b7a9c423300c8cca6e6e065baf1dc EQUAL", "P2SH,WITNESS,MINIMALIF", "OK"],
|
||||
[["00", "645168", 0.00000001], "0x22 0x0020f913eacf2e38a5d6fc3a8311d72ae704cb83866350a984dd3e5eb76d2a8c28e8", "HASH160 0x14 0xdbb7d1c0a56b7a9c423300c8cca6e6e065baf1dc EQUAL", "P2SH,WITNESS,MINIMALIF", "MINIMALIF"],
|
||||
[["645168", 0.00000001], "0x22 0x0020f913eacf2e38a5d6fc3a8311d72ae704cb83866350a984dd3e5eb76d2a8c28e8", "HASH160 0x14 0xdbb7d1c0a56b7a9c423300c8cca6e6e065baf1dc EQUAL", "P2SH,WITNESS", "UNBALANCED_CONDITIONAL"],
|
||||
[["645168", 0.00000001], "0x22 0x0020f913eacf2e38a5d6fc3a8311d72ae704cb83866350a984dd3e5eb76d2a8c28e8", "HASH160 0x14 0xdbb7d1c0a56b7a9c423300c8cca6e6e065baf1dc EQUAL", "P2SH,WITNESS,MINIMALIF", "UNBALANCED_CONDITIONAL"],
|
||||
|
||||
["NULLFAIL should cover all signatures and signatures only"],
|
||||
["0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0", "0x01 0x14 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0x01 0x14 CHECKMULTISIG NOT", "DERSIG", "OK", "BIP66 and NULLFAIL-compliant"],
|
||||
["0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0", "0x01 0x14 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0x01 0x14 CHECKMULTISIG NOT", "DERSIG,NULLFAIL", "OK", "BIP66 and NULLFAIL-compliant"],
|
||||
|
@ -245,94 +245,5 @@
|
||||
[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "4194304 CHECKSEQUENCEVERIFY 1"]],
|
||||
"010000000100010000000000000000000000000000000000000000000000000000000000000000000000000040000100000000000000000000000000", "P2SH,CHECKSEQUENCEVERIFY"],
|
||||
|
||||
["Unknown witness program version (with DISCOURAGE_UPGRADABLE_WITNESS_PROGRAM)"],
|
||||
[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0x51", 1000],
|
||||
["0000000000000000000000000000000000000000000000000000000000000100", 1, "0x60 0x14 0x4c9c3dfac4207d5d8cb89df5722cb3d712385e3f", 2000],
|
||||
["0000000000000000000000000000000000000000000000000000000000000100", 2, "0x51", 3000]],
|
||||
"0100000000010300010000000000000000000000000000000000000000000000000000000000000000000000ffffffff00010000000000000000000000000000000000000000000000000000000000000100000000ffffffff00010000000000000000000000000000000000000000000000000000000000000200000000ffffffff03e8030000000000000151d0070000000000000151b80b00000000000001510002483045022100a3cec69b52cba2d2de623ffffffffff1606184ea55476c0f8189fda231bc9cbb022003181ad597f7c380a7d1c740286b1d022b8b04ded028b833282e055e03b8efef812103596d3451025c19dbbdeb932d6bf8bfb4ad499b95b6f88db8899efac102e5fc710000000000", "P2SH,WITNESS,DISCOURAGE_UPGRADABLE_WITNESS_PROGRAM"],
|
||||
|
||||
["Unknown length for witness program v0"],
|
||||
[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0x51", 1000],
|
||||
["0000000000000000000000000000000000000000000000000000000000000100", 1, "0x00 0x15 0x4c9c3dfac4207d5d8cb89df5722cb3d712385e3fff", 2000],
|
||||
["0000000000000000000000000000000000000000000000000000000000000100", 2, "0x51", 3000]],
|
||||
"0100000000010300010000000000000000000000000000000000000000000000000000000000000000000000ffffffff00010000000000000000000000000000000000000000000000000000000000000100000000ffffffff00010000000000000000000000000000000000000000000000000000000000000200000000ffffffff04b60300000000000001519e070000000000000151860b0000000000000100960000000000000001510002473044022022fceb54f62f8feea77faac7083c3b56c4676a78f93745adc8a35800bc36adfa022026927df9abcf0a8777829bcfcce3ff0a385fa54c3f9df577405e3ef24ee56479022103596d3451025c19dbbdeb932d6bf8bfb4ad499b95b6f88db8899efac102e5fc710000000000", "P2SH,WITNESS"],
|
||||
|
||||
["Witness with SigHash Single|AnyoneCanPay (same index output value changed)"],
|
||||
[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0x51", 1000],
|
||||
["0000000000000000000000000000000000000000000000000000000000000100", 1, "0x00 0x14 0x4c9c3dfac4207d5d8cb89df5722cb3d712385e3f", 2000],
|
||||
["0000000000000000000000000000000000000000000000000000000000000100", 2, "0x51", 3000]],
|
||||
"0100000000010300010000000000000000000000000000000000000000000000000000000000000000000000ffffffff00010000000000000000000000000000000000000000000000000000000000000100000000ffffffff00010000000000000000000000000000000000000000000000000000000000000200000000ffffffff03e80300000000000001516c070000000000000151b80b0000000000000151000248304502210092f4777a0f17bf5aeb8ae768dec5f2c14feabf9d1fe2c89c78dfed0f13fdb86902206da90a86042e252bcd1e80a168c719e4a1ddcc3cebea24b9812c5453c79107e9832103596d3451025c19dbbdeb932d6bf8bfb4ad499b95b6f88db8899efac102e5fc710000000000", "P2SH,WITNESS"],
|
||||
|
||||
["Witness with SigHash None|AnyoneCanPay (input sequence changed)"],
|
||||
[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0x51", 1000],
|
||||
["0000000000000000000000000000000000000000000000000000000000000100", 1, "0x00 0x14 0x4c9c3dfac4207d5d8cb89df5722cb3d712385e3f", 2000],
|
||||
["0000000000000000000000000000000000000000000000000000000000000100", 2, "0x51", 3000]],
|
||||
"0100000000010300010000000000000000000000000000000000000000000000000000000000000000000000ffffffff000100000000000000000000000000000000000000000000000000000000000001000000000100000000010000000000000000000000000000000000000000000000000000000000000200000000ffffffff00000248304502210091b32274295c2a3fa02f5bce92fb2789e3fc6ea947fbe1a76e52ea3f4ef2381a022079ad72aefa3837a2e0c033a8652a59731da05fa4a813f4fc48e87c075037256b822103596d3451025c19dbbdeb932d6bf8bfb4ad499b95b6f88db8899efac102e5fc710000000000", "P2SH,WITNESS"],
|
||||
|
||||
["Witness with SigHash All|AnyoneCanPay (third output value changed)"],
|
||||
[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0x51", 1000],
|
||||
["0000000000000000000000000000000000000000000000000000000000000100", 1, "0x00 0x14 0x4c9c3dfac4207d5d8cb89df5722cb3d712385e3f", 2000],
|
||||
["0000000000000000000000000000000000000000000000000000000000000100", 2, "0x51", 3000]],
|
||||
"0100000000010300010000000000000000000000000000000000000000000000000000000000000000000000ffffffff00010000000000000000000000000000000000000000000000000000000000000100000000ffffffff00010000000000000000000000000000000000000000000000000000000000000200000000ffffffff03e8030000000000000151d0070000000000000151540b00000000000001510002483045022100a3cec69b52cba2d2de623eeef89e0ba1606184ea55476c0f8189fda231bc9cbb022003181ad597f7c380a7d1c740286b1d022b8b04ded028b833282e055e03b8efef812103596d3451025c19dbbdeb932d6bf8bfb4ad499b95b6f88db8899efac102e5fc710000000000", "P2SH,WITNESS"],
|
||||
|
||||
["Witness with a push of 521 bytes"],
|
||||
[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0x00 0x20 0x33198a9bfef674ebddb9ffaa52928017b8472791e54c609cb95f278ac6b1e349", 1000]],
|
||||
"0100000000010100010000000000000000000000000000000000000000000000000000000000000000000000ffffffff010000000000000000015102fd0902000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002755100000000", "P2SH,WITNESS"],
|
||||
|
||||
["Witness with unknown version which push false on the stack should be invalid (even without DISCOURAGE_UPGRADABLE_WITNESS_PROGRAM)"],
|
||||
[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0x60 0x02 0x0000", 2000]],
|
||||
"0100000000010100010000000000000000000000000000000000000000000000000000000000000000000000ffffffff010000000000000000015101010100000000", "P2SH,WITNESS"],
|
||||
|
||||
["Witness program should leave clean stack"],
|
||||
[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0x00 0x20 0x2f04a3aa051f1f60d695f6c44c0c3d383973dfd446ace8962664a76bb10e31a8", 2000]],
|
||||
"0100000000010100010000000000000000000000000000000000000000000000000000000000000000000000ffffffff01000000000000000001510102515100000000", "P2SH,WITNESS"],
|
||||
|
||||
["Witness v0 with a push of 2 bytes"],
|
||||
[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0x00 0x02 0x0001", 2000]],
|
||||
"0100000000010100010000000000000000000000000000000000000000000000000000000000000000000000ffffffff010000000000000000015101040002000100000000", "P2SH,WITNESS"],
|
||||
|
||||
["Unknown witness version with non empty scriptSig"],
|
||||
[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0x60 0x02 0x0001", 2000]],
|
||||
"01000000010001000000000000000000000000000000000000000000000000000000000000000000000151ffffffff010000000000000000015100000000", "P2SH,WITNESS"],
|
||||
|
||||
["Non witness Single|AnyoneCanPay hash input's position (permutation)"],
|
||||
[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0x21 0x03596d3451025c19dbbdeb932d6bf8bfb4ad499b95b6f88db8899efac102e5fc71 CHECKSIG", 1000],
|
||||
["0000000000000000000000000000000000000000000000000000000000000100", 1, "0x21 0x03596d3451025c19dbbdeb932d6bf8bfb4ad499b95b6f88db8899efac102e5fc71 CHECKSIG", 1001]],
|
||||
"010000000200010000000000000000000000000000000000000000000000000000000000000100000049483045022100acb96cfdbda6dc94b489fd06f2d720983b5f350e31ba906cdbd800773e80b21c02200d74ea5bdf114212b4bbe9ed82c36d2e369e302dff57cb60d01c428f0bd3daab83ffffffff0001000000000000000000000000000000000000000000000000000000000000000000004847304402202a0b4b1294d70540235ae033d78e64b4897ec859c7b6f1b2b1d8a02e1d46006702201445e756d2254b0f1dfda9ab8e1e1bc26df9668077403204f32d16a49a36eb6983ffffffff02e9030000000000000151e803000000000000015100000000", "P2SH,WITNESS"],
|
||||
|
||||
["P2WSH with a redeem representing a witness scriptPubKey should fail"],
|
||||
[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0x00 0x20 0x34b6c399093e06cf9f0f7f660a1abcfe78fcf7b576f43993208edd9518a0ae9b", 1000]],
|
||||
"0100000000010100010000000000000000000000000000000000000000000000000000000000000000000000ffffffff0001045102010100000000", "P2SH,WITNESS"],
|
||||
|
||||
["33 bytes push should be considered a witness scriptPubKey"],
|
||||
[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0x60 0x21 0xff25429251b5a84f452230a3c75fd886b7fc5a7865ce4a7bb7a9d7c5be6da3dbff", 1000]],
|
||||
"010000000100010000000000000000000000000000000000000000000000000000000000000000000000ffffffff01e803000000000000015100000000", "P2SH,WITNESS,DISCOURAGE_UPGRADABLE_WITNESS_PROGRAM"],
|
||||
|
||||
["FindAndDelete tests"],
|
||||
["This is a test of FindAndDelete. The first tx is a spend of normal scriptPubKey and the second tx is a spend of bare P2WSH."],
|
||||
["The redeemScript/witnessScript is CHECKSIGVERIFY <0x30450220487fb382c4974de3f7d834c1b617fe15860828c7f96454490edd6d891556dcc9022100baf95feb48f845d5bfc9882eb6aeefa1bc3790e39f59eaa46ff7f15ae626c53e01>."],
|
||||
["The signature is <0x30450220487fb382c4974de3f7d834c1b617fe15860828c7f96454490edd6d891556dcc9022100baf95feb48f845d5bfc9882eb6aeefa1bc3790e39f59eaa46ff7f15ae626c53e01> <pubkey>,"],
|
||||
["where the pubkey is obtained through key recovery with sig and the wrong sighash."],
|
||||
["This is to show that FindAndDelete is applied only to non-segwit scripts"],
|
||||
["To show that the tests are 'correctly wrong', they should pass by modifying OP_CHECKSIG under interpreter.cpp"],
|
||||
["by replacing (sigversion == SIGVERSION_BASE) with (sigversion != SIGVERSION_BASE)"],
|
||||
["Non-segwit: wrong sighash (without FindAndDelete) = 1ba1fe3bc90c5d1265460e684ce6774e324f0fabdf67619eda729e64e8b6bc08"],
|
||||
[[["f18783ace138abac5d3a7a5cf08e88fe6912f267ef936452e0c27d090621c169", 7000, "HASH160 0x14 0x0c746489e2d83cdbb5b90b432773342ba809c134 EQUAL", 200000]],
|
||||
"010000000169c12106097dc2e0526493ef67f21269fe888ef05c7a3a5dacab38e1ac8387f1581b0000b64830450220487fb382c4974de3f7d834c1b617fe15860828c7f96454490edd6d891556dcc9022100baf95feb48f845d5bfc9882eb6aeefa1bc3790e39f59eaa46ff7f15ae626c53e012103b12a1ec8428fc74166926318c15e17408fea82dbb157575e16a8c365f546248f4aad4830450220487fb382c4974de3f7d834c1b617fe15860828c7f96454490edd6d891556dcc9022100baf95feb48f845d5bfc9882eb6aeefa1bc3790e39f59eaa46ff7f15ae626c53e01ffffffff0101000000000000000000000000", "P2SH,WITNESS"],
|
||||
["BIP143: wrong sighash (with FindAndDelete) = 71c9cd9b2869b9c70b01b1f0360c148f42dee72297db312638df136f43311f23"],
|
||||
[[["f18783ace138abac5d3a7a5cf08e88fe6912f267ef936452e0c27d090621c169", 7500, "0x00 0x20 0x9e1be07558ea5cc8e02ed1d80c0911048afad949affa36d5c3951e3159dbea19", 200000]],
|
||||
"0100000000010169c12106097dc2e0526493ef67f21269fe888ef05c7a3a5dacab38e1ac8387f14c1d000000ffffffff01010000000000000000034830450220487fb382c4974de3f7d834c1b617fe15860828c7f96454490edd6d891556dcc9022100baf95feb48f845d5bfc9882eb6aeefa1bc3790e39f59eaa46ff7f15ae626c53e012102a9d7ed6e161f0e255c10bbfcca0128a9e2035c2c8da58899c54d22d3a31afdef4aad4830450220487fb382c4974de3f7d834c1b617fe15860828c7f96454490edd6d891556dcc9022100baf95feb48f845d5bfc9882eb6aeefa1bc3790e39f59eaa46ff7f15ae626c53e0100000000", "P2SH,WITNESS"],
|
||||
["This is multisig version of the FindAndDelete tests"],
|
||||
["Script is 2 CHECKMULTISIGVERIFY <sig1> <sig2> DROP"],
|
||||
["52af4830450220487fb382c4974de3f7d834c1b617fe15860828c7f96454490edd6d891556dcc9022100baf95feb48f845d5bfc9882eb6aeefa1bc3790e39f59eaa46ff7f15ae626c53e0148304502205286f726690b2e9b0207f0345711e63fa7012045b9eb0f19c2458ce1db90cf43022100e89f17f86abc5b149eba4115d4f128bcf45d77fb3ecdd34f594091340c0395960175"],
|
||||
["Signature is 0 <sig1> <sig2> 2 <key1> <key2>"],
|
||||
["Should pass by replacing (sigversion == SIGVERSION_BASE) with (sigversion != SIGVERSION_BASE) under OP_CHECKMULTISIG"],
|
||||
["Non-segwit: wrong sighash (without FindAndDelete) = 4bc6a53e8e16ef508c19e38bba08831daba85228b0211f323d4cb0999cf2a5e8"],
|
||||
[[["9628667ad48219a169b41b020800162287d2c0f713c04157e95c484a8dcb7592", 7000, "HASH160 0x14 0x5748407f5ca5cdca53ba30b79040260770c9ee1b EQUAL", 200000]],
|
||||
"01000000019275cb8d4a485ce95741c013f7c0d28722160008021bb469a11982d47a662896581b0000fd6f01004830450220487fb382c4974de3f7d834c1b617fe15860828c7f96454490edd6d891556dcc9022100baf95feb48f845d5bfc9882eb6aeefa1bc3790e39f59eaa46ff7f15ae626c53e0148304502205286f726690b2e9b0207f0345711e63fa7012045b9eb0f19c2458ce1db90cf43022100e89f17f86abc5b149eba4115d4f128bcf45d77fb3ecdd34f594091340c039596015221023fd5dd42b44769c5653cbc5947ff30ab8871f240ad0c0e7432aefe84b5b4ff3421039d52178dbde360b83f19cf348deb04fa8360e1bf5634577be8e50fafc2b0e4ef4c9552af4830450220487fb382c4974de3f7d834c1b617fe15860828c7f96454490edd6d891556dcc9022100baf95feb48f845d5bfc9882eb6aeefa1bc3790e39f59eaa46ff7f15ae626c53e0148304502205286f726690b2e9b0207f0345711e63fa7012045b9eb0f19c2458ce1db90cf43022100e89f17f86abc5b149eba4115d4f128bcf45d77fb3ecdd34f594091340c0395960175ffffffff0101000000000000000000000000", "P2SH,WITNESS"],
|
||||
["BIP143: wrong sighash (with FindAndDelete) = 17c50ec2181ecdfdc85ca081174b248199ba81fff730794d4f69b8ec031f2dce"],
|
||||
[[["9628667ad48219a169b41b020800162287d2c0f713c04157e95c484a8dcb7592", 7500, "0x00 0x20 0x9b66c15b4e0b4eb49fa877982cafded24859fe5b0e2dbfbe4f0df1de7743fd52", 200000]],
|
||||
"010000000001019275cb8d4a485ce95741c013f7c0d28722160008021bb469a11982d47a6628964c1d000000ffffffff0101000000000000000007004830450220487fb382c4974de3f7d834c1b617fe15860828c7f96454490edd6d891556dcc9022100baf95feb48f845d5bfc9882eb6aeefa1bc3790e39f59eaa46ff7f15ae626c53e0148304502205286f726690b2e9b0207f0345711e63fa7012045b9eb0f19c2458ce1db90cf43022100e89f17f86abc5b149eba4115d4f128bcf45d77fb3ecdd34f594091340c03959601010221023cb6055f4b57a1580c5a753e19610cafaedf7e0ff377731c77837fd666eae1712102c1b1db303ac232ffa8e5e7cc2cf5f96c6e40d3e6914061204c0541cb2043a0969552af4830450220487fb382c4974de3f7d834c1b617fe15860828c7f96454490edd6d891556dcc9022100baf95feb48f845d5bfc9882eb6aeefa1bc3790e39f59eaa46ff7f15ae626c53e0148304502205286f726690b2e9b0207f0345711e63fa7012045b9eb0f19c2458ce1db90cf43022100e89f17f86abc5b149eba4115d4f128bcf45d77fb3ecdd34f594091340c039596017500000000", "P2SH,WITNESS"],
|
||||
|
||||
["Make diffs cleaner by leaving a comment here without comma at the end"]
|
||||
]
|
||||
|
@ -317,198 +317,5 @@
|
||||
[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "HASH160 0x14 0x7c17aff532f22beb54069942f9bf567a66133eaf EQUAL"]],
|
||||
"0200000001000100000000000000000000000000000000000000000000000000000000000000000000030251b2010000000100000000000000000000000000", "P2SH,CHECKSEQUENCEVERIFY"],
|
||||
|
||||
["Valid P2WPKH (Private key of segwit tests is L5AQtV2HDm4xGsseLokK2VAT2EtYKcTm3c7HwqnJBFt9LdaQULsM)"],
|
||||
[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0x00 0x14 0x4c9c3dfac4207d5d8cb89df5722cb3d712385e3f", 1000]],
|
||||
"0100000000010100010000000000000000000000000000000000000000000000000000000000000000000000ffffffff01e8030000000000001976a9144c9c3dfac4207d5d8cb89df5722cb3d712385e3f88ac02483045022100cfb07164b36ba64c1b1e8c7720a56ad64d96f6ef332d3d37f9cb3c96477dc44502200a464cd7a9cf94cd70f66ce4f4f0625ef650052c7afcfe29d7d7e01830ff91ed012103596d3451025c19dbbdeb932d6bf8bfb4ad499b95b6f88db8899efac102e5fc7100000000", "P2SH,WITNESS"],
|
||||
|
||||
["Valid P2WSH"],
|
||||
[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0x00 0x20 0xff25429251b5a84f452230a3c75fd886b7fc5a7865ce4a7bb7a9d7c5be6da3db", 1000]],
|
||||
"0100000000010100010000000000000000000000000000000000000000000000000000000000000000000000ffffffff01e8030000000000001976a9144c9c3dfac4207d5d8cb89df5722cb3d712385e3f88ac02483045022100aa5d8aa40a90f23ce2c3d11bc845ca4a12acd99cbea37de6b9f6d86edebba8cb022022dedc2aa0a255f74d04c0b76ece2d7c691f9dd11a64a8ac49f62a99c3a05f9d01232103596d3451025c19dbbdeb932d6bf8bfb4ad499b95b6f88db8899efac102e5fc71ac00000000", "P2SH,WITNESS"],
|
||||
|
||||
["Valid P2SH(P2WPKH)"],
|
||||
[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "HASH160 0x14 0xfe9c7dacc9fcfbf7e3b7d5ad06aa2b28c5a7b7e3 EQUAL", 1000]],
|
||||
"01000000000101000100000000000000000000000000000000000000000000000000000000000000000000171600144c9c3dfac4207d5d8cb89df5722cb3d712385e3fffffffff01e8030000000000001976a9144c9c3dfac4207d5d8cb89df5722cb3d712385e3f88ac02483045022100cfb07164b36ba64c1b1e8c7720a56ad64d96f6ef332d3d37f9cb3c96477dc44502200a464cd7a9cf94cd70f66ce4f4f0625ef650052c7afcfe29d7d7e01830ff91ed012103596d3451025c19dbbdeb932d6bf8bfb4ad499b95b6f88db8899efac102e5fc7100000000", "P2SH,WITNESS"],
|
||||
|
||||
["Valid P2SH(P2WSH)"],
|
||||
[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "HASH160 0x14 0x2135ab4f0981830311e35600eebc7376dce3a914 EQUAL", 1000]],
|
||||
"0100000000010100010000000000000000000000000000000000000000000000000000000000000000000023220020ff25429251b5a84f452230a3c75fd886b7fc5a7865ce4a7bb7a9d7c5be6da3dbffffffff01e8030000000000001976a9144c9c3dfac4207d5d8cb89df5722cb3d712385e3f88ac02483045022100aa5d8aa40a90f23ce2c3d11bc845ca4a12acd99cbea37de6b9f6d86edebba8cb022022dedc2aa0a255f74d04c0b76ece2d7c691f9dd11a64a8ac49f62a99c3a05f9d01232103596d3451025c19dbbdeb932d6bf8bfb4ad499b95b6f88db8899efac102e5fc71ac00000000", "P2SH,WITNESS"],
|
||||
|
||||
["Witness with SigHash Single|AnyoneCanPay"],
|
||||
[[["0000000000000000000000000000000000000000000000000000000000000100", 2, "0x51", 3100],
|
||||
["0000000000000000000000000000000000000000000000000000000000000100", 1, "0x00 0x14 0x4c9c3dfac4207d5d8cb89df5722cb3d712385e3f", 2000],
|
||||
["0000000000000000000000000000000000000000000000000000000000000100", 0, "0x51", 1100],
|
||||
["0000000000000000000000000000000000000000000000000000000000000100", 3, "0x51", 4100]],
|
||||
"0100000000010400010000000000000000000000000000000000000000000000000000000000000200000000ffffffff00010000000000000000000000000000000000000000000000000000000000000100000000ffffffff00010000000000000000000000000000000000000000000000000000000000000000000000ffffffff00010000000000000000000000000000000000000000000000000000000000000300000000ffffffff05540b0000000000000151d0070000000000000151840300000000000001513c0f00000000000001512c010000000000000151000248304502210092f4777a0f17bf5aeb8ae768dec5f2c14feabf9d1fe2c89c78dfed0f13fdb86902206da90a86042e252bcd1e80a168c719e4a1ddcc3cebea24b9812c5453c79107e9832103596d3451025c19dbbdeb932d6bf8bfb4ad499b95b6f88db8899efac102e5fc71000000000000", "P2SH,WITNESS"],
|
||||
|
||||
["Witness with SigHash Single|AnyoneCanPay (same signature as previous)"],
|
||||
[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0x51", 1000],
|
||||
["0000000000000000000000000000000000000000000000000000000000000100", 1, "0x00 0x14 0x4c9c3dfac4207d5d8cb89df5722cb3d712385e3f", 2000],
|
||||
["0000000000000000000000000000000000000000000000000000000000000100", 2, "0x51", 3000]],
|
||||
"0100000000010300010000000000000000000000000000000000000000000000000000000000000000000000ffffffff00010000000000000000000000000000000000000000000000000000000000000100000000ffffffff00010000000000000000000000000000000000000000000000000000000000000200000000ffffffff03e8030000000000000151d0070000000000000151b80b0000000000000151000248304502210092f4777a0f17bf5aeb8ae768dec5f2c14feabf9d1fe2c89c78dfed0f13fdb86902206da90a86042e252bcd1e80a168c719e4a1ddcc3cebea24b9812c5453c79107e9832103596d3451025c19dbbdeb932d6bf8bfb4ad499b95b6f88db8899efac102e5fc710000000000", "P2SH,WITNESS"],
|
||||
|
||||
["Witness with SigHash Single"],
|
||||
[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0x51", 1000],
|
||||
["0000000000000000000000000000000000000000000000000000000000000100", 1, "0x00 0x14 0x4c9c3dfac4207d5d8cb89df5722cb3d712385e3f", 2000],
|
||||
["0000000000000000000000000000000000000000000000000000000000000100", 2, "0x51", 3000]],
|
||||
"0100000000010300010000000000000000000000000000000000000000000000000000000000000000000000ffffffff00010000000000000000000000000000000000000000000000000000000000000100000000ffffffff00010000000000000000000000000000000000000000000000000000000000000200000000ffffffff0484030000000000000151d0070000000000000151540b0000000000000151c800000000000000015100024730440220699e6b0cfe015b64ca3283e6551440a34f901ba62dd4c72fe1cb815afb2e6761022021cc5e84db498b1479de14efda49093219441adc6c543e5534979605e273d80b032103596d3451025c19dbbdeb932d6bf8bfb4ad499b95b6f88db8899efac102e5fc710000000000", "P2SH,WITNESS"],
|
||||
|
||||
["Witness with SigHash Single (same signature as previous)"],
|
||||
[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0x51", 1000],
|
||||
["0000000000000000000000000000000000000000000000000000000000000100", 1, "0x00 0x14 0x4c9c3dfac4207d5d8cb89df5722cb3d712385e3f", 2000],
|
||||
["0000000000000000000000000000000000000000000000000000000000000100", 2, "0x51", 3000]],
|
||||
"0100000000010300010000000000000000000000000000000000000000000000000000000000000000000000ffffffff00010000000000000000000000000000000000000000000000000000000000000100000000ffffffff00010000000000000000000000000000000000000000000000000000000000000200000000ffffffff03e8030000000000000151d0070000000000000151b80b000000000000015100024730440220699e6b0cfe015b64ca3283e6551440a34f901ba62dd4c72fe1cb815afb2e6761022021cc5e84db498b1479de14efda49093219441adc6c543e5534979605e273d80b032103596d3451025c19dbbdeb932d6bf8bfb4ad499b95b6f88db8899efac102e5fc710000000000", "P2SH,WITNESS"],
|
||||
|
||||
["Witness with SigHash None|AnyoneCanPay"],
|
||||
[[["0000000000000000000000000000000000000000000000000000000000000100", 2, "0x51", 3100],
|
||||
["0000000000000000000000000000000000000000000000000000000000000100", 0, "0x51", 1100],
|
||||
["0000000000000000000000000000000000000000000000000000000000000100", 1, "0x00 0x14 0x4c9c3dfac4207d5d8cb89df5722cb3d712385e3f", 2000],
|
||||
["0000000000000000000000000000000000000000000000000000000000000100", 3, "0x51", 4100]],
|
||||
"0100000000010400010000000000000000000000000000000000000000000000000000000000000200000000ffffffff00010000000000000000000000000000000000000000000000000000000000000000000000ffffffff00010000000000000000000000000000000000000000000000000000000000000100000000ffffffff00010000000000000000000000000000000000000000000000000000000000000300000000ffffffff04b60300000000000001519e070000000000000151860b00000000000001009600000000000000015100000248304502210091b32274295c2a3fa02f5bce92fb2789e3fc6ea947fbe1a76e52ea3f4ef2381a022079ad72aefa3837a2e0c033a8652a59731da05fa4a813f4fc48e87c075037256b822103596d3451025c19dbbdeb932d6bf8bfb4ad499b95b6f88db8899efac102e5fc710000000000", "P2SH,WITNESS"],
|
||||
|
||||
["Witness with SigHash None|AnyoneCanPay (same signature as previous)"],
|
||||
[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0x51", 1000],
|
||||
["0000000000000000000000000000000000000000000000000000000000000100", 1, "0x00 0x14 0x4c9c3dfac4207d5d8cb89df5722cb3d712385e3f", 2000],
|
||||
["0000000000000000000000000000000000000000000000000000000000000100", 2, "0x51", 3000]],
|
||||
"0100000000010300010000000000000000000000000000000000000000000000000000000000000000000000ffffffff00010000000000000000000000000000000000000000000000000000000000000100000000ffffffff00010000000000000000000000000000000000000000000000000000000000000200000000ffffffff03e8030000000000000151d0070000000000000151b80b0000000000000151000248304502210091b32274295c2a3fa02f5bce92fb2789e3fc6ea947fbe1a76e52ea3f4ef2381a022079ad72aefa3837a2e0c033a8652a59731da05fa4a813f4fc48e87c075037256b822103596d3451025c19dbbdeb932d6bf8bfb4ad499b95b6f88db8899efac102e5fc710000000000", "P2SH,WITNESS"],
|
||||
|
||||
["Witness with SigHash None"],
|
||||
[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0x51", 1000],
|
||||
["0000000000000000000000000000000000000000000000000000000000000100", 1, "0x00 0x14 0x4c9c3dfac4207d5d8cb89df5722cb3d712385e3f", 2000],
|
||||
["0000000000000000000000000000000000000000000000000000000000000100", 2, "0x51", 3000]],
|
||||
"0100000000010300010000000000000000000000000000000000000000000000000000000000000000000000ffffffff00010000000000000000000000000000000000000000000000000000000000000100000000ffffffff00010000000000000000000000000000000000000000000000000000000000000200000000ffffffff04b60300000000000001519e070000000000000151860b0000000000000100960000000000000001510002473044022022fceb54f62f8feea77faac7083c3b56c4676a78f93745adc8a35800bc36adfa022026927df9abcf0a8777829bcfcce3ff0a385fa54c3f9df577405e3ef24ee56479022103596d3451025c19dbbdeb932d6bf8bfb4ad499b95b6f88db8899efac102e5fc710000000000", "P2SH,WITNESS"],
|
||||
|
||||
["Witness with SigHash None (same signature as previous)"],
|
||||
[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0x51", 1000],
|
||||
["0000000000000000000000000000000000000000000000000000000000000100", 1, "0x00 0x14 0x4c9c3dfac4207d5d8cb89df5722cb3d712385e3f", 2000],
|
||||
["0000000000000000000000000000000000000000000000000000000000000100", 2, "0x51", 3000]],
|
||||
"0100000000010300010000000000000000000000000000000000000000000000000000000000000000000000ffffffff00010000000000000000000000000000000000000000000000000000000000000100000000ffffffff00010000000000000000000000000000000000000000000000000000000000000200000000ffffffff03e8030000000000000151d0070000000000000151b80b00000000000001510002473044022022fceb54f62f8feea77faac7083c3b56c4676a78f93745adc8a35800bc36adfa022026927df9abcf0a8777829bcfcce3ff0a385fa54c3f9df577405e3ef24ee56479022103596d3451025c19dbbdeb932d6bf8bfb4ad499b95b6f88db8899efac102e5fc710000000000", "P2SH,WITNESS"],
|
||||
|
||||
["Witness with SigHash None (same signature, only sequences changed)"],
|
||||
[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0x51", 1000],
|
||||
["0000000000000000000000000000000000000000000000000000000000000100", 1, "0x00 0x14 0x4c9c3dfac4207d5d8cb89df5722cb3d712385e3f", 2000],
|
||||
["0000000000000000000000000000000000000000000000000000000000000100", 2, "0x51", 3000]],
|
||||
"01000000000103000100000000000000000000000000000000000000000000000000000000000000000000000200000000010000000000000000000000000000000000000000000000000000000000000100000000ffffffff000100000000000000000000000000000000000000000000000000000000000002000000000200000003e8030000000000000151d0070000000000000151b80b00000000000001510002473044022022fceb54f62f8feea77faac7083c3b56c4676a78f93745adc8a35800bc36adfa022026927df9abcf0a8777829bcfcce3ff0a385fa54c3f9df577405e3ef24ee56479022103596d3451025c19dbbdeb932d6bf8bfb4ad499b95b6f88db8899efac102e5fc710000000000", "P2SH,WITNESS"],
|
||||
|
||||
["Witness with SigHash All|AnyoneCanPay"],
|
||||
[[["0000000000000000000000000000000000000000000000000000000000000100", 2, "0x51", 3100],
|
||||
["0000000000000000000000000000000000000000000000000000000000000100", 0, "0x51", 1100],
|
||||
["0000000000000000000000000000000000000000000000000000000000000100", 1, "0x00 0x14 0x4c9c3dfac4207d5d8cb89df5722cb3d712385e3f", 2000],
|
||||
["0000000000000000000000000000000000000000000000000000000000000100", 3, "0x51", 4100]],
|
||||
"0100000000010400010000000000000000000000000000000000000000000000000000000000000200000000ffffffff00010000000000000000000000000000000000000000000000000000000000000000000000ffffffff00010000000000000000000000000000000000000000000000000000000000000100000000ffffffff00010000000000000000000000000000000000000000000000000000000000000300000000ffffffff03e8030000000000000151d0070000000000000151b80b0000000000000151000002483045022100a3cec69b52cba2d2de623eeef89e0ba1606184ea55476c0f8189fda231bc9cbb022003181ad597f7c380a7d1c740286b1d022b8b04ded028b833282e055e03b8efef812103596d3451025c19dbbdeb932d6bf8bfb4ad499b95b6f88db8899efac102e5fc710000000000", "P2SH,WITNESS"],
|
||||
|
||||
["Witness with SigHash All|AnyoneCanPay (same signature as previous)"],
|
||||
[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0x51", 1000],
|
||||
["0000000000000000000000000000000000000000000000000000000000000100", 1, "0x00 0x14 0x4c9c3dfac4207d5d8cb89df5722cb3d712385e3f", 2000],
|
||||
["0000000000000000000000000000000000000000000000000000000000000100", 2, "0x51", 3000]],
|
||||
"0100000000010300010000000000000000000000000000000000000000000000000000000000000000000000ffffffff00010000000000000000000000000000000000000000000000000000000000000100000000ffffffff00010000000000000000000000000000000000000000000000000000000000000200000000ffffffff03e8030000000000000151d0070000000000000151b80b00000000000001510002483045022100a3cec69b52cba2d2de623eeef89e0ba1606184ea55476c0f8189fda231bc9cbb022003181ad597f7c380a7d1c740286b1d022b8b04ded028b833282e055e03b8efef812103596d3451025c19dbbdeb932d6bf8bfb4ad499b95b6f88db8899efac102e5fc710000000000", "P2SH,WITNESS"],
|
||||
|
||||
["Unknown witness program version (without DISCOURAGE_UPGRADABLE_WITNESS_PROGRAM)"],
|
||||
[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0x51", 1000],
|
||||
["0000000000000000000000000000000000000000000000000000000000000100", 1, "0x60 0x14 0x4c9c3dfac4207d5d8cb89df5722cb3d712385e3f", 2000],
|
||||
["0000000000000000000000000000000000000000000000000000000000000100", 2, "0x51", 3000]],
|
||||
"0100000000010300010000000000000000000000000000000000000000000000000000000000000000000000ffffffff00010000000000000000000000000000000000000000000000000000000000000100000000ffffffff00010000000000000000000000000000000000000000000000000000000000000200000000ffffffff03e8030000000000000151d0070000000000000151b80b00000000000001510002483045022100a3cec69b52cba2d2de623ffffffffff1606184ea55476c0f8189fda231bc9cbb022003181ad597f7c380a7d1c740286b1d022b8b04ded028b833282e055e03b8efef812103596d3451025c19dbbdeb932d6bf8bfb4ad499b95b6f88db8899efac102e5fc710000000000", "P2SH,WITNESS"],
|
||||
|
||||
["Witness with a push of 520 bytes"],
|
||||
[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0x00 0x20 0x33198a9bfef674ebddb9ffaa52928017b8472791e54c609cb95f278ac6b1e349", 1000]],
|
||||
"0100000000010100010000000000000000000000000000000000000000000000000000000000000000000000ffffffff010000000000000000015102fd08020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002755100000000", "P2SH,WITNESS"],
|
||||
|
||||
["Transaction mixing all SigHash, segwit and normal inputs"],
|
||||
[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0x00 0x14 0x4c9c3dfac4207d5d8cb89df5722cb3d712385e3f", 1000],
|
||||
["0000000000000000000000000000000000000000000000000000000000000100", 1, "0x00 0x14 0x4c9c3dfac4207d5d8cb89df5722cb3d712385e3f", 1001],
|
||||
["0000000000000000000000000000000000000000000000000000000000000100", 2, "DUP HASH160 0x14 0x4c9c3dfac4207d5d8cb89df5722cb3d712385e3f EQUALVERIFY CHECKSIG", 1002],
|
||||
["0000000000000000000000000000000000000000000000000000000000000100", 3, "DUP HASH160 0x14 0x4c9c3dfac4207d5d8cb89df5722cb3d712385e3f EQUALVERIFY CHECKSIG", 1003],
|
||||
["0000000000000000000000000000000000000000000000000000000000000100", 4, "DUP HASH160 0x14 0x4c9c3dfac4207d5d8cb89df5722cb3d712385e3f EQUALVERIFY CHECKSIG", 1004],
|
||||
["0000000000000000000000000000000000000000000000000000000000000100", 5, "DUP HASH160 0x14 0x4c9c3dfac4207d5d8cb89df5722cb3d712385e3f EQUALVERIFY CHECKSIG", 1005],
|
||||
["0000000000000000000000000000000000000000000000000000000000000100", 6, "DUP HASH160 0x14 0x4c9c3dfac4207d5d8cb89df5722cb3d712385e3f EQUALVERIFY CHECKSIG", 1006],
|
||||
["0000000000000000000000000000000000000000000000000000000000000100", 7, "0x00 0x14 0x4c9c3dfac4207d5d8cb89df5722cb3d712385e3f", 1007],
|
||||
["0000000000000000000000000000000000000000000000000000000000000100", 8, "0x00 0x14 0x4c9c3dfac4207d5d8cb89df5722cb3d712385e3f", 1008],
|
||||
["0000000000000000000000000000000000000000000000000000000000000100", 9, "0x00 0x14 0x4c9c3dfac4207d5d8cb89df5722cb3d712385e3f", 1009],
|
||||
["0000000000000000000000000000000000000000000000000000000000000100", 10, "0x00 0x14 0x4c9c3dfac4207d5d8cb89df5722cb3d712385e3f", 1010],
|
||||
["0000000000000000000000000000000000000000000000000000000000000100", 11, "DUP HASH160 0x14 0x4c9c3dfac4207d5d8cb89df5722cb3d712385e3f EQUALVERIFY CHECKSIG", 1011]],
|
||||
"0100000000010c00010000000000000000000000000000000000000000000000000000000000000000000000ffffffff00010000000000000000000000000000000000000000000000000000000000000100000000ffffffff0001000000000000000000000000000000000000000000000000000000000000020000006a473044022026c2e65b33fcd03b2a3b0f25030f0244bd23cc45ae4dec0f48ae62255b1998a00220463aa3982b718d593a6b9e0044513fd67a5009c2fdccc59992cffc2b167889f4012103596d3451025c19dbbdeb932d6bf8bfb4ad499b95b6f88db8899efac102e5fc71ffffffff0001000000000000000000000000000000000000000000000000000000000000030000006a4730440220008bd8382911218dcb4c9f2e75bf5c5c3635f2f2df49b36994fde85b0be21a1a02205a539ef10fb4c778b522c1be852352ea06c67ab74200977c722b0bc68972575a012103596d3451025c19dbbdeb932d6bf8bfb4ad499b95b6f88db8899efac102e5fc71ffffffff0001000000000000000000000000000000000000000000000000000000000000040000006b483045022100d9436c32ff065127d71e1a20e319e4fe0a103ba0272743dbd8580be4659ab5d302203fd62571ee1fe790b182d078ecfd092a509eac112bea558d122974ef9cc012c7012103596d3451025c19dbbdeb932d6bf8bfb4ad499b95b6f88db8899efac102e5fc71ffffffff0001000000000000000000000000000000000000000000000000000000000000050000006a47304402200e2c149b114ec546015c13b2b464bbcb0cdc5872e6775787527af6cbc4830b6c02207e9396c6979fb15a9a2b96ca08a633866eaf20dc0ff3c03e512c1d5a1654f148012103596d3451025c19dbbdeb932d6bf8bfb4ad499b95b6f88db8899efac102e5fc71ffffffff0001000000000000000000000000000000000000000000000000000000000000060000006b483045022100b20e70d897dc15420bccb5e0d3e208d27bdd676af109abbd3f88dbdb7721e6d6022005836e663173fbdfe069f54cde3c2decd3d0ea84378092a5d9d85ec8642e8a41012103596d3451025c19dbbdeb932d6bf8bfb4ad499b95b6f88db8899efac102e5fc71ffffffff00010000000000000000000000000000000000000000000000000000000000000700000000ffffffff00010000000000000000000000000000000000000000000000000000000000000800000000ffffffff00010000000000000000000000000000000000000000000000000000000000000900000000ffffffff00010000000000000000000000000000000000000000000000000000000000000a00000000ffffffff00010000000000000000000000000000000000000000000000000000000000000b0000006a47304402206639c6e05e3b9d2675a7f3876286bdf7584fe2bbd15e0ce52dd4e02c0092cdc60220757d60b0a61fc95ada79d23746744c72bac1545a75ff6c2c7cdb6ae04e7e9592012103596d3451025c19dbbdeb932d6bf8bfb4ad499b95b6f88db8899efac102e5fc71ffffffff0ce8030000000000000151e9030000000000000151ea030000000000000151eb030000000000000151ec030000000000000151ed030000000000000151ee030000000000000151ef030000000000000151f0030000000000000151f1030000000000000151f2030000000000000151f30300000000000001510248304502210082219a54f61bf126bfc3fa068c6e33831222d1d7138c6faa9d33ca87fd4202d6022063f9902519624254d7c2c8ea7ba2d66ae975e4e229ae38043973ec707d5d4a83012103596d3451025c19dbbdeb932d6bf8bfb4ad499b95b6f88db8899efac102e5fc7102473044022017fb58502475848c1b09f162cb1688d0920ff7f142bed0ef904da2ccc88b168f02201798afa61850c65e77889cbcd648a5703b487895517c88f85cdd18b021ee246a012103596d3451025c19dbbdeb932d6bf8bfb4ad499b95b6f88db8899efac102e5fc7100000000000247304402202830b7926e488da75782c81a54cd281720890d1af064629ebf2e31bf9f5435f30220089afaa8b455bbeb7d9b9c3fe1ed37d07685ade8455c76472cda424d93e4074a012103596d3451025c19dbbdeb932d6bf8bfb4ad499b95b6f88db8899efac102e5fc7102473044022026326fcdae9207b596c2b05921dbac11d81040c4d40378513670f19d9f4af893022034ecd7a282c0163b89aaa62c22ec202cef4736c58cd251649bad0d8139bcbf55012103596d3451025c19dbbdeb932d6bf8bfb4ad499b95b6f88db8899efac102e5fc71024730440220214978daeb2f38cd426ee6e2f44131a33d6b191af1c216247f1dd7d74c16d84a02205fdc05529b0bc0c430b4d5987264d9d075351c4f4484c16e91662e90a72aab24012103596d3451025c19dbbdeb932d6bf8bfb4ad499b95b6f88db8899efac102e5fc710247304402204a6e9f199dc9672cf2ff8094aaa784363be1eb62b679f7ff2df361124f1dca3302205eeb11f70fab5355c9c8ad1a0700ea355d315e334822fa182227e9815308ee8f012103596d3451025c19dbbdeb932d6bf8bfb4ad499b95b6f88db8899efac102e5fc710000000000", "P2SH,WITNESS"],
|
||||
|
||||
["Unknown version witness program with empty witness"],
|
||||
[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0x60 0x14 0x4c9c3dfac4207d5d8cb89df5722cb3d712385e3f", 1000]],
|
||||
"010000000100010000000000000000000000000000000000000000000000000000000000000000000000ffffffff01e803000000000000015100000000", "P2SH,WITNESS"],
|
||||
|
||||
["Witness SIGHASH_SINGLE with output out of bound"],
|
||||
[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0x51", 1000],
|
||||
["0000000000000000000000000000000000000000000000000000000000000100", 1, "0x00 0x20 0x4d6c2a32c87821d68fc016fca70797abdb80df6cd84651d40a9300c6bad79e62", 1000]],
|
||||
"0100000000010200010000000000000000000000000000000000000000000000000000000000000000000000ffffffff00010000000000000000000000000000000000000000000000000000000000000100000000ffffffff01d00700000000000001510003483045022100e078de4e96a0e05dcdc0a414124dd8475782b5f3f0ed3f607919e9a5eeeb22bf02201de309b3a3109adb3de8074b3610d4cf454c49b61247a2779a0bcbf31c889333032103596d3451025c19dbbdeb932d6bf8bfb4ad499b95b6f88db8899efac102e5fc711976a9144c9c3dfac4207d5d8cb89df5722cb3d712385e3f88ac00000000", "P2SH,WITNESS"],
|
||||
|
||||
["1 byte push should not be considered a witness scriptPubKey"],
|
||||
[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0x60 0x01 0x01", 1000]],
|
||||
"010000000100010000000000000000000000000000000000000000000000000000000000000000000000ffffffff01e803000000000000015100000000", "P2SH,WITNESS,DISCOURAGE_UPGRADABLE_WITNESS_PROGRAM"],
|
||||
|
||||
["41 bytes push should not be considered a witness scriptPubKey"],
|
||||
[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0x60 0x29 0xff25429251b5a84f452230a3c75fd886b7fc5a7865ce4a7bb7a9d7c5be6da3dbff0000000000000000", 1000]],
|
||||
"010000000100010000000000000000000000000000000000000000000000000000000000000000000000ffffffff01e803000000000000015100000000", "P2SH,WITNESS,DISCOURAGE_UPGRADABLE_WITNESS_PROGRAM"],
|
||||
|
||||
["The witness version must use OP_1 to OP_16 only"],
|
||||
[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0x01 0x10 0x02 0x0001", 1000]],
|
||||
"010000000100010000000000000000000000000000000000000000000000000000000000000000000000ffffffff01e803000000000000015100000000", "P2SH,WITNESS,DISCOURAGE_UPGRADABLE_WITNESS_PROGRAM"],
|
||||
|
||||
["The witness program push must be canonical"],
|
||||
[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0x60 0x4c02 0x0001", 1000]],
|
||||
"010000000100010000000000000000000000000000000000000000000000000000000000000000000000ffffffff01e803000000000000015100000000", "P2SH,WITNESS,DISCOURAGE_UPGRADABLE_WITNESS_PROGRAM"],
|
||||
|
||||
["Witness Single|AnyoneCanPay does not hash input's position"],
|
||||
[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0x00 0x14 0x4c9c3dfac4207d5d8cb89df5722cb3d712385e3f", 1000],
|
||||
["0000000000000000000000000000000000000000000000000000000000000100", 1, "0x00 0x14 0x4c9c3dfac4207d5d8cb89df5722cb3d712385e3f", 1001]],
|
||||
"0100000000010200010000000000000000000000000000000000000000000000000000000000000000000000ffffffff00010000000000000000000000000000000000000000000000000000000000000100000000ffffffff02e8030000000000000151e90300000000000001510247304402206d59682663faab5e4cb733c562e22cdae59294895929ec38d7c016621ff90da0022063ef0af5f970afe8a45ea836e3509b8847ed39463253106ac17d19c437d3d56b832103596d3451025c19dbbdeb932d6bf8bfb4ad499b95b6f88db8899efac102e5fc710248304502210085001a820bfcbc9f9de0298af714493f8a37b3b354bfd21a7097c3e009f2018c022050a8b4dbc8155d4d04da2f5cdd575dcf8dd0108de8bec759bd897ea01ecb3af7832103596d3451025c19dbbdeb932d6bf8bfb4ad499b95b6f88db8899efac102e5fc7100000000", "P2SH,WITNESS"],
|
||||
|
||||
["Witness Single|AnyoneCanPay does not hash input's position (permutation)"],
|
||||
[[["0000000000000000000000000000000000000000000000000000000000000100", 1, "0x00 0x14 0x4c9c3dfac4207d5d8cb89df5722cb3d712385e3f", 1001],
|
||||
["0000000000000000000000000000000000000000000000000000000000000100", 0, "0x00 0x14 0x4c9c3dfac4207d5d8cb89df5722cb3d712385e3f", 1000]],
|
||||
"0100000000010200010000000000000000000000000000000000000000000000000000000000000100000000ffffffff00010000000000000000000000000000000000000000000000000000000000000000000000ffffffff02e9030000000000000151e80300000000000001510248304502210085001a820bfcbc9f9de0298af714493f8a37b3b354bfd21a7097c3e009f2018c022050a8b4dbc8155d4d04da2f5cdd575dcf8dd0108de8bec759bd897ea01ecb3af7832103596d3451025c19dbbdeb932d6bf8bfb4ad499b95b6f88db8899efac102e5fc710247304402206d59682663faab5e4cb733c562e22cdae59294895929ec38d7c016621ff90da0022063ef0af5f970afe8a45ea836e3509b8847ed39463253106ac17d19c437d3d56b832103596d3451025c19dbbdeb932d6bf8bfb4ad499b95b6f88db8899efac102e5fc7100000000", "P2SH,WITNESS"],
|
||||
|
||||
["Non witness Single|AnyoneCanPay hash input's position"],
|
||||
[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0x21 0x03596d3451025c19dbbdeb932d6bf8bfb4ad499b95b6f88db8899efac102e5fc71 CHECKSIG", 1000],
|
||||
["0000000000000000000000000000000000000000000000000000000000000100", 1, "0x21 0x03596d3451025c19dbbdeb932d6bf8bfb4ad499b95b6f88db8899efac102e5fc71 CHECKSIG", 1001]],
|
||||
"01000000020001000000000000000000000000000000000000000000000000000000000000000000004847304402202a0b4b1294d70540235ae033d78e64b4897ec859c7b6f1b2b1d8a02e1d46006702201445e756d2254b0f1dfda9ab8e1e1bc26df9668077403204f32d16a49a36eb6983ffffffff00010000000000000000000000000000000000000000000000000000000000000100000049483045022100acb96cfdbda6dc94b489fd06f2d720983b5f350e31ba906cdbd800773e80b21c02200d74ea5bdf114212b4bbe9ed82c36d2e369e302dff57cb60d01c428f0bd3daab83ffffffff02e8030000000000000151e903000000000000015100000000", "P2SH,WITNESS"],
|
||||
|
||||
["BIP143 examples: details and private keys are available in BIP143"],
|
||||
["BIP143 example: P2WSH with OP_CODESEPARATOR and out-of-range SIGHASH_SINGLE."],
|
||||
[[["6eb316926b1c5d567cd6f5e6a84fec606fc53d7b474526d1fff3948020c93dfe", 0, "0x21 0x036d5c20fa14fb2f635474c1dc4ef5909d4568e5569b79fc94d3448486e14685f8 CHECKSIG", 156250000],
|
||||
["f825690aee1b3dc247da796cacb12687a5e802429fd291cfd63e010f02cf1508", 0, "0x00 0x20 0x5d1b56b63d714eebe542309525f484b7e9d6f686b3781b6f61ef925d66d6f6a0", 4900000000]],
|
||||
"01000000000102fe3dc9208094f3ffd12645477b3dc56f60ec4fa8e6f5d67c565d1c6b9216b36e000000004847304402200af4e47c9b9629dbecc21f73af989bdaa911f7e6f6c2e9394588a3aa68f81e9902204f3fcf6ade7e5abb1295b6774c8e0abd94ae62217367096bc02ee5e435b67da201ffffffff0815cf020f013ed6cf91d29f4202e8a58726b1ac6c79da47c23d1bee0a6925f80000000000ffffffff0100f2052a010000001976a914a30741f8145e5acadf23f751864167f32e0963f788ac000347304402200de66acf4527789bfda55fc5459e214fa6083f936b430a762c629656216805ac0220396f550692cd347171cbc1ef1f51e15282e837bb2b30860dc77c8f78bc8501e503473044022027dc95ad6b740fe5129e7e62a75dd00f291a2aeb1200b84b09d9e3789406b6c002201a9ecd315dd6a0e632ab20bbb98948bc0c6fb204f2c286963bb48517a7058e27034721026dccc749adc2a9d0d89497ac511f760f45c47dc5ed9cf352a58ac706453880aeadab210255a9626aebf5e29c0e6538428ba0d1dcf6ca98ffdf086aa8ced5e0d0215ea465ac00000000", "P2SH,WITNESS"],
|
||||
|
||||
["BIP143 example: P2WSH with unexecuted OP_CODESEPARATOR and SINGLE|ANYONECANPAY"],
|
||||
[[["01c0cf7fba650638e55eb91261b183251fbb466f90dff17f10086817c542b5e9", 0, "0x00 0x20 0xba468eea561b26301e4cf69fa34bde4ad60c81e70f059f045ca9a79931004a4d", 16777215],
|
||||
["1b2a9a426ba603ba357ce7773cb5805cb9c7c2b386d100d1fc9263513188e680", 0, "0x00 0x20 0xd9bbfbe56af7c4b7f960a70d7ea107156913d9e5a26b0a71429df5e097ca6537", 16777215]],
|
||||
"01000000000102e9b542c5176808107ff1df906f46bb1f2583b16112b95ee5380665ba7fcfc0010000000000ffffffff80e68831516392fcd100d186b3c2c7b95c80b53c77e77c35ba03a66b429a2a1b0000000000ffffffff0280969800000000001976a914de4b231626ef508c9a74a8517e6783c0546d6b2888ac80969800000000001976a9146648a8cd4531e1ec47f35916de8e259237294d1e88ac02483045022100f6a10b8604e6dc910194b79ccfc93e1bc0ec7c03453caaa8987f7d6c3413566002206216229ede9b4d6ec2d325be245c5b508ff0339bf1794078e20bfe0babc7ffe683270063ab68210392972e2eb617b2388771abe27235fd5ac44af8e61693261550447a4c3e39da98ac024730440220032521802a76ad7bf74d0e2c218b72cf0cbc867066e2e53db905ba37f130397e02207709e2188ed7f08f4c952d9d13986da504502b8c3be59617e043552f506c46ff83275163ab68210392972e2eb617b2388771abe27235fd5ac44af8e61693261550447a4c3e39da98ac00000000", "P2SH,WITNESS"],
|
||||
|
||||
["BIP143 example: Same as the previous example with input-output pairs swapped"],
|
||||
[[["1b2a9a426ba603ba357ce7773cb5805cb9c7c2b386d100d1fc9263513188e680", 0, "0x00 0x20 0xd9bbfbe56af7c4b7f960a70d7ea107156913d9e5a26b0a71429df5e097ca6537", 16777215],
|
||||
["01c0cf7fba650638e55eb91261b183251fbb466f90dff17f10086817c542b5e9", 0, "0x00 0x20 0xba468eea561b26301e4cf69fa34bde4ad60c81e70f059f045ca9a79931004a4d", 16777215]],
|
||||
"0100000000010280e68831516392fcd100d186b3c2c7b95c80b53c77e77c35ba03a66b429a2a1b0000000000ffffffffe9b542c5176808107ff1df906f46bb1f2583b16112b95ee5380665ba7fcfc0010000000000ffffffff0280969800000000001976a9146648a8cd4531e1ec47f35916de8e259237294d1e88ac80969800000000001976a914de4b231626ef508c9a74a8517e6783c0546d6b2888ac024730440220032521802a76ad7bf74d0e2c218b72cf0cbc867066e2e53db905ba37f130397e02207709e2188ed7f08f4c952d9d13986da504502b8c3be59617e043552f506c46ff83275163ab68210392972e2eb617b2388771abe27235fd5ac44af8e61693261550447a4c3e39da98ac02483045022100f6a10b8604e6dc910194b79ccfc93e1bc0ec7c03453caaa8987f7d6c3413566002206216229ede9b4d6ec2d325be245c5b508ff0339bf1794078e20bfe0babc7ffe683270063ab68210392972e2eb617b2388771abe27235fd5ac44af8e61693261550447a4c3e39da98ac00000000", "P2SH,WITNESS"],
|
||||
|
||||
["BIP143 example: P2SH-P2WSH 6-of-6 multisig signed with 6 different SIGHASH types"],
|
||||
[[["6eb98797a21c6c10aa74edf29d618be109f48a8e94c694f3701e08ca69186436", 1, "HASH160 0x14 0x9993a429037b5d912407a71c252019287b8d27a5 EQUAL", 987654321]],
|
||||
"0100000000010136641869ca081e70f394c6948e8af409e18b619df2ed74aa106c1ca29787b96e0100000023220020a16b5755f7f6f96dbd65f5f0d6ab9418b89af4b1f14a1bb8a09062c35f0dcb54ffffffff0200e9a435000000001976a914389ffce9cd9ae88dcc0631e88a821ffdbe9bfe2688acc0832f05000000001976a9147480a33f950689af511e6e84c138dbbd3c3ee41588ac080047304402206ac44d672dac41f9b00e28f4df20c52eeb087207e8d758d76d92c6fab3b73e2b0220367750dbbe19290069cba53d096f44530e4f98acaa594810388cf7409a1870ce01473044022068c7946a43232757cbdf9176f009a928e1cd9a1a8c212f15c1e11ac9f2925d9002205b75f937ff2f9f3c1246e547e54f62e027f64eefa2695578cc6432cdabce271502473044022059ebf56d98010a932cf8ecfec54c48e6139ed6adb0728c09cbe1e4fa0915302e022007cd986c8fa870ff5d2b3a89139c9fe7e499259875357e20fcbb15571c76795403483045022100fbefd94bd0a488d50b79102b5dad4ab6ced30c4069f1eaa69a4b5a763414067e02203156c6a5c9cf88f91265f5a942e96213afae16d83321c8b31bb342142a14d16381483045022100a5263ea0553ba89221984bd7f0b13613db16e7a70c549a86de0cc0444141a407022005c360ef0ae5a5d4f9f2f87a56c1546cc8268cab08c73501d6b3be2e1e1a8a08824730440220525406a1482936d5a21888260dc165497a90a15669636d8edca6b9fe490d309c022032af0c646a34a44d1f4576bf6a4a74b67940f8faa84c7df9abe12a01a11e2b4783cf56210307b8ae49ac90a048e9b53357a2354b3334e9c8bee813ecb98e99a7e07e8c3ba32103b28f0c28bfab54554ae8c658ac5c3e0ce6e79ad336331f78c428dd43eea8449b21034b8113d703413d57761b8b9781957b8c0ac1dfe69f492580ca4195f50376ba4a21033400f6afecb833092a9a21cfdf1ed1376e58c5d1f47de74683123987e967a8f42103a6d48b1131e94ba04d9737d61acdaa1322008af9602b3b14862c07a1789aac162102d8b661b0b3302ee2f162b09e07a55ad5dfbe673a9f01d9f0c19617681024306b56ae00000000", "P2SH,WITNESS"],
|
||||
|
||||
["FindAndDelete tests"],
|
||||
["This is a test of FindAndDelete. The first tx is a spend of normal P2SH and the second tx is a spend of bare P2WSH."],
|
||||
["The redeemScript/witnessScript is CHECKSIGVERIFY <0x30450220487fb382c4974de3f7d834c1b617fe15860828c7f96454490edd6d891556dcc9022100baf95feb48f845d5bfc9882eb6aeefa1bc3790e39f59eaa46ff7f15ae626c53e01>."],
|
||||
["The signature is <0x30450220487fb382c4974de3f7d834c1b617fe15860828c7f96454490edd6d891556dcc9022100baf95feb48f845d5bfc9882eb6aeefa1bc3790e39f59eaa46ff7f15ae626c53e01> <pubkey>,"],
|
||||
["where the pubkey is obtained through key recovery with sig and correct sighash."],
|
||||
["This is to show that FindAndDelete is applied only to non-segwit scripts"],
|
||||
["Non-segwit: correct sighash (with FindAndDelete) = 1ba1fe3bc90c5d1265460e684ce6774e324f0fabdf67619eda729e64e8b6bc08"],
|
||||
[[["f18783ace138abac5d3a7a5cf08e88fe6912f267ef936452e0c27d090621c169", 7000, "HASH160 0x14 0x0c746489e2d83cdbb5b90b432773342ba809c134 EQUAL", 200000]],
|
||||
"010000000169c12106097dc2e0526493ef67f21269fe888ef05c7a3a5dacab38e1ac8387f1581b0000b64830450220487fb382c4974de3f7d834c1b617fe15860828c7f96454490edd6d891556dcc9022100baf95feb48f845d5bfc9882eb6aeefa1bc3790e39f59eaa46ff7f15ae626c53e0121037a3fb04bcdb09eba90f69961ba1692a3528e45e67c85b200df820212d7594d334aad4830450220487fb382c4974de3f7d834c1b617fe15860828c7f96454490edd6d891556dcc9022100baf95feb48f845d5bfc9882eb6aeefa1bc3790e39f59eaa46ff7f15ae626c53e01ffffffff0101000000000000000000000000", "P2SH,WITNESS"],
|
||||
["BIP143: correct sighash (without FindAndDelete) = 71c9cd9b2869b9c70b01b1f0360c148f42dee72297db312638df136f43311f23"],
|
||||
[[["f18783ace138abac5d3a7a5cf08e88fe6912f267ef936452e0c27d090621c169", 7500, "0x00 0x20 0x9e1be07558ea5cc8e02ed1d80c0911048afad949affa36d5c3951e3159dbea19", 200000]],
|
||||
"0100000000010169c12106097dc2e0526493ef67f21269fe888ef05c7a3a5dacab38e1ac8387f14c1d000000ffffffff01010000000000000000034830450220487fb382c4974de3f7d834c1b617fe15860828c7f96454490edd6d891556dcc9022100baf95feb48f845d5bfc9882eb6aeefa1bc3790e39f59eaa46ff7f15ae626c53e012102a9781d66b61fb5a7ef00ac5ad5bc6ffc78be7b44a566e3c87870e1079368df4c4aad4830450220487fb382c4974de3f7d834c1b617fe15860828c7f96454490edd6d891556dcc9022100baf95feb48f845d5bfc9882eb6aeefa1bc3790e39f59eaa46ff7f15ae626c53e0100000000", "P2SH,WITNESS"],
|
||||
["This is multisig version of the FindAndDelete tests"],
|
||||
["Script is 2 CHECKMULTISIGVERIFY <sig1> <sig2> DROP"],
|
||||
["52af4830450220487fb382c4974de3f7d834c1b617fe15860828c7f96454490edd6d891556dcc9022100baf95feb48f845d5bfc9882eb6aeefa1bc3790e39f59eaa46ff7f15ae626c53e0148304502205286f726690b2e9b0207f0345711e63fa7012045b9eb0f19c2458ce1db90cf43022100e89f17f86abc5b149eba4115d4f128bcf45d77fb3ecdd34f594091340c0395960175"],
|
||||
["Signature is 0 <sig1> <sig2> 2 <key1> <key2>"],
|
||||
["Non-segwit: correct sighash (with FindAndDelete) = 1d50f00ba4db2917b903b0ec5002e017343bb38876398c9510570f5dce099295"],
|
||||
[[["9628667ad48219a169b41b020800162287d2c0f713c04157e95c484a8dcb7592", 7000, "HASH160 0x14 0x5748407f5ca5cdca53ba30b79040260770c9ee1b EQUAL", 200000]],
|
||||
"01000000019275cb8d4a485ce95741c013f7c0d28722160008021bb469a11982d47a662896581b0000fd6f01004830450220487fb382c4974de3f7d834c1b617fe15860828c7f96454490edd6d891556dcc9022100baf95feb48f845d5bfc9882eb6aeefa1bc3790e39f59eaa46ff7f15ae626c53e0148304502205286f726690b2e9b0207f0345711e63fa7012045b9eb0f19c2458ce1db90cf43022100e89f17f86abc5b149eba4115d4f128bcf45d77fb3ecdd34f594091340c03959601522102cd74a2809ffeeed0092bc124fd79836706e41f048db3f6ae9df8708cefb83a1c2102e615999372426e46fd107b76eaf007156a507584aa2cc21de9eee3bdbd26d36c4c9552af4830450220487fb382c4974de3f7d834c1b617fe15860828c7f96454490edd6d891556dcc9022100baf95feb48f845d5bfc9882eb6aeefa1bc3790e39f59eaa46ff7f15ae626c53e0148304502205286f726690b2e9b0207f0345711e63fa7012045b9eb0f19c2458ce1db90cf43022100e89f17f86abc5b149eba4115d4f128bcf45d77fb3ecdd34f594091340c0395960175ffffffff0101000000000000000000000000", "P2SH,WITNESS"],
|
||||
["BIP143: correct sighash (without FindAndDelete) = c1628a1e7c67f14ca0c27c06e4fdeec2e6d1a73c7a91d7c046ff83e835aebb72"],
|
||||
[[["9628667ad48219a169b41b020800162287d2c0f713c04157e95c484a8dcb7592", 7500, "0x00 0x20 0x9b66c15b4e0b4eb49fa877982cafded24859fe5b0e2dbfbe4f0df1de7743fd52", 200000]],
|
||||
"010000000001019275cb8d4a485ce95741c013f7c0d28722160008021bb469a11982d47a6628964c1d000000ffffffff0101000000000000000007004830450220487fb382c4974de3f7d834c1b617fe15860828c7f96454490edd6d891556dcc9022100baf95feb48f845d5bfc9882eb6aeefa1bc3790e39f59eaa46ff7f15ae626c53e0148304502205286f726690b2e9b0207f0345711e63fa7012045b9eb0f19c2458ce1db90cf43022100e89f17f86abc5b149eba4115d4f128bcf45d77fb3ecdd34f594091340c0395960101022102966f109c54e85d3aee8321301136cedeb9fc710fdef58a9de8a73942f8e567c021034ffc99dd9a79dd3cb31e2ab3e0b09e0e67db41ac068c625cd1f491576016c84e9552af4830450220487fb382c4974de3f7d834c1b617fe15860828c7f96454490edd6d891556dcc9022100baf95feb48f845d5bfc9882eb6aeefa1bc3790e39f59eaa46ff7f15ae626c53e0148304502205286f726690b2e9b0207f0345711e63fa7012045b9eb0f19c2458ce1db90cf43022100e89f17f86abc5b149eba4115d4f128bcf45d77fb3ecdd34f594091340c039596017500000000", "P2SH,WITNESS"],
|
||||
|
||||
["Make diffs cleaner by leaving a comment here without comma at the end"]
|
||||
]
|
||||
|
@ -5,8 +5,6 @@
|
||||
package txscript
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/sha256"
|
||||
"fmt"
|
||||
"math/big"
|
||||
|
||||
@ -48,8 +46,7 @@ const (
|
||||
// ScriptVerifyCleanStack defines that the stack must contain only
|
||||
// one stack element after evaluation and that the element must be
|
||||
// true if interpreted as a boolean. This is rule 6 of BIP0062.
|
||||
// This flag should never be used without the ScriptBip16 flag nor the
|
||||
// ScriptVerifyWitness flag.
|
||||
// This flag should never be used without the ScriptBip16 flag.
|
||||
ScriptVerifyCleanStack
|
||||
|
||||
// ScriptVerifyDERSignatures defines that signatures are required
|
||||
@ -76,23 +73,6 @@ const (
|
||||
// ScriptVerifyStrictEncoding defines that signature scripts and
|
||||
// public keys must follow the strict encoding requirements.
|
||||
ScriptVerifyStrictEncoding
|
||||
|
||||
// ScriptVerifyWitness defines whether or not to verify a transaction
|
||||
// output using a witness program template.
|
||||
ScriptVerifyWitness
|
||||
|
||||
// ScriptVerifyDiscourageUpgradeableWitnessProgram makes witness
|
||||
// program with versions 2-16 non-standard.
|
||||
ScriptVerifyDiscourageUpgradeableWitnessProgram
|
||||
|
||||
// ScriptVerifyMinimalIf makes a script with an OP_IF/OP_NOTIF whose
|
||||
// operand is anything other than empty vector or [0x01] non-standard.
|
||||
ScriptVerifyMinimalIf
|
||||
|
||||
// ScriptVerifyWitnessPubKeyType makes a script within a check-sig
|
||||
// operation whose public key isn't serialized in a compressed format
|
||||
// non-standard.
|
||||
ScriptVerifyWitnessPubKeyType
|
||||
)
|
||||
|
||||
const (
|
||||
@ -102,14 +82,6 @@ const (
|
||||
|
||||
// MaxScriptSize is the maximum allowed length of a raw script.
|
||||
MaxScriptSize = 10000
|
||||
|
||||
// payToWitnessPubKeyHashDataSize is the size of the witness program's
|
||||
// data push for a pay-to-witness-pub-key-hash output.
|
||||
payToWitnessPubKeyHashDataSize = 20
|
||||
|
||||
// payToWitnessScriptHashDataSize is the size of the witness program's
|
||||
// data push for a pay-to-witness-script-hash output.
|
||||
payToWitnessScriptHashDataSize = 32
|
||||
)
|
||||
|
||||
// halforder is used to tame ECDSA malleability (see BIP0062).
|
||||
@ -129,12 +101,8 @@ type Engine struct {
|
||||
numOps int
|
||||
flags ScriptFlags
|
||||
sigCache *SigCache
|
||||
hashCache *TxSigHashes
|
||||
bip16 bool // treat execution as pay-to-script-hash
|
||||
savedFirstStack [][]byte // stack from first script for bip16 scripts
|
||||
witnessVersion int
|
||||
witnessProgram []byte
|
||||
inputAmount int64
|
||||
}
|
||||
|
||||
// hasFlag returns whether the script engine instance has the passed flag set.
|
||||
@ -241,122 +209,6 @@ func (vm *Engine) curPC() (script int, off int, err error) {
|
||||
return vm.scriptIdx, vm.scriptOff, nil
|
||||
}
|
||||
|
||||
// isWitnessVersionActive returns true if a witness program was extracted
|
||||
// during the initialization of the Engine, and the program's version matches
|
||||
// the specified version.
|
||||
func (vm *Engine) isWitnessVersionActive(version uint) bool {
|
||||
return vm.witnessProgram != nil && uint(vm.witnessVersion) == version
|
||||
}
|
||||
|
||||
// verifyWitnessProgram validates the stored witness program using the passed
|
||||
// witness as input.
|
||||
func (vm *Engine) verifyWitnessProgram(witness [][]byte) error {
|
||||
if vm.isWitnessVersionActive(0) {
|
||||
switch len(vm.witnessProgram) {
|
||||
case payToWitnessPubKeyHashDataSize: // P2WKH
|
||||
// The witness stack should consist of exactly two
|
||||
// items: the signature, and the pubkey.
|
||||
if len(witness) != 2 {
|
||||
err := fmt.Sprintf("should have exactly two "+
|
||||
"items in witness, instead have %v", len(witness))
|
||||
return scriptError(ErrWitnessProgramMismatch, err)
|
||||
}
|
||||
|
||||
// Now we'll resume execution as if it were a regular
|
||||
// p2pkh transaction.
|
||||
pkScript, err := payToPubKeyHashScript(vm.witnessProgram)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
pops, err := parseScript(pkScript)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Set the stack to the provided witness stack, then
|
||||
// append the pkScript generated above as the next
|
||||
// script to execute.
|
||||
vm.scripts = append(vm.scripts, pops)
|
||||
vm.SetStack(witness)
|
||||
|
||||
case payToWitnessScriptHashDataSize: // P2WSH
|
||||
// Additionally, The witness stack MUST NOT be empty at
|
||||
// this point.
|
||||
if len(witness) == 0 {
|
||||
return scriptError(ErrWitnessProgramEmpty, "witness "+
|
||||
"program empty passed empty witness")
|
||||
}
|
||||
|
||||
// Obtain the witness script which should be the last
|
||||
// element in the passed stack. The size of the script
|
||||
// MUST NOT exceed the max script size.
|
||||
witnessScript := witness[len(witness)-1]
|
||||
if len(witnessScript) > MaxScriptSize {
|
||||
str := fmt.Sprintf("witnessScript size %d "+
|
||||
"is larger than max allowed size %d",
|
||||
len(witnessScript), MaxScriptSize)
|
||||
return scriptError(ErrScriptTooBig, str)
|
||||
}
|
||||
|
||||
// Ensure that the serialized pkScript at the end of
|
||||
// the witness stack matches the witness program.
|
||||
witnessHash := sha256.Sum256(witnessScript)
|
||||
if !bytes.Equal(witnessHash[:], vm.witnessProgram) {
|
||||
return scriptError(ErrWitnessProgramMismatch,
|
||||
"witness program hash mismatch")
|
||||
}
|
||||
|
||||
// With all the validity checks passed, parse the
|
||||
// script into individual op-codes so w can execute it
|
||||
// as the next script.
|
||||
pops, err := parseScript(witnessScript)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// The hash matched successfully, so use the witness as
|
||||
// the stack, and set the witnessScript to be the next
|
||||
// script executed.
|
||||
vm.scripts = append(vm.scripts, pops)
|
||||
vm.SetStack(witness[:len(witness)-1])
|
||||
|
||||
default:
|
||||
errStr := fmt.Sprintf("length of witness program "+
|
||||
"must either be %v or %v bytes, instead is %v bytes",
|
||||
payToWitnessPubKeyHashDataSize,
|
||||
payToWitnessScriptHashDataSize,
|
||||
len(vm.witnessProgram))
|
||||
return scriptError(ErrWitnessProgramWrongLength, errStr)
|
||||
}
|
||||
} else if vm.hasFlag(ScriptVerifyDiscourageUpgradeableWitnessProgram) {
|
||||
errStr := fmt.Sprintf("new witness program versions "+
|
||||
"invalid: %v", vm.witnessProgram)
|
||||
return scriptError(ErrDiscourageUpgradableWitnessProgram, errStr)
|
||||
} else {
|
||||
// If we encounter an unknown witness program version and we
|
||||
// aren't discouraging future unknown witness based soft-forks,
|
||||
// then we de-activate the segwit behavior within the VM for
|
||||
// the remainder of execution.
|
||||
vm.witnessProgram = nil
|
||||
}
|
||||
|
||||
if vm.isWitnessVersionActive(0) {
|
||||
// All elements within the witness stack must not be greater
|
||||
// than the maximum bytes which are allowed to be pushed onto
|
||||
// the stack.
|
||||
for _, witElement := range vm.GetStack() {
|
||||
if len(witElement) > MaxScriptElementSize {
|
||||
str := fmt.Sprintf("element size %d exceeds "+
|
||||
"max allowed size %d", len(witElement),
|
||||
MaxScriptElementSize)
|
||||
return scriptError(ErrElementTooBig, str)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// DisasmPC returns the string for the disassembly of the opcode that will be
|
||||
// next to execute when Step() is called.
|
||||
func (vm *Engine) DisasmPC() (string, error) {
|
||||
@ -395,14 +247,6 @@ func (vm *Engine) CheckErrorCondition(finalScript bool) error {
|
||||
"error check when script unfinished")
|
||||
}
|
||||
|
||||
// If we're in version zero witness execution mode, and this was the
|
||||
// final script, then the stack MUST be clean in order to maintain
|
||||
// compatibility with BIP16.
|
||||
if finalScript && vm.isWitnessVersionActive(0) && vm.dstack.Depth() != 1 {
|
||||
return scriptError(ErrEvalFalse, "witness program must "+
|
||||
"have clean stack")
|
||||
}
|
||||
|
||||
if finalScript && vm.hasFlag(ScriptVerifyCleanStack) &&
|
||||
vm.dstack.Depth() != 1 {
|
||||
|
||||
@ -500,15 +344,6 @@ func (vm *Engine) Step() (done bool, err error) {
|
||||
// Set stack to be the stack from first script minus the
|
||||
// script itself
|
||||
vm.SetStack(vm.savedFirstStack[:len(vm.savedFirstStack)-1])
|
||||
} else if (vm.scriptIdx == 1 && vm.witnessProgram != nil) ||
|
||||
(vm.scriptIdx == 2 && vm.witnessProgram != nil && vm.bip16) { // Nested P2SH.
|
||||
|
||||
vm.scriptIdx++
|
||||
|
||||
witness := vm.tx.TxIn[vm.txIdx].Witness
|
||||
if err := vm.verifyWitnessProgram(witness); err != nil {
|
||||
return false, err
|
||||
}
|
||||
} else {
|
||||
vm.scriptIdx++
|
||||
}
|
||||
@ -582,13 +417,6 @@ func (vm *Engine) checkHashTypeEncoding(hashType SigHashType) error {
|
||||
// checkPubKeyEncoding returns whether or not the passed public key adheres to
|
||||
// the strict encoding requirements if enabled.
|
||||
func (vm *Engine) checkPubKeyEncoding(pubKey []byte) error {
|
||||
if vm.hasFlag(ScriptVerifyWitnessPubKeyType) &&
|
||||
vm.isWitnessVersionActive(0) && !btcec.IsCompressedPubKey(pubKey) {
|
||||
|
||||
str := "only uncompressed keys are accepted post-segwit"
|
||||
return scriptError(ErrWitnessPubKeyType, str)
|
||||
}
|
||||
|
||||
if !vm.hasFlag(ScriptVerifyStrictEncoding) {
|
||||
return nil
|
||||
}
|
||||
@ -801,7 +629,7 @@ func (vm *Engine) SetAltStack(data [][]byte) {
|
||||
// transaction, and input index. The flags modify the behavior of the script
|
||||
// engine according to the description provided by each flag.
|
||||
func NewEngine(scriptPubKey []byte, tx *wire.MsgTx, txIdx int, flags ScriptFlags,
|
||||
sigCache *SigCache, hashCache *TxSigHashes, inputAmount int64) (*Engine, error) {
|
||||
sigCache *SigCache) (*Engine, error) {
|
||||
|
||||
// The provided transaction input index must refer to a valid input.
|
||||
if txIdx < 0 || txIdx >= len(tx.TxIn) {
|
||||
@ -821,19 +649,15 @@ func NewEngine(scriptPubKey []byte, tx *wire.MsgTx, txIdx int, flags ScriptFlags
|
||||
}
|
||||
|
||||
// The clean stack flag (ScriptVerifyCleanStack) is not allowed without
|
||||
// either the pay-to-script-hash (P2SH) evaluation (ScriptBip16)
|
||||
// flag or the Segregated Witness (ScriptVerifyWitness) flag.
|
||||
// the pay-to-script-hash (P2SH) evaluation (ScriptBip16) flag.
|
||||
//
|
||||
// Recall that evaluating a P2SH script without the flag set results in
|
||||
// non-P2SH evaluation which leaves the P2SH inputs on the stack.
|
||||
// Thus, allowing the clean stack flag without the P2SH flag would make
|
||||
// it possible to have a situation where P2SH would not be a soft fork
|
||||
// when it should be. The same goes for segwit which will pull in
|
||||
// additional scripts for execution from the witness stack.
|
||||
vm := Engine{flags: flags, sigCache: sigCache, hashCache: hashCache,
|
||||
inputAmount: inputAmount}
|
||||
if vm.hasFlag(ScriptVerifyCleanStack) && (!vm.hasFlag(ScriptBip16) &&
|
||||
!vm.hasFlag(ScriptVerifyWitness)) {
|
||||
// non-P2SH evaluation which leaves the P2SH inputs on the stack. Thus,
|
||||
// allowing the clean stack flag without the P2SH flag would make it
|
||||
// possible to have a situation where P2SH would not be a soft fork when
|
||||
// it should be.
|
||||
vm := Engine{flags: flags, sigCache: sigCache}
|
||||
if vm.hasFlag(ScriptVerifyCleanStack) && !vm.hasFlag(ScriptBip16) {
|
||||
return nil, scriptError(ErrInvalidFlags,
|
||||
"invalid flags combination")
|
||||
}
|
||||
@ -884,67 +708,6 @@ func NewEngine(scriptPubKey []byte, tx *wire.MsgTx, txIdx int, flags ScriptFlags
|
||||
vm.astack.verifyMinimalData = true
|
||||
}
|
||||
|
||||
// Check to see if we should execute in witness verification mode
|
||||
// according to the set flags. We check both the pkScript, and sigScript
|
||||
// here since in the case of nested p2sh, the scriptSig will be a valid
|
||||
// witness program. For nested p2sh, all the bytes after the first data
|
||||
// push should *exactly* match the witness program template.
|
||||
if vm.hasFlag(ScriptVerifyWitness) {
|
||||
// If witness evaluation is enabled, then P2SH MUST also be
|
||||
// active.
|
||||
if !vm.hasFlag(ScriptBip16) {
|
||||
errStr := "P2SH must be enabled to do witness verification"
|
||||
return nil, scriptError(ErrInvalidFlags, errStr)
|
||||
}
|
||||
|
||||
var witProgram []byte
|
||||
|
||||
switch {
|
||||
case isWitnessProgram(vm.scripts[1]):
|
||||
// The scriptSig must be *empty* for all native witness
|
||||
// programs, otherwise we introduce malleability.
|
||||
if len(scriptSig) != 0 {
|
||||
errStr := "native witness program cannot " +
|
||||
"also have a signature script"
|
||||
return nil, scriptError(ErrWitnessMalleated, errStr)
|
||||
}
|
||||
|
||||
witProgram = scriptPubKey
|
||||
case len(tx.TxIn[txIdx].Witness) != 0 && vm.bip16:
|
||||
// The sigScript MUST be *exactly* a single canonical
|
||||
// data push of the witness program, otherwise we
|
||||
// reintroduce malleability.
|
||||
sigPops := vm.scripts[0]
|
||||
if len(sigPops) == 1 && canonicalPush(sigPops[0]) &&
|
||||
IsWitnessProgram(sigPops[0].data) {
|
||||
|
||||
witProgram = sigPops[0].data
|
||||
} else {
|
||||
errStr := "signature script for witness " +
|
||||
"nested p2sh is not canonical"
|
||||
return nil, scriptError(ErrWitnessMalleatedP2SH, errStr)
|
||||
}
|
||||
}
|
||||
|
||||
if witProgram != nil {
|
||||
var err error
|
||||
vm.witnessVersion, vm.witnessProgram, err = ExtractWitnessProgramInfo(witProgram)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
} else {
|
||||
// If we didn't find a witness program in either the
|
||||
// pkScript or as a datapush within the sigScript, then
|
||||
// there MUST NOT be any witness data associated with
|
||||
// the input being validated.
|
||||
if vm.witnessProgram == nil && len(tx.TxIn[txIdx].Witness) != 0 {
|
||||
errStr := "non-witness inputs cannot have a witness"
|
||||
return nil, scriptError(ErrWitnessUnexpected, errStr)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
vm.tx = *tx
|
||||
vm.txIdx = txIdx
|
||||
|
||||
|
@ -54,7 +54,7 @@ func TestBadPC(t *testing.T) {
|
||||
pkScript := mustParseShortForm("NOP")
|
||||
|
||||
for _, test := range tests {
|
||||
vm, err := NewEngine(pkScript, tx, 0, 0, nil, nil, -1)
|
||||
vm, err := NewEngine(pkScript, tx, 0, 0, nil)
|
||||
if err != nil {
|
||||
t.Errorf("Failed to create script: %v", err)
|
||||
}
|
||||
@ -111,7 +111,7 @@ func TestCheckErrorCondition(t *testing.T) {
|
||||
pkScript := mustParseShortForm("NOP NOP NOP NOP NOP NOP NOP NOP NOP" +
|
||||
" NOP TRUE")
|
||||
|
||||
vm, err := NewEngine(pkScript, tx, 0, 0, nil, nil, 0)
|
||||
vm, err := NewEngine(pkScript, tx, 0, 0, nil)
|
||||
if err != nil {
|
||||
t.Errorf("failed to create script: %v", err)
|
||||
}
|
||||
@ -187,7 +187,7 @@ func TestInvalidFlagCombinations(t *testing.T) {
|
||||
pkScript := []byte{OP_NOP}
|
||||
|
||||
for i, test := range tests {
|
||||
_, err := NewEngine(pkScript, tx, 0, test, nil, nil, -1)
|
||||
_, err := NewEngine(pkScript, tx, 0, test, nil)
|
||||
if !IsErrorCode(err, ErrInvalidFlags) {
|
||||
t.Fatalf("TestInvalidFlagCombinations #%d unexpected "+
|
||||
"error: %v", i, err)
|
||||
|
@ -209,15 +209,6 @@ const (
|
||||
// operations.
|
||||
ErrNullFail
|
||||
|
||||
// ErrWitnessMalleated is returned if ScriptVerifyWitness is set and a
|
||||
// native p2wsh program is encountered which has a non-empty sigScript.
|
||||
ErrWitnessMalleated
|
||||
|
||||
// ErrWitnessMalleatedP2SH is returned if ScriptVerifyWitness if set
|
||||
// and the validation logic for nested p2sh encounters a sigScript
|
||||
// which isn't *exactyl* a datapush of the witness program.
|
||||
ErrWitnessMalleatedP2SH
|
||||
|
||||
// -------------------------------
|
||||
// Failures related to soft forks.
|
||||
// -------------------------------
|
||||
@ -236,46 +227,6 @@ const (
|
||||
// reached.
|
||||
ErrUnsatisfiedLockTime
|
||||
|
||||
// ErrMinimalIf is returned if ScriptVerifyWitness is set and the
|
||||
// operand of an OP_IF/OP_NOF_IF are not either an empty vector or
|
||||
// [0x01].
|
||||
ErrMinimalIf
|
||||
|
||||
// ErrDiscourageUpgradableWitnessProgram is returned if
|
||||
// ScriptVerifyWitness is set and the versino of an executing witness
|
||||
// program is outside the set of currently defined witness program
|
||||
// vesions.
|
||||
ErrDiscourageUpgradableWitnessProgram
|
||||
|
||||
// ----------------------------------------
|
||||
// Failures related to segregated witness.
|
||||
// ----------------------------------------
|
||||
|
||||
// ErrWitnessProgramEmpty is returned if ScriptVerifyWitness is set and
|
||||
// the witness stack itself is empty.
|
||||
ErrWitnessProgramEmpty
|
||||
|
||||
// ErrWitnessProgramMismatch is returned if ScriptVerifyWitness is set
|
||||
// and the witness itself for a p2wkh witness program isn't *exactly* 2
|
||||
// items or if the witness for a p2wsh isn't the sha255 of the witness
|
||||
// script.
|
||||
ErrWitnessProgramMismatch
|
||||
|
||||
// ErrWitnessProgramWrongLength is returned if ScriptVerifyWitness is
|
||||
// set and the length of the witness program violates the length as
|
||||
// dictated by the current witness version.
|
||||
ErrWitnessProgramWrongLength
|
||||
|
||||
// ErrWitnessUnexpected is returned if ScriptVerifyWitness is set and a
|
||||
// transaction includes witness data but doesn't spend an which is a
|
||||
// witness program (nested or native).
|
||||
ErrWitnessUnexpected
|
||||
|
||||
// ErrWitnessPubKeyType is returned if ScriptVerifyWitness is set and
|
||||
// the public key used in either a check-sig or check-multi-sig isn't
|
||||
// serialized in a compressed format.
|
||||
ErrWitnessPubKeyType
|
||||
|
||||
// numErrorCodes is the maximum error code number used in tests. This
|
||||
// entry MUST be the last entry in the enum.
|
||||
numErrorCodes
|
||||
@ -283,56 +234,47 @@ const (
|
||||
|
||||
// Map of ErrorCode values back to their constant names for pretty printing.
|
||||
var errorCodeStrings = map[ErrorCode]string{
|
||||
ErrInternal: "ErrInternal",
|
||||
ErrInvalidFlags: "ErrInvalidFlags",
|
||||
ErrInvalidIndex: "ErrInvalidIndex",
|
||||
ErrUnsupportedAddress: "ErrUnsupportedAddress",
|
||||
ErrNotMultisigScript: "ErrNotMultisigScript",
|
||||
ErrTooManyRequiredSigs: "ErrTooManyRequiredSigs",
|
||||
ErrTooMuchNullData: "ErrTooMuchNullData",
|
||||
ErrEarlyReturn: "ErrEarlyReturn",
|
||||
ErrEmptyStack: "ErrEmptyStack",
|
||||
ErrEvalFalse: "ErrEvalFalse",
|
||||
ErrScriptUnfinished: "ErrScriptUnfinished",
|
||||
ErrInvalidProgramCounter: "ErrInvalidProgramCounter",
|
||||
ErrScriptTooBig: "ErrScriptTooBig",
|
||||
ErrElementTooBig: "ErrElementTooBig",
|
||||
ErrTooManyOperations: "ErrTooManyOperations",
|
||||
ErrStackOverflow: "ErrStackOverflow",
|
||||
ErrInvalidPubKeyCount: "ErrInvalidPubKeyCount",
|
||||
ErrInvalidSignatureCount: "ErrInvalidSignatureCount",
|
||||
ErrNumberTooBig: "ErrNumberTooBig",
|
||||
ErrVerify: "ErrVerify",
|
||||
ErrEqualVerify: "ErrEqualVerify",
|
||||
ErrNumEqualVerify: "ErrNumEqualVerify",
|
||||
ErrCheckSigVerify: "ErrCheckSigVerify",
|
||||
ErrCheckMultiSigVerify: "ErrCheckMultiSigVerify",
|
||||
ErrDisabledOpcode: "ErrDisabledOpcode",
|
||||
ErrReservedOpcode: "ErrReservedOpcode",
|
||||
ErrMalformedPush: "ErrMalformedPush",
|
||||
ErrInvalidStackOperation: "ErrInvalidStackOperation",
|
||||
ErrUnbalancedConditional: "ErrUnbalancedConditional",
|
||||
ErrMinimalData: "ErrMinimalData",
|
||||
ErrInvalidSigHashType: "ErrInvalidSigHashType",
|
||||
ErrSigDER: "ErrSigDER",
|
||||
ErrSigHighS: "ErrSigHighS",
|
||||
ErrNotPushOnly: "ErrNotPushOnly",
|
||||
ErrSigNullDummy: "ErrSigNullDummy",
|
||||
ErrPubKeyType: "ErrPubKeyType",
|
||||
ErrCleanStack: "ErrCleanStack",
|
||||
ErrNullFail: "ErrNullFail",
|
||||
ErrDiscourageUpgradableNOPs: "ErrDiscourageUpgradableNOPs",
|
||||
ErrNegativeLockTime: "ErrNegativeLockTime",
|
||||
ErrUnsatisfiedLockTime: "ErrUnsatisfiedLockTime",
|
||||
ErrWitnessProgramEmpty: "ErrWitnessProgramEmpty",
|
||||
ErrWitnessProgramMismatch: "ErrWitnessProgramMismatch",
|
||||
ErrWitnessProgramWrongLength: "ErrWitnessProgramWrongLength",
|
||||
ErrWitnessMalleated: "ErrWitnessMalleated",
|
||||
ErrWitnessMalleatedP2SH: "ErrWitnessMalleatedP2SH",
|
||||
ErrWitnessUnexpected: "ErrWitnessUnexpected",
|
||||
ErrMinimalIf: "ErrMinimalIf",
|
||||
ErrWitnessPubKeyType: "ErrWitnessPubKeyType",
|
||||
ErrDiscourageUpgradableWitnessProgram: "ErrDiscourageUpgradableWitnessProgram",
|
||||
ErrInternal: "ErrInternal",
|
||||
ErrInvalidFlags: "ErrInvalidFlags",
|
||||
ErrInvalidIndex: "ErrInvalidIndex",
|
||||
ErrUnsupportedAddress: "ErrUnsupportedAddress",
|
||||
ErrNotMultisigScript: "ErrNotMultisigScript",
|
||||
ErrTooManyRequiredSigs: "ErrTooManyRequiredSigs",
|
||||
ErrTooMuchNullData: "ErrTooMuchNullData",
|
||||
ErrEarlyReturn: "ErrEarlyReturn",
|
||||
ErrEmptyStack: "ErrEmptyStack",
|
||||
ErrEvalFalse: "ErrEvalFalse",
|
||||
ErrScriptUnfinished: "ErrScriptUnfinished",
|
||||
ErrInvalidProgramCounter: "ErrInvalidProgramCounter",
|
||||
ErrScriptTooBig: "ErrScriptTooBig",
|
||||
ErrElementTooBig: "ErrElementTooBig",
|
||||
ErrTooManyOperations: "ErrTooManyOperations",
|
||||
ErrStackOverflow: "ErrStackOverflow",
|
||||
ErrInvalidPubKeyCount: "ErrInvalidPubKeyCount",
|
||||
ErrInvalidSignatureCount: "ErrInvalidSignatureCount",
|
||||
ErrNumberTooBig: "ErrNumberTooBig",
|
||||
ErrVerify: "ErrVerify",
|
||||
ErrEqualVerify: "ErrEqualVerify",
|
||||
ErrNumEqualVerify: "ErrNumEqualVerify",
|
||||
ErrCheckSigVerify: "ErrCheckSigVerify",
|
||||
ErrCheckMultiSigVerify: "ErrCheckMultiSigVerify",
|
||||
ErrDisabledOpcode: "ErrDisabledOpcode",
|
||||
ErrReservedOpcode: "ErrReservedOpcode",
|
||||
ErrMalformedPush: "ErrMalformedPush",
|
||||
ErrInvalidStackOperation: "ErrInvalidStackOperation",
|
||||
ErrUnbalancedConditional: "ErrUnbalancedConditional",
|
||||
ErrMinimalData: "ErrMinimalData",
|
||||
ErrInvalidSigHashType: "ErrInvalidSigHashType",
|
||||
ErrSigDER: "ErrSigDER",
|
||||
ErrSigHighS: "ErrSigHighS",
|
||||
ErrNotPushOnly: "ErrNotPushOnly",
|
||||
ErrSigNullDummy: "ErrSigNullDummy",
|
||||
ErrPubKeyType: "ErrPubKeyType",
|
||||
ErrCleanStack: "ErrCleanStack",
|
||||
ErrNullFail: "ErrNullFail",
|
||||
ErrDiscourageUpgradableNOPs: "ErrDiscourageUpgradableNOPs",
|
||||
ErrNegativeLockTime: "ErrNegativeLockTime",
|
||||
ErrUnsatisfiedLockTime: "ErrUnsatisfiedLockTime",
|
||||
}
|
||||
|
||||
// String returns the ErrorCode as a human-readable name.
|
||||
|
@ -57,15 +57,6 @@ func TestErrorCodeStringer(t *testing.T) {
|
||||
{ErrDiscourageUpgradableNOPs, "ErrDiscourageUpgradableNOPs"},
|
||||
{ErrNegativeLockTime, "ErrNegativeLockTime"},
|
||||
{ErrUnsatisfiedLockTime, "ErrUnsatisfiedLockTime"},
|
||||
{ErrWitnessProgramEmpty, "ErrWitnessProgramEmpty"},
|
||||
{ErrWitnessProgramMismatch, "ErrWitnessProgramMismatch"},
|
||||
{ErrWitnessProgramWrongLength, "ErrWitnessProgramWrongLength"},
|
||||
{ErrWitnessMalleated, "ErrWitnessMalleated"},
|
||||
{ErrWitnessMalleatedP2SH, "ErrWitnessMalleatedP2SH"},
|
||||
{ErrWitnessUnexpected, "ErrWitnessUnexpected"},
|
||||
{ErrMinimalIf, "ErrMinimalIf"},
|
||||
{ErrWitnessPubKeyType, "ErrWitnessPubKeyType"},
|
||||
{ErrDiscourageUpgradableWitnessProgram, "ErrDiscourageUpgradableWitnessProgram"},
|
||||
{0xffff, "Unknown ErrorCode (65535)"},
|
||||
}
|
||||
|
||||
|
@ -165,8 +165,7 @@ func ExampleSignTxOutput() {
|
||||
flags := txscript.ScriptBip16 | txscript.ScriptVerifyDERSignatures |
|
||||
txscript.ScriptStrictMultiSig |
|
||||
txscript.ScriptDiscourageUpgradableNops
|
||||
vm, err := txscript.NewEngine(originTx.TxOut[0].PkScript, redeemTx, 0,
|
||||
flags, nil, nil, -1)
|
||||
vm, err := txscript.NewEngine(originTx.TxOut[0].PkScript, redeemTx, 0, flags, nil)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
return
|
||||
|
@ -1,89 +0,0 @@
|
||||
// Copyright (c) 2016 The btcsuite developers
|
||||
// Use of this source code is governed by an ISC
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package txscript
|
||||
|
||||
import (
|
||||
"sync"
|
||||
|
||||
"github.com/daglabs/btcd/chaincfg/chainhash"
|
||||
"github.com/daglabs/btcd/wire"
|
||||
)
|
||||
|
||||
// TxSigHashes houses the partial set of sighashes introduced within BIP0143.
|
||||
// This partial set of sighashes may be re-used within each input across a
|
||||
// transaction when validating all inputs. As a result, validation complexity
|
||||
// for SigHashAll can be reduced by a polynomial factor.
|
||||
type TxSigHashes struct {
|
||||
HashPrevOuts chainhash.Hash
|
||||
HashSequence chainhash.Hash
|
||||
HashOutputs chainhash.Hash
|
||||
}
|
||||
|
||||
// NewTxSigHashes computes, and returns the cached sighashes of the given
|
||||
// transaction.
|
||||
func NewTxSigHashes(tx *wire.MsgTx) *TxSigHashes {
|
||||
return &TxSigHashes{
|
||||
HashPrevOuts: calcHashPrevOuts(tx),
|
||||
HashSequence: calcHashSequence(tx),
|
||||
HashOutputs: calcHashOutputs(tx),
|
||||
}
|
||||
}
|
||||
|
||||
// HashCache houses a set of partial sighashes keyed by txid. The set of partial
|
||||
// sighashes are those introduced within BIP0143 by the new more efficient
|
||||
// sighash digest calculation algorithm. Using this threadsafe shared cache,
|
||||
// multiple goroutines can safely re-use the pre-computed partial sighashes
|
||||
// speeding up validation time amongst all inputs found within a block.
|
||||
type HashCache struct {
|
||||
sigHashes map[chainhash.Hash]*TxSigHashes
|
||||
|
||||
sync.RWMutex
|
||||
}
|
||||
|
||||
// NewHashCache returns a new instance of the HashCache given a maximum number
|
||||
// of entries which may exist within it at anytime.
|
||||
func NewHashCache(maxSize uint) *HashCache {
|
||||
return &HashCache{
|
||||
sigHashes: make(map[chainhash.Hash]*TxSigHashes, maxSize),
|
||||
}
|
||||
}
|
||||
|
||||
// AddSigHashes computes, then adds the partial sighashes for the passed
|
||||
// transaction.
|
||||
func (h *HashCache) AddSigHashes(tx *wire.MsgTx) {
|
||||
h.Lock()
|
||||
h.sigHashes[tx.TxHash()] = NewTxSigHashes(tx)
|
||||
h.Unlock()
|
||||
}
|
||||
|
||||
// ContainsHashes returns true if the partial sighashes for the passed
|
||||
// transaction currently exist within the HashCache, and false otherwise.
|
||||
func (h *HashCache) ContainsHashes(txid *chainhash.Hash) bool {
|
||||
h.RLock()
|
||||
_, found := h.sigHashes[*txid]
|
||||
h.RUnlock()
|
||||
|
||||
return found
|
||||
}
|
||||
|
||||
// GetSigHashes possibly returns the previously cached partial sighashes for
|
||||
// the passed transaction. This function also returns an additional boolean
|
||||
// value indicating if the sighashes for the passed transaction were found to
|
||||
// be present within the HashCache.
|
||||
func (h *HashCache) GetSigHashes(txid *chainhash.Hash) (*TxSigHashes, bool) {
|
||||
h.RLock()
|
||||
item, found := h.sigHashes[*txid]
|
||||
h.RUnlock()
|
||||
|
||||
return item, found
|
||||
}
|
||||
|
||||
// PurgeSigHashes removes all partial sighashes from the HashCache belonging to
|
||||
// the passed transaction.
|
||||
func (h *HashCache) PurgeSigHashes(txid *chainhash.Hash) {
|
||||
h.Lock()
|
||||
delete(h.sigHashes, *txid)
|
||||
h.Unlock()
|
||||
}
|
@ -1,182 +0,0 @@
|
||||
// Copyright (c) 2017 The btcsuite developers
|
||||
// Use of this source code is governed by an ISC
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package txscript
|
||||
|
||||
import (
|
||||
"math/rand"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/daglabs/btcd/wire"
|
||||
"github.com/davecgh/go-spew/spew"
|
||||
)
|
||||
|
||||
// genTestTx creates a random transaction for uses within test cases.
|
||||
func genTestTx() (*wire.MsgTx, error) {
|
||||
tx := wire.NewMsgTx(2)
|
||||
tx.Version = rand.Int31()
|
||||
|
||||
numTxins := rand.Intn(11)
|
||||
for i := 0; i < numTxins; i++ {
|
||||
randTxIn := wire.TxIn{
|
||||
PreviousOutPoint: wire.OutPoint{
|
||||
Index: uint32(rand.Int31()),
|
||||
},
|
||||
Sequence: uint32(rand.Int31()),
|
||||
}
|
||||
_, err := rand.Read(randTxIn.PreviousOutPoint.Hash[:])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
tx.TxIn = append(tx.TxIn, &randTxIn)
|
||||
}
|
||||
|
||||
numTxouts := rand.Intn(11)
|
||||
for i := 0; i < numTxouts; i++ {
|
||||
randTxOut := wire.TxOut{
|
||||
Value: rand.Int63(),
|
||||
PkScript: make([]byte, rand.Intn(30)),
|
||||
}
|
||||
if _, err := rand.Read(randTxOut.PkScript); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
tx.TxOut = append(tx.TxOut, &randTxOut)
|
||||
}
|
||||
|
||||
return tx, nil
|
||||
}
|
||||
|
||||
// TestHashCacheAddContainsHashes tests that after items have been added to the
|
||||
// hash cache, the ContainsHashes method returns true for all the items
|
||||
// inserted. Conversely, ContainsHashes should return false for any items
|
||||
// _not_ in the hash cache.
|
||||
func TestHashCacheAddContainsHashes(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
rand.Seed(time.Now().Unix())
|
||||
|
||||
cache := NewHashCache(10)
|
||||
|
||||
var err error
|
||||
|
||||
// First, we'll generate 10 random transactions for use within our
|
||||
// tests.
|
||||
const numTxns = 10
|
||||
txns := make([]*wire.MsgTx, numTxns)
|
||||
for i := 0; i < numTxns; i++ {
|
||||
txns[i], err = genTestTx()
|
||||
if err != nil {
|
||||
t.Fatalf("unable to generate test tx: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
// With the transactions generated, we'll add each of them to the hash
|
||||
// cache.
|
||||
for _, tx := range txns {
|
||||
cache.AddSigHashes(tx)
|
||||
}
|
||||
|
||||
// Next, we'll ensure that each of the transactions inserted into the
|
||||
// cache are properly located by the ContainsHashes method.
|
||||
for _, tx := range txns {
|
||||
txid := tx.TxHash()
|
||||
if ok := cache.ContainsHashes(&txid); !ok {
|
||||
t.Fatalf("txid %v not found in cache but should be: ",
|
||||
txid)
|
||||
}
|
||||
}
|
||||
|
||||
randTx, err := genTestTx()
|
||||
if err != nil {
|
||||
t.Fatalf("unable to generate tx: %v", err)
|
||||
}
|
||||
|
||||
// Finally, we'll assert that a transaction that wasn't added to the
|
||||
// cache won't be reported as being present by the ContainsHashes
|
||||
// method.
|
||||
randTxid := randTx.TxHash()
|
||||
if ok := cache.ContainsHashes(&randTxid); ok {
|
||||
t.Fatalf("txid %v wasn't inserted into cache but was found",
|
||||
randTxid)
|
||||
}
|
||||
}
|
||||
|
||||
// TestHashCacheAddGet tests that the sighashes for a particular transaction
|
||||
// are properly retrieved by the GetSigHashes function.
|
||||
func TestHashCacheAddGet(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
rand.Seed(time.Now().Unix())
|
||||
|
||||
cache := NewHashCache(10)
|
||||
|
||||
// To start, we'll generate a random transaction and compute the set of
|
||||
// sighashes for the transaction.
|
||||
randTx, err := genTestTx()
|
||||
if err != nil {
|
||||
t.Fatalf("unable to generate tx: %v", err)
|
||||
}
|
||||
sigHashes := NewTxSigHashes(randTx)
|
||||
|
||||
// Next, add the transaction to the hash cache.
|
||||
cache.AddSigHashes(randTx)
|
||||
|
||||
// The transaction inserted into the cache above should be found.
|
||||
txid := randTx.TxHash()
|
||||
cacheHashes, ok := cache.GetSigHashes(&txid)
|
||||
if !ok {
|
||||
t.Fatalf("tx %v wasn't found in cache", txid)
|
||||
}
|
||||
|
||||
// Finally, the sighashes retrieved should exactly match the sighash
|
||||
// originally inserted into the cache.
|
||||
if *sigHashes != *cacheHashes {
|
||||
t.Fatalf("sighashes don't match: expected %v, got %v",
|
||||
spew.Sdump(sigHashes), spew.Sdump(cacheHashes))
|
||||
}
|
||||
}
|
||||
|
||||
// TestHashCachePurge tests that items are able to be properly removed from the
|
||||
// hash cache.
|
||||
func TestHashCachePurge(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
rand.Seed(time.Now().Unix())
|
||||
|
||||
cache := NewHashCache(10)
|
||||
|
||||
var err error
|
||||
|
||||
// First we'll start by inserting numTxns transactions into the hash cache.
|
||||
const numTxns = 10
|
||||
txns := make([]*wire.MsgTx, numTxns)
|
||||
for i := 0; i < numTxns; i++ {
|
||||
txns[i], err = genTestTx()
|
||||
if err != nil {
|
||||
t.Fatalf("unable to generate test tx: %v", err)
|
||||
}
|
||||
}
|
||||
for _, tx := range txns {
|
||||
cache.AddSigHashes(tx)
|
||||
}
|
||||
|
||||
// Once all the transactions have been inserted, we'll purge them from
|
||||
// the hash cache.
|
||||
for _, tx := range txns {
|
||||
txid := tx.TxHash()
|
||||
cache.PurgeSigHashes(&txid)
|
||||
}
|
||||
|
||||
// At this point, none of the transactions inserted into the hash cache
|
||||
// should be found within the cache.
|
||||
for _, tx := range txns {
|
||||
txid := tx.TxHash()
|
||||
if ok := cache.ContainsHashes(&txid); ok {
|
||||
t.Fatalf("tx %v found in cache but should have "+
|
||||
"been purged: ", txid)
|
||||
}
|
||||
}
|
||||
}
|
@ -918,47 +918,6 @@ func opcodeNop(op *parsedOpcode, vm *Engine) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// popIfBool enforces the "minimal if" policy during script execution if the
|
||||
// particular flag is set. If so, in order to eliminate an additional source
|
||||
// of nuisance malleability, post-segwit for version 0 witness programs, we now
|
||||
// require the following: for OP_IF and OP_NOT_IF, the top stack item MUST
|
||||
// either be an empty byte slice, or [0x01]. Otherwise, the item at the top of
|
||||
// the stack will be popped and interpreted as a boolean.
|
||||
func popIfBool(vm *Engine) (bool, error) {
|
||||
// When not in witness execution mode, not executing a v0 witness
|
||||
// program, or the minimal if flag isn't set pop the top stack item as
|
||||
// a normal bool.
|
||||
if !vm.isWitnessVersionActive(0) || !vm.hasFlag(ScriptVerifyMinimalIf) {
|
||||
return vm.dstack.PopBool()
|
||||
}
|
||||
|
||||
// At this point, a v0 witness program is being executed and the minimal
|
||||
// if flag is set, so enforce additional constraints on the top stack
|
||||
// item.
|
||||
so, err := vm.dstack.PopByteArray()
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
// The top element MUST have a length of at least one.
|
||||
if len(so) > 1 {
|
||||
str := fmt.Sprintf("minimal if is active, top element MUST "+
|
||||
"have a length of at least, instead length is %v",
|
||||
len(so))
|
||||
return false, scriptError(ErrMinimalIf, str)
|
||||
}
|
||||
|
||||
// Additionally, if the length is one, then the value MUST be 0x01.
|
||||
if len(so) == 1 && so[0] != 0x01 {
|
||||
str := fmt.Sprintf("minimal if is active, top stack item MUST "+
|
||||
"be an empty byte array or 0x01, is instead: %v",
|
||||
so[0])
|
||||
return false, scriptError(ErrMinimalIf, str)
|
||||
}
|
||||
|
||||
return asBool(so), nil
|
||||
}
|
||||
|
||||
// opcodeIf treats the top item on the data stack as a boolean and removes it.
|
||||
//
|
||||
// An appropriate entry is added to the conditional stack depending on whether
|
||||
@ -977,7 +936,8 @@ func popIfBool(vm *Engine) (bool, error) {
|
||||
func opcodeIf(op *parsedOpcode, vm *Engine) error {
|
||||
condVal := OpCondFalse
|
||||
if vm.isBranchExecuting() {
|
||||
ok, err := popIfBool(vm)
|
||||
ok, err := vm.dstack.PopBool()
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -1011,7 +971,7 @@ func opcodeIf(op *parsedOpcode, vm *Engine) error {
|
||||
func opcodeNotIf(op *parsedOpcode, vm *Engine) error {
|
||||
condVal := OpCondFalse
|
||||
if vm.isBranchExecuting() {
|
||||
ok, err := popIfBool(vm)
|
||||
ok, err := vm.dstack.PopBool()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -2088,28 +2048,12 @@ func opcodeCheckSig(op *parsedOpcode, vm *Engine) error {
|
||||
// Get script starting from the most recent OP_CODESEPARATOR.
|
||||
subScript := vm.subScript()
|
||||
|
||||
// Remove the signature since there is no way for a signature
|
||||
// to sign itself.
|
||||
subScript = removeOpcodeByData(subScript, fullSigBytes)
|
||||
|
||||
// Generate the signature hash based on the signature hash type.
|
||||
var hash []byte
|
||||
if vm.isWitnessVersionActive(0) {
|
||||
var sigHashes *TxSigHashes
|
||||
if vm.hashCache != nil {
|
||||
sigHashes = vm.hashCache
|
||||
} else {
|
||||
sigHashes = NewTxSigHashes(&vm.tx)
|
||||
}
|
||||
|
||||
hash, err = calcWitnessSignatureHash(subScript, sigHashes, hashType,
|
||||
&vm.tx, vm.txIdx, vm.inputAmount)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
// Remove the signature since there is no way for a signature
|
||||
// to sign itself.
|
||||
subScript = removeOpcodeByData(subScript, fullSigBytes)
|
||||
|
||||
hash = calcSignatureHash(subScript, hashType, &vm.tx, vm.txIdx)
|
||||
}
|
||||
hash := calcSignatureHash(subScript, hashType, &vm.tx, vm.txIdx)
|
||||
|
||||
pubKey, err := btcec.ParsePubKey(pkBytes, btcec.S256())
|
||||
if err != nil {
|
||||
@ -2275,12 +2219,9 @@ func opcodeCheckMultiSig(op *parsedOpcode, vm *Engine) error {
|
||||
// Get script starting from the most recent OP_CODESEPARATOR.
|
||||
script := vm.subScript()
|
||||
|
||||
// Remove the signature in pre version 0 segwit scripts since there is
|
||||
// no way for a signature to sign itself.
|
||||
if !vm.isWitnessVersionActive(0) {
|
||||
for _, sigInfo := range signatures {
|
||||
script = removeOpcodeByData(script, sigInfo.signature)
|
||||
}
|
||||
// Remove the signatures in scripts since there is no way for a signature to sign itself.
|
||||
for _, sigInfo := range signatures {
|
||||
script = removeOpcodeByData(script, sigInfo.signature)
|
||||
}
|
||||
|
||||
success := true
|
||||
@ -2362,23 +2303,7 @@ func opcodeCheckMultiSig(op *parsedOpcode, vm *Engine) error {
|
||||
}
|
||||
|
||||
// Generate the signature hash based on the signature hash type.
|
||||
var hash []byte
|
||||
if vm.isWitnessVersionActive(0) {
|
||||
var sigHashes *TxSigHashes
|
||||
if vm.hashCache != nil {
|
||||
sigHashes = vm.hashCache
|
||||
} else {
|
||||
sigHashes = NewTxSigHashes(&vm.tx)
|
||||
}
|
||||
|
||||
hash, err = calcWitnessSignatureHash(script, sigHashes, hashType,
|
||||
&vm.tx, vm.txIdx, vm.inputAmount)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
hash = calcSignatureHash(script, hashType, &vm.tx, vm.txIdx)
|
||||
}
|
||||
hash := calcSignatureHash(script, hashType, &vm.tx, vm.txIdx)
|
||||
|
||||
var valid bool
|
||||
if vm.sigCache != nil {
|
||||
|
@ -23,16 +23,9 @@ import (
|
||||
// scriptTestName returns a descriptive test name for the given reference script
|
||||
// test data.
|
||||
func scriptTestName(test []interface{}) (string, error) {
|
||||
// Account for any optional leading witness data.
|
||||
var witnessOffset int
|
||||
if _, ok := test[0].([]interface{}); ok {
|
||||
witnessOffset++
|
||||
}
|
||||
|
||||
// In addition to the optional leading witness data, the test must
|
||||
// consist of at least a signature script, public key script, flags,
|
||||
// The test must consist of a signature script, public key script, flags,
|
||||
// and expected error. Finally, it may optionally contain a comment.
|
||||
if len(test) < witnessOffset+4 || len(test) > witnessOffset+5 {
|
||||
if len(test) < 4 || len(test) > 5 {
|
||||
return "", fmt.Errorf("invalid test length %d", len(test))
|
||||
}
|
||||
|
||||
@ -40,11 +33,11 @@ func scriptTestName(test []interface{}) (string, error) {
|
||||
// construct the name based on the signature script, public key script,
|
||||
// and flags.
|
||||
var name string
|
||||
if len(test) == witnessOffset+5 {
|
||||
name = fmt.Sprintf("test (%s)", test[witnessOffset+4])
|
||||
if len(test) == 5 {
|
||||
name = fmt.Sprintf("test (%s)", test[4])
|
||||
} else {
|
||||
name = fmt.Sprintf("test ([%s, %s, %s])", test[witnessOffset],
|
||||
test[witnessOffset+1], test[witnessOffset+2])
|
||||
name = fmt.Sprintf("test ([%s, %s, %s])", test[0],
|
||||
test[1], test[2])
|
||||
}
|
||||
return name, nil
|
||||
}
|
||||
@ -57,22 +50,6 @@ func parseHex(tok string) ([]byte, error) {
|
||||
return hex.DecodeString(tok[2:])
|
||||
}
|
||||
|
||||
// parseWitnessStack parses a json array of witness items encoded as hex into a
|
||||
// slice of witness elements.
|
||||
func parseWitnessStack(elements []interface{}) ([][]byte, error) {
|
||||
witness := make([][]byte, len(elements))
|
||||
for i, e := range elements {
|
||||
witElement, err := hex.DecodeString(e.(string))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
witness[i] = witElement
|
||||
}
|
||||
|
||||
return witness, nil
|
||||
}
|
||||
|
||||
// shortFormOps holds a map of opcode names to values for use in short form
|
||||
// parsing. It is declared here so it only needs to be created once.
|
||||
var shortFormOps map[string]byte
|
||||
@ -184,14 +161,6 @@ func parseScriptFlags(flagStr string) (ScriptFlags, error) {
|
||||
flags |= ScriptVerifySigPushOnly
|
||||
case "STRICTENC":
|
||||
flags |= ScriptVerifyStrictEncoding
|
||||
case "WITNESS":
|
||||
flags |= ScriptVerifyWitness
|
||||
case "DISCOURAGE_UPGRADABLE_WITNESS_PROGRAM":
|
||||
flags |= ScriptVerifyDiscourageUpgradeableWitnessProgram
|
||||
case "MINIMALIF":
|
||||
flags |= ScriptVerifyMinimalIf
|
||||
case "WITNESS_PUBKEYTYPE":
|
||||
flags |= ScriptVerifyWitnessPubKeyType
|
||||
default:
|
||||
return flags, fmt.Errorf("invalid flag: %s", flag)
|
||||
}
|
||||
@ -261,24 +230,6 @@ func parseExpectedResult(expected string) ([]ErrorCode, error) {
|
||||
return []ErrorCode{ErrNegativeLockTime}, nil
|
||||
case "UNSATISFIED_LOCKTIME":
|
||||
return []ErrorCode{ErrUnsatisfiedLockTime}, nil
|
||||
case "MINIMALIF":
|
||||
return []ErrorCode{ErrMinimalIf}, nil
|
||||
case "DISCOURAGE_UPGRADABLE_WITNESS_PROGRAM":
|
||||
return []ErrorCode{ErrDiscourageUpgradableWitnessProgram}, nil
|
||||
case "WITNESS_PROGRAM_WRONG_LENGTH":
|
||||
return []ErrorCode{ErrWitnessProgramWrongLength}, nil
|
||||
case "WITNESS_PROGRAM_WITNESS_EMPTY":
|
||||
return []ErrorCode{ErrWitnessProgramEmpty}, nil
|
||||
case "WITNESS_PROGRAM_MISMATCH":
|
||||
return []ErrorCode{ErrWitnessProgramMismatch}, nil
|
||||
case "WITNESS_MALLEATED":
|
||||
return []ErrorCode{ErrWitnessMalleated}, nil
|
||||
case "WITNESS_MALLEATED_P2SH":
|
||||
return []ErrorCode{ErrWitnessMalleatedP2SH}, nil
|
||||
case "WITNESS_UNEXPECTED":
|
||||
return []ErrorCode{ErrWitnessUnexpected}, nil
|
||||
case "WITNESS_PUBKEYTYPE":
|
||||
return []ErrorCode{ErrWitnessPubKeyType}, nil
|
||||
}
|
||||
|
||||
return nil, fmt.Errorf("unrecognized expected result in test data: %v",
|
||||
@ -286,23 +237,21 @@ func parseExpectedResult(expected string) ([]ErrorCode, error) {
|
||||
}
|
||||
|
||||
// createSpendTx generates a basic spending transaction given the passed
|
||||
// signature, witness and public key scripts.
|
||||
func createSpendingTx(witness [][]byte, sigScript, pkScript []byte,
|
||||
outputValue int64) *wire.MsgTx {
|
||||
|
||||
// signature and public key scripts.
|
||||
func createSpendingTx(sigScript, pkScript []byte) *wire.MsgTx {
|
||||
coinbaseTx := wire.NewMsgTx(wire.TxVersion)
|
||||
|
||||
outPoint := wire.NewOutPoint(&chainhash.Hash{}, ^uint32(0))
|
||||
txIn := wire.NewTxIn(outPoint, []byte{OP_0, OP_0}, nil)
|
||||
txOut := wire.NewTxOut(outputValue, pkScript)
|
||||
txOut := wire.NewTxOut(0, pkScript)
|
||||
coinbaseTx.AddTxIn(txIn)
|
||||
coinbaseTx.AddTxOut(txOut)
|
||||
|
||||
spendingTx := wire.NewMsgTx(wire.TxVersion)
|
||||
coinbaseTxSha := coinbaseTx.TxHash()
|
||||
outPoint = wire.NewOutPoint(&coinbaseTxSha, 0)
|
||||
txIn = wire.NewTxIn(outPoint, sigScript, witness)
|
||||
txOut = wire.NewTxOut(outputValue, nil)
|
||||
coinbaseTxHash := coinbaseTx.TxHash()
|
||||
outPoint = wire.NewOutPoint(&coinbaseTxHash, 0)
|
||||
txIn = wire.NewTxIn(outPoint, sigScript, nil)
|
||||
txOut = wire.NewTxOut(0, nil)
|
||||
|
||||
spendingTx.AddTxIn(txIn)
|
||||
spendingTx.AddTxOut(txOut)
|
||||
@ -310,14 +259,6 @@ func createSpendingTx(witness [][]byte, sigScript, pkScript []byte,
|
||||
return spendingTx
|
||||
}
|
||||
|
||||
// scriptWithInputVal wraps a target pkScript with the value of the output in
|
||||
// which it is contained. The inputVal is necessary in order to properly
|
||||
// validate inputs which spend nested, or native witness programs.
|
||||
type scriptWithInputVal struct {
|
||||
inputVal int64
|
||||
pkScript []byte
|
||||
}
|
||||
|
||||
// testScripts ensures all of the passed script tests execute with the expected
|
||||
// results with or without using a signature cache, as specified by the
|
||||
// parameter.
|
||||
@ -345,39 +286,8 @@ func testScripts(t *testing.T, tests [][]interface{}, useSigCache bool) {
|
||||
continue
|
||||
}
|
||||
|
||||
var (
|
||||
witness wire.TxWitness
|
||||
inputAmt btcutil.Amount
|
||||
)
|
||||
|
||||
// When the first field of the test data is a slice it contains
|
||||
// witness data and everything else is offset by 1 as a result.
|
||||
witnessOffset := 0
|
||||
if witnessData, ok := test[0].([]interface{}); ok {
|
||||
witnessOffset++
|
||||
|
||||
// If this is a witness test, then the final element
|
||||
// within the slice is the input amount, so we ignore
|
||||
// all but the last element in order to parse the
|
||||
// witness stack.
|
||||
strWitnesses := witnessData[:len(witnessData)-1]
|
||||
witness, err = parseWitnessStack(strWitnesses)
|
||||
if err != nil {
|
||||
t.Errorf("%s: can't parse witness; %v", name, err)
|
||||
continue
|
||||
}
|
||||
|
||||
inputAmt, err = btcutil.NewAmount(witnessData[len(witnessData)-1].(float64))
|
||||
if err != nil {
|
||||
t.Errorf("%s: can't parse input amt: %v",
|
||||
name, err)
|
||||
continue
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Extract and parse the signature script from the test fields.
|
||||
scriptSigStr, ok := test[witnessOffset].(string)
|
||||
scriptSigStr, ok := test[0].(string)
|
||||
if !ok {
|
||||
t.Errorf("%s: signature script is not a string", name)
|
||||
continue
|
||||
@ -390,7 +300,7 @@ func testScripts(t *testing.T, tests [][]interface{}, useSigCache bool) {
|
||||
}
|
||||
|
||||
// Extract and parse the public key script from the test fields.
|
||||
scriptPubKeyStr, ok := test[witnessOffset+1].(string)
|
||||
scriptPubKeyStr, ok := test[1].(string)
|
||||
if !ok {
|
||||
t.Errorf("%s: public key script is not a string", name)
|
||||
continue
|
||||
@ -403,7 +313,7 @@ func testScripts(t *testing.T, tests [][]interface{}, useSigCache bool) {
|
||||
}
|
||||
|
||||
// Extract and parse the script flags from the test fields.
|
||||
flagsStr, ok := test[witnessOffset+2].(string)
|
||||
flagsStr, ok := test[2].(string)
|
||||
if !ok {
|
||||
t.Errorf("%s: flags field is not a string", name)
|
||||
continue
|
||||
@ -421,7 +331,7 @@ func testScripts(t *testing.T, tests [][]interface{}, useSigCache bool) {
|
||||
// fine grained with its errors than the reference test data, so
|
||||
// some of the reference test data errors map to more than one
|
||||
// possibility.
|
||||
resultStr, ok := test[witnessOffset+3].(string)
|
||||
resultStr, ok := test[3].(string)
|
||||
if !ok {
|
||||
t.Errorf("%s: result field is not a string", name)
|
||||
continue
|
||||
@ -435,10 +345,8 @@ func testScripts(t *testing.T, tests [][]interface{}, useSigCache bool) {
|
||||
// Generate a transaction pair such that one spends from the
|
||||
// other and the provided signature and public key scripts are
|
||||
// used, then create a new engine to execute the scripts.
|
||||
tx := createSpendingTx(witness, scriptSig, scriptPubKey,
|
||||
int64(inputAmt))
|
||||
vm, err := NewEngine(scriptPubKey, tx, 0, flags, sigCache, nil,
|
||||
int64(inputAmt))
|
||||
tx := createSpendingTx(scriptSig, scriptPubKey)
|
||||
vm, err := NewEngine(scriptPubKey, tx, 0, flags, sigCache)
|
||||
if err == nil {
|
||||
err = vm.Execute()
|
||||
}
|
||||
@ -566,7 +474,7 @@ testloop:
|
||||
continue
|
||||
}
|
||||
|
||||
prevOuts := make(map[wire.OutPoint]scriptWithInputVal)
|
||||
prevOuts := make(map[wire.OutPoint][]byte)
|
||||
for j, iinput := range inputs {
|
||||
input, ok := iinput.([]interface{})
|
||||
if !ok {
|
||||
@ -575,7 +483,7 @@ testloop:
|
||||
continue testloop
|
||||
}
|
||||
|
||||
if len(input) < 3 || len(input) > 4 {
|
||||
if len(input) != 3 {
|
||||
t.Errorf("bad test (%dth input wrong length)"+
|
||||
"%d: %v", j, i, test)
|
||||
continue testloop
|
||||
@ -617,25 +525,11 @@ testloop:
|
||||
continue testloop
|
||||
}
|
||||
|
||||
var inputValue float64
|
||||
if len(input) == 4 {
|
||||
inputValue, ok = input[3].(float64)
|
||||
if !ok {
|
||||
t.Errorf("bad test (%dth input value not int) "+
|
||||
"%d: %v", j, i, test)
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
v := scriptWithInputVal{
|
||||
inputVal: int64(inputValue),
|
||||
pkScript: script,
|
||||
}
|
||||
prevOuts[*wire.NewOutPoint(prevhash, idx)] = v
|
||||
prevOuts[*wire.NewOutPoint(prevhash, idx)] = script
|
||||
}
|
||||
|
||||
for k, txin := range tx.MsgTx().TxIn {
|
||||
prevOut, ok := prevOuts[txin.PreviousOutPoint]
|
||||
pkScript, ok := prevOuts[txin.PreviousOutPoint]
|
||||
if !ok {
|
||||
t.Errorf("bad test (missing %dth input) %d:%v",
|
||||
k, i, test)
|
||||
@ -644,8 +538,7 @@ testloop:
|
||||
// These are meant to fail, so as soon as the first
|
||||
// input fails the transaction has failed. (some of the
|
||||
// test txns have good inputs, too..
|
||||
vm, err := NewEngine(prevOut.pkScript, tx.MsgTx(), k,
|
||||
flags, nil, nil, prevOut.inputVal)
|
||||
vm, err := NewEngine(pkScript, tx.MsgTx(), k, flags, nil)
|
||||
if err != nil {
|
||||
continue testloop
|
||||
}
|
||||
@ -677,7 +570,7 @@ func TestTxValidTests(t *testing.T) {
|
||||
// form is either:
|
||||
// ["this is a comment "]
|
||||
// or:
|
||||
// [[[previous hash, previous index, previous scriptPubKey, input value]...,]
|
||||
// [[[previous hash, previous index, previous scriptPubKey]...,]
|
||||
// serializedTransaction, verifyFlags]
|
||||
testloop:
|
||||
for i, test := range tests {
|
||||
@ -721,7 +614,7 @@ testloop:
|
||||
continue
|
||||
}
|
||||
|
||||
prevOuts := make(map[wire.OutPoint]scriptWithInputVal)
|
||||
prevOuts := make(map[wire.OutPoint][]byte)
|
||||
for j, iinput := range inputs {
|
||||
input, ok := iinput.([]interface{})
|
||||
if !ok {
|
||||
@ -730,7 +623,7 @@ testloop:
|
||||
continue
|
||||
}
|
||||
|
||||
if len(input) < 3 || len(input) > 4 {
|
||||
if len(input) != 3 {
|
||||
t.Errorf("bad test (%dth input wrong length)"+
|
||||
"%d: %v", j, i, test)
|
||||
continue
|
||||
@ -772,32 +665,21 @@ testloop:
|
||||
continue
|
||||
}
|
||||
|
||||
var inputValue float64
|
||||
if len(input) == 4 {
|
||||
inputValue, ok = input[3].(float64)
|
||||
if !ok {
|
||||
t.Errorf("bad test (%dth input value not int) "+
|
||||
"%d: %v", j, i, test)
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
v := scriptWithInputVal{
|
||||
inputVal: int64(inputValue),
|
||||
pkScript: script,
|
||||
}
|
||||
prevOuts[*wire.NewOutPoint(prevhash, idx)] = v
|
||||
prevOuts[*wire.NewOutPoint(prevhash, idx)] = script
|
||||
}
|
||||
|
||||
for k, txin := range tx.MsgTx().TxIn {
|
||||
prevOut, ok := prevOuts[txin.PreviousOutPoint]
|
||||
pkScript, ok := prevOuts[txin.PreviousOutPoint]
|
||||
if !ok {
|
||||
t.Errorf("bad test (missing %dth input) %d:%v",
|
||||
k, i, test)
|
||||
continue testloop
|
||||
}
|
||||
vm, err := NewEngine(prevOut.pkScript, tx.MsgTx(), k,
|
||||
flags, nil, nil, prevOut.inputVal)
|
||||
|
||||
if i == 93 {
|
||||
fmt.Printf("lalala")
|
||||
}
|
||||
vm, err := NewEngine(pkScript, tx.MsgTx(), k, flags, nil)
|
||||
if err != nil {
|
||||
t.Errorf("test (%d:%v:%d) failed to create "+
|
||||
"script: %v", i, test, k, err)
|
||||
|
@ -70,98 +70,6 @@ func IsPayToScriptHash(script []byte) bool {
|
||||
return isScriptHash(pops)
|
||||
}
|
||||
|
||||
// isWitnessScriptHash returns true if the passed script is a
|
||||
// pay-to-witness-script-hash transaction, false otherwise.
|
||||
func isWitnessScriptHash(pops []parsedOpcode) bool {
|
||||
return len(pops) == 2 &&
|
||||
pops[0].opcode.value == OP_0 &&
|
||||
pops[1].opcode.value == OP_DATA_32
|
||||
}
|
||||
|
||||
// IsPayToWitnessScriptHash returns true if the is in the standard
|
||||
// pay-to-witness-script-hash (P2WSH) format, false otherwise.
|
||||
func IsPayToWitnessScriptHash(script []byte) bool {
|
||||
pops, err := parseScript(script)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
return isWitnessScriptHash(pops)
|
||||
}
|
||||
|
||||
// IsPayToWitnessPubKeyHash returns true if the is in the standard
|
||||
// pay-to-witness-pubkey-hash (P2WKH) format, false otherwise.
|
||||
func IsPayToWitnessPubKeyHash(script []byte) bool {
|
||||
pops, err := parseScript(script)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
return isWitnessPubKeyHash(pops)
|
||||
}
|
||||
|
||||
// isWitnessPubKeyHash returns true if the passed script is a
|
||||
// pay-to-witness-pubkey-hash, and false otherwise.
|
||||
func isWitnessPubKeyHash(pops []parsedOpcode) bool {
|
||||
return len(pops) == 2 &&
|
||||
pops[0].opcode.value == OP_0 &&
|
||||
pops[1].opcode.value == OP_DATA_20
|
||||
}
|
||||
|
||||
// IsWitnessProgram returns true if the passed script is a valid witness
|
||||
// program which is encoded according to the passed witness program version. A
|
||||
// witness program must be a small integer (from 0-16), followed by 2-40 bytes
|
||||
// of pushed data.
|
||||
func IsWitnessProgram(script []byte) bool {
|
||||
// The length of the script must be between 4 and 42 bytes. The
|
||||
// smallest program is the witness version, followed by a data push of
|
||||
// 2 bytes. The largest allowed witness program has a data push of
|
||||
// 40-bytes.
|
||||
if len(script) < 4 || len(script) > 42 {
|
||||
return false
|
||||
}
|
||||
|
||||
pops, err := parseScript(script)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
|
||||
return isWitnessProgram(pops)
|
||||
}
|
||||
|
||||
// isWitnessProgram returns true if the passed script is a witness program, and
|
||||
// false otherwise. A witness program MUST adhere to the following constraints:
|
||||
// there must be exactly two pops (program version and the program itself), the
|
||||
// first opcode MUST be a small integer (0-16), the push data MUST be
|
||||
// canonical, and finally the size of the push data must be between 2 and 40
|
||||
// bytes.
|
||||
func isWitnessProgram(pops []parsedOpcode) bool {
|
||||
return len(pops) == 2 &&
|
||||
isSmallInt(pops[0].opcode) &&
|
||||
canonicalPush(pops[1]) &&
|
||||
(len(pops[1].data) >= 2 && len(pops[1].data) <= 40)
|
||||
}
|
||||
|
||||
// ExtractWitnessProgramInfo attempts to extract the witness program version,
|
||||
// as well as the witness program itself from the passed script.
|
||||
func ExtractWitnessProgramInfo(script []byte) (int, []byte, error) {
|
||||
pops, err := parseScript(script)
|
||||
if err != nil {
|
||||
return 0, nil, err
|
||||
}
|
||||
|
||||
// If at this point, the scripts doesn't resemble a witness program,
|
||||
// then we'll exit early as there isn't a valid version or program to
|
||||
// extract.
|
||||
if !isWitnessProgram(pops) {
|
||||
return 0, nil, fmt.Errorf("script is not a witness program, " +
|
||||
"unable to extract version or witness program")
|
||||
}
|
||||
|
||||
witnessVersion := asSmallInt(pops[0].opcode)
|
||||
witnessProgram := pops[1].data
|
||||
|
||||
return witnessVersion, witnessProgram, nil
|
||||
}
|
||||
|
||||
// isPushOnly returns true if the script only pushes data, false otherwise.
|
||||
func isPushOnly(pops []parsedOpcode) bool {
|
||||
// NOTE: This function does NOT verify opcodes directly since it is
|
||||
@ -370,190 +278,6 @@ func removeOpcodeByData(pkscript []parsedOpcode, data []byte) []parsedOpcode {
|
||||
|
||||
}
|
||||
|
||||
// calcHashPrevOuts calculates a single hash of all the previous outputs
|
||||
// (txid:index) referenced within the passed transaction. This calculated hash
|
||||
// can be re-used when validating all inputs spending segwit outputs, with a
|
||||
// signature hash type of SigHashAll. This allows validation to re-use previous
|
||||
// hashing computation, reducing the complexity of validating SigHashAll inputs
|
||||
// from O(N^2) to O(N).
|
||||
func calcHashPrevOuts(tx *wire.MsgTx) chainhash.Hash {
|
||||
var b bytes.Buffer
|
||||
for _, in := range tx.TxIn {
|
||||
// First write out the 32-byte transaction ID one of whose
|
||||
// outputs are being referenced by this input.
|
||||
b.Write(in.PreviousOutPoint.Hash[:])
|
||||
|
||||
// Next, we'll encode the index of the referenced output as a
|
||||
// little endian integer.
|
||||
var buf [4]byte
|
||||
binary.LittleEndian.PutUint32(buf[:], in.PreviousOutPoint.Index)
|
||||
b.Write(buf[:])
|
||||
}
|
||||
|
||||
return chainhash.DoubleHashH(b.Bytes())
|
||||
}
|
||||
|
||||
// calcHashSequence computes an aggregated hash of each of the sequence numbers
|
||||
// within the inputs of the passed transaction. This single hash can be re-used
|
||||
// when validating all inputs spending segwit outputs, which include signatures
|
||||
// using the SigHashAll sighash type. This allows validation to re-use previous
|
||||
// hashing computation, reducing the complexity of validating SigHashAll inputs
|
||||
// from O(N^2) to O(N).
|
||||
func calcHashSequence(tx *wire.MsgTx) chainhash.Hash {
|
||||
var b bytes.Buffer
|
||||
for _, in := range tx.TxIn {
|
||||
var buf [4]byte
|
||||
binary.LittleEndian.PutUint32(buf[:], in.Sequence)
|
||||
b.Write(buf[:])
|
||||
}
|
||||
|
||||
return chainhash.DoubleHashH(b.Bytes())
|
||||
}
|
||||
|
||||
// calcHashOutputs computes a hash digest of all outputs created by the
|
||||
// transaction encoded using the wire format. This single hash can be re-used
|
||||
// when validating all inputs spending witness programs, which include
|
||||
// signatures using the SigHashAll sighash type. This allows computation to be
|
||||
// cached, reducing the total hashing complexity from O(N^2) to O(N).
|
||||
func calcHashOutputs(tx *wire.MsgTx) chainhash.Hash {
|
||||
var b bytes.Buffer
|
||||
for _, out := range tx.TxOut {
|
||||
wire.WriteTxOut(&b, 0, 0, out)
|
||||
}
|
||||
|
||||
return chainhash.DoubleHashH(b.Bytes())
|
||||
}
|
||||
|
||||
// calcWitnessSignatureHash computes the sighash digest of a transaction's
|
||||
// segwit input using the new, optimized digest calculation algorithm defined
|
||||
// in BIP0143: https://github.com/bitcoin/bips/blob/master/bip-0143.mediawiki.
|
||||
// This function makes use of pre-calculated sighash fragments stored within
|
||||
// the passed HashCache to eliminate duplicate hashing computations when
|
||||
// calculating the final digest, reducing the complexity from O(N^2) to O(N).
|
||||
// Additionally, signatures now cover the input value of the referenced unspent
|
||||
// output. This allows offline, or hardware wallets to compute the exact amount
|
||||
// being spent, in addition to the final transaction fee. In the case the
|
||||
// wallet if fed an invalid input amount, the real sighash will differ causing
|
||||
// the produced signature to be invalid.
|
||||
func calcWitnessSignatureHash(subScript []parsedOpcode, sigHashes *TxSigHashes,
|
||||
hashType SigHashType, tx *wire.MsgTx, idx int, amt int64) ([]byte, error) {
|
||||
|
||||
// As a sanity check, ensure the passed input index for the transaction
|
||||
// is valid.
|
||||
if idx > len(tx.TxIn)-1 {
|
||||
return nil, fmt.Errorf("idx %d but %d txins", idx, len(tx.TxIn))
|
||||
}
|
||||
|
||||
// We'll utilize this buffer throughout to incrementally calculate
|
||||
// the signature hash for this transaction.
|
||||
var sigHash bytes.Buffer
|
||||
|
||||
// First write out, then encode the transaction's version number.
|
||||
var bVersion [4]byte
|
||||
binary.LittleEndian.PutUint32(bVersion[:], uint32(tx.Version))
|
||||
sigHash.Write(bVersion[:])
|
||||
|
||||
// Next write out the possibly pre-calculated hashes for the sequence
|
||||
// numbers of all inputs, and the hashes of the previous outs for all
|
||||
// outputs.
|
||||
var zeroHash chainhash.Hash
|
||||
|
||||
// If anyone can pay isn't active, then we can use the cached
|
||||
// hashPrevOuts, otherwise we just write zeroes for the prev outs.
|
||||
if hashType&SigHashAnyOneCanPay == 0 {
|
||||
sigHash.Write(sigHashes.HashPrevOuts[:])
|
||||
} else {
|
||||
sigHash.Write(zeroHash[:])
|
||||
}
|
||||
|
||||
// If the sighash isn't anyone can pay, single, or none, the use the
|
||||
// cached hash sequences, otherwise write all zeroes for the
|
||||
// hashSequence.
|
||||
if hashType&SigHashAnyOneCanPay == 0 &&
|
||||
hashType&sigHashMask != SigHashSingle &&
|
||||
hashType&sigHashMask != SigHashNone {
|
||||
sigHash.Write(sigHashes.HashSequence[:])
|
||||
} else {
|
||||
sigHash.Write(zeroHash[:])
|
||||
}
|
||||
|
||||
txIn := tx.TxIn[idx]
|
||||
|
||||
// Next, write the outpoint being spent.
|
||||
sigHash.Write(txIn.PreviousOutPoint.Hash[:])
|
||||
var bIndex [4]byte
|
||||
binary.LittleEndian.PutUint32(bIndex[:], txIn.PreviousOutPoint.Index)
|
||||
sigHash.Write(bIndex[:])
|
||||
|
||||
if isWitnessPubKeyHash(subScript) {
|
||||
// The script code for a p2wkh is a length prefix varint for
|
||||
// the next 25 bytes, followed by a re-creation of the original
|
||||
// p2pkh pk script.
|
||||
sigHash.Write([]byte{0x19})
|
||||
sigHash.Write([]byte{OP_DUP})
|
||||
sigHash.Write([]byte{OP_HASH160})
|
||||
sigHash.Write([]byte{OP_DATA_20})
|
||||
sigHash.Write(subScript[1].data)
|
||||
sigHash.Write([]byte{OP_EQUALVERIFY})
|
||||
sigHash.Write([]byte{OP_CHECKSIG})
|
||||
} else {
|
||||
// For p2wsh outputs, and future outputs, the script code is
|
||||
// the original script, with all code separators removed,
|
||||
// serialized with a var int length prefix.
|
||||
rawScript, _ := unparseScript(subScript)
|
||||
wire.WriteVarBytes(&sigHash, 0, rawScript)
|
||||
}
|
||||
|
||||
// Next, add the input amount, and sequence number of the input being
|
||||
// signed.
|
||||
var bAmount [8]byte
|
||||
binary.LittleEndian.PutUint64(bAmount[:], uint64(amt))
|
||||
sigHash.Write(bAmount[:])
|
||||
var bSequence [4]byte
|
||||
binary.LittleEndian.PutUint32(bSequence[:], txIn.Sequence)
|
||||
sigHash.Write(bSequence[:])
|
||||
|
||||
// If the current signature mode isn't single, or none, then we can
|
||||
// re-use the pre-generated hashoutputs sighash fragment. Otherwise,
|
||||
// we'll serialize and add only the target output index to the signature
|
||||
// pre-image.
|
||||
if hashType&SigHashSingle != SigHashSingle &&
|
||||
hashType&SigHashNone != SigHashNone {
|
||||
sigHash.Write(sigHashes.HashOutputs[:])
|
||||
} else if hashType&sigHashMask == SigHashSingle && idx < len(tx.TxOut) {
|
||||
var b bytes.Buffer
|
||||
wire.WriteTxOut(&b, 0, 0, tx.TxOut[idx])
|
||||
sigHash.Write(chainhash.DoubleHashB(b.Bytes()))
|
||||
} else {
|
||||
sigHash.Write(zeroHash[:])
|
||||
}
|
||||
|
||||
// Finally, write out the transaction's locktime, and the sig hash
|
||||
// type.
|
||||
var bLockTime [4]byte
|
||||
binary.LittleEndian.PutUint32(bLockTime[:], tx.LockTime)
|
||||
sigHash.Write(bLockTime[:])
|
||||
var bHashType [4]byte
|
||||
binary.LittleEndian.PutUint32(bHashType[:], uint32(hashType))
|
||||
sigHash.Write(bHashType[:])
|
||||
|
||||
return chainhash.DoubleHashB(sigHash.Bytes()), nil
|
||||
}
|
||||
|
||||
// CalcWitnessSigHash computes the sighash digest for the specified input of
|
||||
// the target transaction observing the desired sig hash type.
|
||||
func CalcWitnessSigHash(script []byte, sigHashes *TxSigHashes, hType SigHashType,
|
||||
tx *wire.MsgTx, idx int, amt int64) ([]byte, error) {
|
||||
|
||||
parsedScript, err := parseScript(script)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("cannot parse output script: %v", err)
|
||||
}
|
||||
|
||||
return calcWitnessSignatureHash(parsedScript, sigHashes, hType, tx, idx,
|
||||
amt)
|
||||
}
|
||||
|
||||
// shallowCopyTx creates a shallow copy of the transaction for use when
|
||||
// calculating the signature hash. It is used over the Copy method on the
|
||||
// transaction itself since that is a deep copy and therefore does more work and
|
||||
@ -682,8 +406,8 @@ func calcSignatureHash(script []parsedOpcode, hashType SigHashType, tx *wire.Msg
|
||||
// The final hash is the double sha256 of both the serialized modified
|
||||
// transaction and the hash type (encoded as a 4-byte little-endian
|
||||
// value) appended.
|
||||
wbuf := bytes.NewBuffer(make([]byte, 0, txCopy.SerializeSizeStripped()+4))
|
||||
txCopy.SerializeNoWitness(wbuf)
|
||||
wbuf := bytes.NewBuffer(make([]byte, 0, txCopy.SerializeSize()+4))
|
||||
txCopy.Serialize(wbuf)
|
||||
binary.Write(wbuf, binary.LittleEndian, hashType)
|
||||
return chainhash.DoubleHashB(wbuf.Bytes())
|
||||
}
|
||||
@ -788,65 +512,6 @@ func GetPreciseSigOpCount(scriptSig, scriptPubKey []byte, bip16 bool) int {
|
||||
return getSigOpCount(shPops, true)
|
||||
}
|
||||
|
||||
// GetWitnessSigOpCount returns the number of signature operations generated by
|
||||
// spending the passed pkScript with the specified witness, or sigScript.
|
||||
// Unlike GetPreciseSigOpCount, this function is able to accurately count the
|
||||
// number of signature operations generated by spending witness programs, and
|
||||
// nested p2sh witness programs. If the script fails to parse, then the count
|
||||
// up to the point of failure is returned.
|
||||
func GetWitnessSigOpCount(sigScript, pkScript []byte, witness wire.TxWitness) int {
|
||||
// If this is a regular witness program, then we can proceed directly
|
||||
// to counting its signature operations without any further processing.
|
||||
if IsWitnessProgram(pkScript) {
|
||||
return getWitnessSigOps(pkScript, witness)
|
||||
}
|
||||
|
||||
// Next, we'll check the sigScript to see if this is a nested p2sh
|
||||
// witness program. This is a case wherein the sigScript is actually a
|
||||
// datapush of a p2wsh witness program.
|
||||
sigPops, err := parseScript(sigScript)
|
||||
if err != nil {
|
||||
return 0
|
||||
}
|
||||
if IsPayToScriptHash(pkScript) && isPushOnly(sigPops) &&
|
||||
IsWitnessProgram(sigScript[1:]) {
|
||||
return getWitnessSigOps(sigScript[1:], witness)
|
||||
}
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
// getWitnessSigOps returns the number of signature operations generated by
|
||||
// spending the passed witness program wit the passed witness. The exact
|
||||
// signature counting heuristic is modified by the version of the passed
|
||||
// witness program. If the version of the witness program is unable to be
|
||||
// extracted, then 0 is returned for the sig op count.
|
||||
func getWitnessSigOps(pkScript []byte, witness wire.TxWitness) int {
|
||||
// Attempt to extract the witness program version.
|
||||
witnessVersion, witnessProgram, err := ExtractWitnessProgramInfo(
|
||||
pkScript,
|
||||
)
|
||||
if err != nil {
|
||||
return 0
|
||||
}
|
||||
|
||||
switch witnessVersion {
|
||||
case 0:
|
||||
switch {
|
||||
case len(witnessProgram) == payToWitnessPubKeyHashDataSize:
|
||||
return 1
|
||||
case len(witnessProgram) == payToWitnessScriptHashDataSize &&
|
||||
len(witness) > 0:
|
||||
|
||||
witnessScript := witness[len(witness)-1]
|
||||
pops, _ := parseScript(witnessScript)
|
||||
return getSigOpCount(pops, true)
|
||||
}
|
||||
}
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
// IsUnspendable returns whether the passed public key script is unspendable, or
|
||||
// guaranteed to fail at execution. This allows inputs to be pruned instantly
|
||||
// when entering the UTXO set.
|
||||
|
@ -8,8 +8,6 @@ import (
|
||||
"bytes"
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
"github.com/daglabs/btcd/wire"
|
||||
)
|
||||
|
||||
// TestParseOpcode tests for opcode parsing with bad data templates.
|
||||
@ -3846,94 +3844,6 @@ func TestGetPreciseSigOps(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// TestGetWitnessSigOpCount tests that the sig op counting for p2wkh, p2wsh,
|
||||
// nested p2sh, and invalid variants are counted properly.
|
||||
func TestGetWitnessSigOpCount(t *testing.T) {
|
||||
t.Parallel()
|
||||
tests := []struct {
|
||||
name string
|
||||
|
||||
sigScript []byte
|
||||
pkScript []byte
|
||||
witness wire.TxWitness
|
||||
|
||||
numSigOps int
|
||||
}{
|
||||
// A regualr p2wkh witness program. The output being spent
|
||||
// should only have a single sig-op counted.
|
||||
{
|
||||
name: "p2wkh",
|
||||
pkScript: mustParseShortForm("OP_0 DATA_20 " +
|
||||
"0x365ab47888e150ff46f8d51bce36dcd680f1283f"),
|
||||
witness: wire.TxWitness{
|
||||
hexToBytes("3045022100ee9fe8f9487afa977" +
|
||||
"6647ebcf0883ce0cd37454d7ce19889d34ba2c9" +
|
||||
"9ce5a9f402200341cb469d0efd3955acb9e46" +
|
||||
"f568d7e2cc10f9084aaff94ced6dc50a59134ad01"),
|
||||
hexToBytes("03f0000d0639a22bfaf217e4c9428" +
|
||||
"9c2b0cc7fa1036f7fd5d9f61a9d6ec153100e"),
|
||||
},
|
||||
numSigOps: 1,
|
||||
},
|
||||
// A p2wkh witness program nested within a p2sh output script.
|
||||
// The pattern should be recognized properly and attribute only
|
||||
// a single sig op.
|
||||
{
|
||||
name: "nested p2sh",
|
||||
sigScript: hexToBytes("160014ad0ffa2e387f07" +
|
||||
"e7ead14dc56d5a97dbd6ff5a23"),
|
||||
pkScript: mustParseShortForm("HASH160 DATA_20 " +
|
||||
"0xb3a84b564602a9d68b4c9f19c2ea61458ff7826c EQUAL"),
|
||||
witness: wire.TxWitness{
|
||||
hexToBytes("3045022100cb1c2ac1ff1d57d" +
|
||||
"db98f7bdead905f8bf5bcc8641b029ce8eef25" +
|
||||
"c75a9e22a4702203be621b5c86b771288706be5" +
|
||||
"a7eee1db4fceabf9afb7583c1cc6ee3f8297b21201"),
|
||||
hexToBytes("03f0000d0639a22bfaf217e4c9" +
|
||||
"4289c2b0cc7fa1036f7fd5d9f61a9d6ec153100e"),
|
||||
},
|
||||
numSigOps: 1,
|
||||
},
|
||||
// A p2sh script that spends a 2-of-2 multi-sig output.
|
||||
{
|
||||
name: "p2wsh multi-sig spend",
|
||||
numSigOps: 2,
|
||||
pkScript: hexToBytes("0020e112b88a0cd87ba387f" +
|
||||
"449d443ee2596eb353beb1f0351ab2cba8909d875db23"),
|
||||
witness: wire.TxWitness{
|
||||
hexToBytes("522103b05faca7ceda92b493" +
|
||||
"3f7acdf874a93de0dc7edc461832031cd69cbb1d1e" +
|
||||
"6fae2102e39092e031c1621c902e3704424e8d8" +
|
||||
"3ca481d4d4eeae1b7970f51c78231207e52ae"),
|
||||
},
|
||||
},
|
||||
// A p2wsh witness program. However, the witness script fails
|
||||
// to parse after the valid portion of the script. As a result,
|
||||
// the valid portion of the script should still be counted.
|
||||
{
|
||||
name: "witness script doesn't parse",
|
||||
numSigOps: 1,
|
||||
pkScript: hexToBytes("0020e112b88a0cd87ba387f44" +
|
||||
"9d443ee2596eb353beb1f0351ab2cba8909d875db23"),
|
||||
witness: wire.TxWitness{
|
||||
mustParseShortForm("DUP HASH160 " +
|
||||
"'17VZNX1SN5NtKa8UQFxwQbFeFc3iqRYhem'" +
|
||||
" EQUALVERIFY CHECKSIG DATA_20 0x91"),
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
count := GetWitnessSigOpCount(test.sigScript, test.pkScript,
|
||||
test.witness)
|
||||
if count != test.numSigOps {
|
||||
t.Errorf("%s: expected count of %d, got %d", test.name,
|
||||
test.numSigOps, count)
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TestRemoveOpcodes ensures that removing opcodes from scripts behaves as
|
||||
// expected.
|
||||
func TestRemoveOpcodes(t *testing.T) {
|
||||
@ -4181,38 +4091,6 @@ func TestIsPayToScriptHash(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// TestIsPayToWitnessScriptHash ensures the IsPayToWitnessScriptHash function
|
||||
// returns the expected results for all the scripts in scriptClassTests.
|
||||
func TestIsPayToWitnessScriptHash(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
for _, test := range scriptClassTests {
|
||||
script := mustParseShortForm(test.script)
|
||||
shouldBe := (test.class == WitnessV0ScriptHashTy)
|
||||
p2wsh := IsPayToWitnessScriptHash(script)
|
||||
if p2wsh != shouldBe {
|
||||
t.Errorf("%s: expected p2wsh %v, got %v", test.name,
|
||||
shouldBe, p2wsh)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TestIsPayToWitnessPubKeyHash ensures the IsPayToWitnessPubKeyHash function
|
||||
// returns the expected results for all the scripts in scriptClassTests.
|
||||
func TestIsPayToWitnessPubKeyHash(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
for _, test := range scriptClassTests {
|
||||
script := mustParseShortForm(test.script)
|
||||
shouldBe := (test.class == WitnessV0PubKeyHashTy)
|
||||
p2wkh := IsPayToWitnessPubKeyHash(script)
|
||||
if p2wkh != shouldBe {
|
||||
t.Errorf("%s: expected p2wkh %v, got %v", test.name,
|
||||
shouldBe, p2wkh)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TestHasCanonicalPushes ensures the canonicalPush function properly determines
|
||||
// what is considered a canonical push for the purposes of removeOpcodeByData.
|
||||
func TestHasCanonicalPushes(t *testing.T) {
|
||||
|
@ -14,61 +14,6 @@ import (
|
||||
"github.com/daglabs/btcutil"
|
||||
)
|
||||
|
||||
// RawTxInWitnessSignature returns the serialized ECDA signature for the input
|
||||
// idx of the given transaction, with the hashType appended to it. This
|
||||
// function is identical to RawTxInSignature, however the signature generated
|
||||
// signs a new sighash digest defined in BIP0143.
|
||||
func RawTxInWitnessSignature(tx *wire.MsgTx, sigHashes *TxSigHashes, idx int,
|
||||
amt int64, subScript []byte, hashType SigHashType,
|
||||
key *btcec.PrivateKey) ([]byte, error) {
|
||||
|
||||
parsedScript, err := parseScript(subScript)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("cannot parse output script: %v", err)
|
||||
}
|
||||
|
||||
hash, err := calcWitnessSignatureHash(parsedScript, sigHashes, hashType, tx,
|
||||
idx, amt)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
signature, err := key.Sign(hash)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("cannot sign tx input: %s", err)
|
||||
}
|
||||
|
||||
return append(signature.Serialize(), byte(hashType)), nil
|
||||
}
|
||||
|
||||
// WitnessSignature creates an input witness stack for tx to spend BTC sent
|
||||
// from a previous output to the owner of privKey using the p2wkh script
|
||||
// template. The passed transaction must contain all the inputs and outputs as
|
||||
// dictated by the passed hashType. The signature generated observes the new
|
||||
// transaction digest algorithm defined within BIP0143.
|
||||
func WitnessSignature(tx *wire.MsgTx, sigHashes *TxSigHashes, idx int, amt int64,
|
||||
subscript []byte, hashType SigHashType, privKey *btcec.PrivateKey,
|
||||
compress bool) (wire.TxWitness, error) {
|
||||
|
||||
sig, err := RawTxInWitnessSignature(tx, sigHashes, idx, amt, subscript,
|
||||
hashType, privKey)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
pk := (*btcec.PublicKey)(&privKey.PublicKey)
|
||||
var pkData []byte
|
||||
if compress {
|
||||
pkData = pk.SerializeCompressed()
|
||||
} else {
|
||||
pkData = pk.SerializeUncompressed()
|
||||
}
|
||||
|
||||
// A witness script is actually a stack, so we return an array of byte
|
||||
// slices here, rather than a single byte slice.
|
||||
return wire.TxWitness{sig, pkData}, nil
|
||||
}
|
||||
|
||||
// RawTxInSignature returns the serialized ECDSA signature for the input idx of
|
||||
// the given transaction, with hashType appended to it.
|
||||
func RawTxInSignature(tx *wire.MsgTx, idx int, subScript []byte,
|
||||
|
@ -53,10 +53,10 @@ func mkGetScript(scripts map[string][]byte) ScriptDB {
|
||||
})
|
||||
}
|
||||
|
||||
func checkScripts(msg string, tx *wire.MsgTx, idx int, inputAmt int64, sigScript, pkScript []byte) error {
|
||||
func checkScripts(msg string, tx *wire.MsgTx, idx int, sigScript, pkScript []byte) error {
|
||||
tx.TxIn[idx].SignatureScript = sigScript
|
||||
vm, err := NewEngine(pkScript, tx, idx,
|
||||
ScriptBip16|ScriptVerifyDERSignatures, nil, nil, inputAmt)
|
||||
ScriptBip16|ScriptVerifyDERSignatures, nil)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to make script engine for %s: %v",
|
||||
msg, err)
|
||||
@ -71,7 +71,7 @@ func checkScripts(msg string, tx *wire.MsgTx, idx int, inputAmt int64, sigScript
|
||||
return nil
|
||||
}
|
||||
|
||||
func signAndCheck(msg string, tx *wire.MsgTx, idx int, inputAmt int64, pkScript []byte,
|
||||
func signAndCheck(msg string, tx *wire.MsgTx, idx int, pkScript []byte,
|
||||
hashType SigHashType, kdb KeyDB, sdb ScriptDB,
|
||||
previousScript []byte) error {
|
||||
|
||||
@ -81,7 +81,7 @@ func signAndCheck(msg string, tx *wire.MsgTx, idx int, inputAmt int64, pkScript
|
||||
return fmt.Errorf("failed to sign output %s: %v", msg, err)
|
||||
}
|
||||
|
||||
return checkScripts(msg, tx, idx, inputAmt, sigScript, pkScript)
|
||||
return checkScripts(msg, tx, idx, sigScript, pkScript)
|
||||
}
|
||||
|
||||
func TestSignTxOutput(t *testing.T) {
|
||||
@ -99,7 +99,6 @@ func TestSignTxOutput(t *testing.T) {
|
||||
SigHashNone | SigHashAnyOneCanPay,
|
||||
SigHashSingle | SigHashAnyOneCanPay,
|
||||
}
|
||||
inputAmounts := []int64{5, 10, 15}
|
||||
tx := &wire.MsgTx{
|
||||
Version: 1,
|
||||
TxIn: []*wire.TxIn{
|
||||
@ -166,7 +165,7 @@ func TestSignTxOutput(t *testing.T) {
|
||||
"for %s: %v", msg, err)
|
||||
}
|
||||
|
||||
if err := signAndCheck(msg, tx, i, inputAmounts[i], pkScript, hashType,
|
||||
if err := signAndCheck(msg, tx, i, pkScript, hashType,
|
||||
mkGetKey(map[string]addressToKey{
|
||||
address.EncodeAddress(): {key, false},
|
||||
}), mkGetScript(nil), nil); err != nil {
|
||||
@ -227,7 +226,7 @@ func TestSignTxOutput(t *testing.T) {
|
||||
break
|
||||
}
|
||||
|
||||
err = checkScripts(msg, tx, i, inputAmounts[i], sigScript, pkScript)
|
||||
err = checkScripts(msg, tx, i, sigScript, pkScript)
|
||||
if err != nil {
|
||||
t.Errorf("twice signed script invalid for "+
|
||||
"%s: %v", msg, err)
|
||||
@ -264,8 +263,7 @@ func TestSignTxOutput(t *testing.T) {
|
||||
"for %s: %v", msg, err)
|
||||
}
|
||||
|
||||
if err := signAndCheck(msg, tx, i, inputAmounts[i],
|
||||
pkScript, hashType,
|
||||
if err := signAndCheck(msg, tx, i, pkScript, hashType,
|
||||
mkGetKey(map[string]addressToKey{
|
||||
address.EncodeAddress(): {key, true},
|
||||
}), mkGetScript(nil), nil); err != nil {
|
||||
@ -327,8 +325,7 @@ func TestSignTxOutput(t *testing.T) {
|
||||
break
|
||||
}
|
||||
|
||||
err = checkScripts(msg, tx, i, inputAmounts[i],
|
||||
sigScript, pkScript)
|
||||
err = checkScripts(msg, tx, i, sigScript, pkScript)
|
||||
if err != nil {
|
||||
t.Errorf("twice signed script invalid for "+
|
||||
"%s: %v", msg, err)
|
||||
@ -365,8 +362,7 @@ func TestSignTxOutput(t *testing.T) {
|
||||
"for %s: %v", msg, err)
|
||||
}
|
||||
|
||||
if err := signAndCheck(msg, tx, i, inputAmounts[i],
|
||||
pkScript, hashType,
|
||||
if err := signAndCheck(msg, tx, i, pkScript, hashType,
|
||||
mkGetKey(map[string]addressToKey{
|
||||
address.EncodeAddress(): {key, false},
|
||||
}), mkGetScript(nil), nil); err != nil {
|
||||
@ -428,7 +424,7 @@ func TestSignTxOutput(t *testing.T) {
|
||||
break
|
||||
}
|
||||
|
||||
err = checkScripts(msg, tx, i, inputAmounts[i], sigScript, pkScript)
|
||||
err = checkScripts(msg, tx, i, sigScript, pkScript)
|
||||
if err != nil {
|
||||
t.Errorf("twice signed script invalid for "+
|
||||
"%s: %v", msg, err)
|
||||
@ -465,8 +461,7 @@ func TestSignTxOutput(t *testing.T) {
|
||||
"for %s: %v", msg, err)
|
||||
}
|
||||
|
||||
if err := signAndCheck(msg, tx, i, inputAmounts[i],
|
||||
pkScript, hashType,
|
||||
if err := signAndCheck(msg, tx, i, pkScript, hashType,
|
||||
mkGetKey(map[string]addressToKey{
|
||||
address.EncodeAddress(): {key, true},
|
||||
}), mkGetScript(nil), nil); err != nil {
|
||||
@ -528,8 +523,7 @@ func TestSignTxOutput(t *testing.T) {
|
||||
break
|
||||
}
|
||||
|
||||
err = checkScripts(msg, tx, i, inputAmounts[i],
|
||||
sigScript, pkScript)
|
||||
err = checkScripts(msg, tx, i, sigScript, pkScript)
|
||||
if err != nil {
|
||||
t.Errorf("twice signed script invalid for "+
|
||||
"%s: %v", msg, err)
|
||||
@ -583,8 +577,7 @@ func TestSignTxOutput(t *testing.T) {
|
||||
break
|
||||
}
|
||||
|
||||
if err := signAndCheck(msg, tx, i, inputAmounts[i],
|
||||
scriptPkScript, hashType,
|
||||
if err := signAndCheck(msg, tx, i, scriptPkScript, hashType,
|
||||
mkGetKey(map[string]addressToKey{
|
||||
address.EncodeAddress(): {key, false},
|
||||
}), mkGetScript(map[string][]byte{
|
||||
@ -668,8 +661,7 @@ func TestSignTxOutput(t *testing.T) {
|
||||
break
|
||||
}
|
||||
|
||||
err = checkScripts(msg, tx, i, inputAmounts[i],
|
||||
sigScript, scriptPkScript)
|
||||
err = checkScripts(msg, tx, i, sigScript, scriptPkScript)
|
||||
if err != nil {
|
||||
t.Errorf("twice signed script invalid for "+
|
||||
"%s: %v", msg, err)
|
||||
@ -722,8 +714,7 @@ func TestSignTxOutput(t *testing.T) {
|
||||
break
|
||||
}
|
||||
|
||||
if err := signAndCheck(msg, tx, i, inputAmounts[i],
|
||||
scriptPkScript, hashType,
|
||||
if err := signAndCheck(msg, tx, i, scriptPkScript, hashType,
|
||||
mkGetKey(map[string]addressToKey{
|
||||
address.EncodeAddress(): {key, true},
|
||||
}), mkGetScript(map[string][]byte{
|
||||
@ -807,8 +798,7 @@ func TestSignTxOutput(t *testing.T) {
|
||||
break
|
||||
}
|
||||
|
||||
err = checkScripts(msg, tx, i, inputAmounts[i],
|
||||
sigScript, scriptPkScript)
|
||||
err = checkScripts(msg, tx, i, sigScript, scriptPkScript)
|
||||
if err != nil {
|
||||
t.Errorf("twice signed script invalid for "+
|
||||
"%s: %v", msg, err)
|
||||
@ -861,8 +851,7 @@ func TestSignTxOutput(t *testing.T) {
|
||||
break
|
||||
}
|
||||
|
||||
if err := signAndCheck(msg, tx, i, inputAmounts[i],
|
||||
scriptPkScript, hashType,
|
||||
if err := signAndCheck(msg, tx, i, scriptPkScript, hashType,
|
||||
mkGetKey(map[string]addressToKey{
|
||||
address.EncodeAddress(): {key, false},
|
||||
}), mkGetScript(map[string][]byte{
|
||||
@ -945,8 +934,7 @@ func TestSignTxOutput(t *testing.T) {
|
||||
break
|
||||
}
|
||||
|
||||
err = checkScripts(msg, tx, i, inputAmounts[i],
|
||||
sigScript, scriptPkScript)
|
||||
err = checkScripts(msg, tx, i, sigScript, scriptPkScript)
|
||||
if err != nil {
|
||||
t.Errorf("twice signed script invalid for "+
|
||||
"%s: %v", msg, err)
|
||||
@ -998,8 +986,7 @@ func TestSignTxOutput(t *testing.T) {
|
||||
break
|
||||
}
|
||||
|
||||
if err := signAndCheck(msg, tx, i, inputAmounts[i],
|
||||
scriptPkScript, hashType,
|
||||
if err := signAndCheck(msg, tx, i, scriptPkScript, hashType,
|
||||
mkGetKey(map[string]addressToKey{
|
||||
address.EncodeAddress(): {key, true},
|
||||
}), mkGetScript(map[string][]byte{
|
||||
@ -1082,8 +1069,7 @@ func TestSignTxOutput(t *testing.T) {
|
||||
break
|
||||
}
|
||||
|
||||
err = checkScripts(msg, tx, i, inputAmounts[i],
|
||||
sigScript, scriptPkScript)
|
||||
err = checkScripts(msg, tx, i, sigScript, scriptPkScript)
|
||||
if err != nil {
|
||||
t.Errorf("twice signed script invalid for "+
|
||||
"%s: %v", msg, err)
|
||||
@ -1154,8 +1140,7 @@ func TestSignTxOutput(t *testing.T) {
|
||||
break
|
||||
}
|
||||
|
||||
if err := signAndCheck(msg, tx, i, inputAmounts[i],
|
||||
scriptPkScript, hashType,
|
||||
if err := signAndCheck(msg, tx, i, scriptPkScript, hashType,
|
||||
mkGetKey(map[string]addressToKey{
|
||||
address1.EncodeAddress(): {key1, true},
|
||||
address2.EncodeAddress(): {key2, true},
|
||||
@ -1244,8 +1229,7 @@ func TestSignTxOutput(t *testing.T) {
|
||||
}
|
||||
|
||||
// Only 1 out of 2 signed, this *should* fail.
|
||||
if checkScripts(msg, tx, i, inputAmounts[i], sigScript,
|
||||
scriptPkScript) == nil {
|
||||
if checkScripts(msg, tx, i, sigScript, scriptPkScript) == nil {
|
||||
t.Errorf("part signed script valid for %s", msg)
|
||||
break
|
||||
}
|
||||
@ -1263,8 +1247,7 @@ func TestSignTxOutput(t *testing.T) {
|
||||
break
|
||||
}
|
||||
|
||||
err = checkScripts(msg, tx, i, inputAmounts[i], sigScript,
|
||||
scriptPkScript)
|
||||
err = checkScripts(msg, tx, i, sigScript, scriptPkScript)
|
||||
if err != nil {
|
||||
t.Errorf("fully signed script invalid for "+
|
||||
"%s: %v", msg, err)
|
||||
@ -1350,8 +1333,7 @@ func TestSignTxOutput(t *testing.T) {
|
||||
}
|
||||
|
||||
// Only 1 out of 2 signed, this *should* fail.
|
||||
if checkScripts(msg, tx, i, inputAmounts[i], sigScript,
|
||||
scriptPkScript) == nil {
|
||||
if checkScripts(msg, tx, i, sigScript, scriptPkScript) == nil {
|
||||
t.Errorf("part signed script valid for %s", msg)
|
||||
break
|
||||
}
|
||||
@ -1371,8 +1353,7 @@ func TestSignTxOutput(t *testing.T) {
|
||||
}
|
||||
|
||||
// Now we should pass.
|
||||
err = checkScripts(msg, tx, i, inputAmounts[i],
|
||||
sigScript, scriptPkScript)
|
||||
err = checkScripts(msg, tx, i, sigScript, scriptPkScript)
|
||||
if err != nil {
|
||||
t.Errorf("fully signed script invalid for "+
|
||||
"%s: %v", msg, err)
|
||||
@ -1694,7 +1675,7 @@ nexttest:
|
||||
scriptFlags := ScriptBip16 | ScriptVerifyDERSignatures
|
||||
for j := range tx.TxIn {
|
||||
vm, err := NewEngine(sigScriptTests[i].
|
||||
inputs[j].txout.PkScript, tx, j, scriptFlags, nil, nil, 0)
|
||||
inputs[j].txout.PkScript, tx, j, scriptFlags, nil)
|
||||
if err != nil {
|
||||
t.Errorf("cannot create script vm for test %v: %v",
|
||||
sigScriptTests[i].name, err)
|
||||
|
@ -8,7 +8,6 @@ import (
|
||||
"fmt"
|
||||
|
||||
"github.com/daglabs/btcd/chaincfg"
|
||||
"github.com/daglabs/btcd/wire"
|
||||
"github.com/daglabs/btcutil"
|
||||
)
|
||||
|
||||
@ -38,11 +37,7 @@ const (
|
||||
ScriptVerifyCheckLockTimeVerify |
|
||||
ScriptVerifyCheckSequenceVerify |
|
||||
ScriptVerifyLowS |
|
||||
ScriptStrictMultiSig |
|
||||
ScriptVerifyWitness |
|
||||
ScriptVerifyDiscourageUpgradeableWitnessProgram |
|
||||
ScriptVerifyMinimalIf |
|
||||
ScriptVerifyWitnessPubKeyType
|
||||
ScriptStrictMultiSig
|
||||
)
|
||||
|
||||
// ScriptClass is an enumeration for the list of standard types of script.
|
||||
@ -50,27 +45,23 @@ type ScriptClass byte
|
||||
|
||||
// Classes of script payment known about in the blockchain.
|
||||
const (
|
||||
NonStandardTy ScriptClass = iota // None of the recognized forms.
|
||||
PubKeyTy // Pay pubkey.
|
||||
PubKeyHashTy // Pay pubkey hash.
|
||||
WitnessV0PubKeyHashTy // Pay witness pubkey hash.
|
||||
ScriptHashTy // Pay to script hash.
|
||||
WitnessV0ScriptHashTy // Pay to witness script hash.
|
||||
MultiSigTy // Multi signature.
|
||||
NullDataTy // Empty data-only (provably prunable).
|
||||
NonStandardTy ScriptClass = iota // None of the recognized forms.
|
||||
PubKeyTy // Pay pubkey.
|
||||
PubKeyHashTy // Pay pubkey hash.
|
||||
ScriptHashTy // Pay to script hash.
|
||||
MultiSigTy // Multi signature.
|
||||
NullDataTy // Empty data-only (provably prunable).
|
||||
)
|
||||
|
||||
// scriptClassToName houses the human-readable strings which describe each
|
||||
// script class.
|
||||
var scriptClassToName = []string{
|
||||
NonStandardTy: "nonstandard",
|
||||
PubKeyTy: "pubkey",
|
||||
PubKeyHashTy: "pubkeyhash",
|
||||
WitnessV0PubKeyHashTy: "witness_v0_keyhash",
|
||||
ScriptHashTy: "scripthash",
|
||||
WitnessV0ScriptHashTy: "witness_v0_scripthash",
|
||||
MultiSigTy: "multisig",
|
||||
NullDataTy: "nulldata",
|
||||
NonStandardTy: "nonstandard",
|
||||
PubKeyTy: "pubkey",
|
||||
PubKeyHashTy: "pubkeyhash",
|
||||
ScriptHashTy: "scripthash",
|
||||
MultiSigTy: "multisig",
|
||||
NullDataTy: "nulldata",
|
||||
}
|
||||
|
||||
// String implements the Stringer interface by returning the name of
|
||||
@ -163,12 +154,8 @@ func typeOfScript(pops []parsedOpcode) ScriptClass {
|
||||
return PubKeyTy
|
||||
} else if isPubkeyHash(pops) {
|
||||
return PubKeyHashTy
|
||||
} else if isWitnessPubKeyHash(pops) {
|
||||
return WitnessV0PubKeyHashTy
|
||||
} else if isScriptHash(pops) {
|
||||
return ScriptHashTy
|
||||
} else if isWitnessScriptHash(pops) {
|
||||
return WitnessV0ScriptHashTy
|
||||
} else if isMultiSig(pops) {
|
||||
return MultiSigTy
|
||||
} else if isNullData(pops) {
|
||||
@ -201,17 +188,10 @@ func expectedInputs(pops []parsedOpcode, class ScriptClass) int {
|
||||
case PubKeyHashTy:
|
||||
return 2
|
||||
|
||||
case WitnessV0PubKeyHashTy:
|
||||
return 2
|
||||
|
||||
case ScriptHashTy:
|
||||
// Not including script. That is handled by the caller.
|
||||
return 1
|
||||
|
||||
case WitnessV0ScriptHashTy:
|
||||
// Not including script. That is handled by the caller.
|
||||
return 1
|
||||
|
||||
case MultiSigTy:
|
||||
// Standard multisig has a push a small number for the number
|
||||
// of sigs and number of keys. Check the first push instruction
|
||||
@ -252,9 +232,7 @@ type ScriptInfo struct {
|
||||
// pair. It will error if the pair is in someway invalid such that they can not
|
||||
// be analysed, i.e. if they do not parse or the pkScript is not a push-only
|
||||
// script
|
||||
func CalcScriptInfo(sigScript, pkScript []byte, witness wire.TxWitness,
|
||||
bip16, segwit bool) (*ScriptInfo, error) {
|
||||
|
||||
func CalcScriptInfo(sigScript, pkScript []byte, bip16 bool) (*ScriptInfo, error) {
|
||||
sigPops, err := parseScript(sigScript)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@ -277,9 +255,10 @@ func CalcScriptInfo(sigScript, pkScript []byte, witness wire.TxWitness,
|
||||
|
||||
si.ExpectedInputs = expectedInputs(pkPops, si.PkScriptClass)
|
||||
|
||||
switch {
|
||||
// Count sigops taking into account pay-to-script-hash.
|
||||
case si.PkScriptClass == ScriptHashTy && bip16 && !segwit:
|
||||
// All entries pushed to stack (or are OP_RESERVED and exec will fail).
|
||||
si.NumInputs = len(sigPops)
|
||||
|
||||
if si.PkScriptClass == ScriptHashTy && bip16 {
|
||||
// The pay-to-hash-script is the final data push of the
|
||||
// signature script.
|
||||
script := sigPops[len(sigPops)-1].data
|
||||
@ -295,62 +274,8 @@ func CalcScriptInfo(sigScript, pkScript []byte, witness wire.TxWitness,
|
||||
si.ExpectedInputs += shInputs
|
||||
}
|
||||
si.SigOps = getSigOpCount(shPops, true)
|
||||
|
||||
// All entries pushed to stack (or are OP_RESERVED and exec
|
||||
// will fail).
|
||||
si.NumInputs = len(sigPops)
|
||||
|
||||
// If segwit is active, and this is a regular p2wkh output, then we'll
|
||||
// treat the script as a p2pkh output in essence.
|
||||
case si.PkScriptClass == WitnessV0PubKeyHashTy && segwit:
|
||||
|
||||
si.SigOps = GetWitnessSigOpCount(sigScript, pkScript, witness)
|
||||
si.NumInputs = len(witness)
|
||||
|
||||
// We'll attempt to detect the nested p2sh case so we can accurately
|
||||
// count the signature operations involved.
|
||||
case si.PkScriptClass == ScriptHashTy &&
|
||||
IsWitnessProgram(sigScript[1:]) && bip16 && segwit:
|
||||
|
||||
// Extract the pushed witness program from the sigScript so we
|
||||
// can determine the number of expected inputs.
|
||||
pkPops, _ := parseScript(sigScript[1:])
|
||||
shInputs := expectedInputs(pkPops, typeOfScript(pkPops))
|
||||
if shInputs == -1 {
|
||||
si.ExpectedInputs = -1
|
||||
} else {
|
||||
si.ExpectedInputs += shInputs
|
||||
}
|
||||
|
||||
si.SigOps = GetWitnessSigOpCount(sigScript, pkScript, witness)
|
||||
|
||||
si.NumInputs = len(witness)
|
||||
si.NumInputs += len(sigPops)
|
||||
|
||||
// If segwit is active, and this is a p2wsh output, then we'll need to
|
||||
// examine the witness script to generate accurate script info.
|
||||
case si.PkScriptClass == WitnessV0ScriptHashTy && segwit:
|
||||
// The witness script is the final element of the witness
|
||||
// stack.
|
||||
witnessScript := witness[len(witness)-1]
|
||||
pops, _ := parseScript(witnessScript)
|
||||
|
||||
shInputs := expectedInputs(pops, typeOfScript(pops))
|
||||
if shInputs == -1 {
|
||||
si.ExpectedInputs = -1
|
||||
} else {
|
||||
si.ExpectedInputs += shInputs
|
||||
}
|
||||
|
||||
si.SigOps = GetWitnessSigOpCount(sigScript, pkScript, witness)
|
||||
si.NumInputs = len(witness)
|
||||
|
||||
default:
|
||||
} else {
|
||||
si.SigOps = getSigOpCount(pkPops, true)
|
||||
|
||||
// All entries pushed to stack (or are OP_RESERVED and exec
|
||||
// will fail).
|
||||
si.NumInputs = len(sigPops)
|
||||
}
|
||||
|
||||
return si, nil
|
||||
@ -391,12 +316,6 @@ func payToPubKeyHashScript(pubKeyHash []byte) ([]byte, error) {
|
||||
Script()
|
||||
}
|
||||
|
||||
// payToWitnessPubKeyHashScript creates a new script to pay to a version 0
|
||||
// pubkey hash witness program. The passed hash is expected to be valid.
|
||||
func payToWitnessPubKeyHashScript(pubKeyHash []byte) ([]byte, error) {
|
||||
return NewScriptBuilder().AddOp(OP_0).AddData(pubKeyHash).Script()
|
||||
}
|
||||
|
||||
// payToScriptHashScript creates a new script to pay a transaction output to a
|
||||
// script hash. It is expected that the input is a valid hash.
|
||||
func payToScriptHashScript(scriptHash []byte) ([]byte, error) {
|
||||
@ -404,12 +323,6 @@ func payToScriptHashScript(scriptHash []byte) ([]byte, error) {
|
||||
AddOp(OP_EQUAL).Script()
|
||||
}
|
||||
|
||||
// payToWitnessPubKeyHashScript creates a new script to pay to a version 0
|
||||
// script hash witness program. The passed hash is expected to be valid.
|
||||
func payToWitnessScriptHashScript(scriptHash []byte) ([]byte, error) {
|
||||
return NewScriptBuilder().AddOp(OP_0).AddData(scriptHash).Script()
|
||||
}
|
||||
|
||||
// payToPubkeyScript creates a new script to pay a transaction output to a
|
||||
// public key. It is expected that the input is a valid pubkey.
|
||||
func payToPubKeyScript(serializedPubKey []byte) ([]byte, error) {
|
||||
@ -443,19 +356,6 @@ func PayToAddrScript(addr btcutil.Address) ([]byte, error) {
|
||||
nilAddrErrStr)
|
||||
}
|
||||
return payToPubKeyScript(addr.ScriptAddress())
|
||||
|
||||
case *btcutil.AddressWitnessPubKeyHash:
|
||||
if addr == nil {
|
||||
return nil, scriptError(ErrUnsupportedAddress,
|
||||
nilAddrErrStr)
|
||||
}
|
||||
return payToWitnessPubKeyHashScript(addr.ScriptAddress())
|
||||
case *btcutil.AddressWitnessScriptHash:
|
||||
if addr == nil {
|
||||
return nil, scriptError(ErrUnsupportedAddress,
|
||||
nilAddrErrStr)
|
||||
}
|
||||
return payToWitnessScriptHashScript(addr.ScriptAddress())
|
||||
}
|
||||
|
||||
str := fmt.Sprintf("unable to generate payment script for unsupported "+
|
||||
@ -546,18 +446,6 @@ func ExtractPkScriptAddrs(pkScript []byte, chainParams *chaincfg.Params) (Script
|
||||
addrs = append(addrs, addr)
|
||||
}
|
||||
|
||||
case WitnessV0PubKeyHashTy:
|
||||
// A pay-to-witness-pubkey-hash script is of thw form:
|
||||
// OP_0 <20-byte hash>
|
||||
// Therefore, the pubkey hash is the second item on the stack.
|
||||
// Skip the pubkey hash if it's invalid for some reason.
|
||||
requiredSigs = 1
|
||||
addr, err := btcutil.NewAddressWitnessPubKeyHash(pops[1].data,
|
||||
chainParams)
|
||||
if err == nil {
|
||||
addrs = append(addrs, addr)
|
||||
}
|
||||
|
||||
case PubKeyTy:
|
||||
// A pay-to-pubkey script is of the form:
|
||||
// <pubkey> OP_CHECKSIG
|
||||
@ -581,18 +469,6 @@ func ExtractPkScriptAddrs(pkScript []byte, chainParams *chaincfg.Params) (Script
|
||||
addrs = append(addrs, addr)
|
||||
}
|
||||
|
||||
case WitnessV0ScriptHashTy:
|
||||
// A pay-to-witness-script-hash script is of the form:
|
||||
// OP_0 <32-byte hash>
|
||||
// Therefore, the script hash is the second item on the stack.
|
||||
// Skip the script hash if it's invalid for some reason.
|
||||
requiredSigs = 1
|
||||
addr, err := btcutil.NewAddressWitnessScriptHash(pops[1].data,
|
||||
chainParams)
|
||||
if err == nil {
|
||||
addrs = append(addrs, addr)
|
||||
}
|
||||
|
||||
case MultiSigTy:
|
||||
// A multi-signature script is of the form:
|
||||
// <numsigs> <pubkey> <pubkey> <pubkey>... <numpubkeys> OP_CHECKMULTISIG
|
||||
|
@ -6,12 +6,10 @@ package txscript
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/hex"
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
"github.com/daglabs/btcd/chaincfg"
|
||||
"github.com/daglabs/btcd/wire"
|
||||
"github.com/daglabs/btcutil"
|
||||
)
|
||||
|
||||
@ -381,10 +379,8 @@ func TestCalcScriptInfo(t *testing.T) {
|
||||
name string
|
||||
sigScript string
|
||||
pkScript string
|
||||
witness []string
|
||||
|
||||
bip16 bool
|
||||
segwit bool
|
||||
bip16 bool
|
||||
|
||||
scriptInfo ScriptInfo
|
||||
scriptInfoErr error
|
||||
@ -462,91 +458,13 @@ func TestCalcScriptInfo(t *testing.T) {
|
||||
SigOps: 3,
|
||||
},
|
||||
},
|
||||
{
|
||||
// A v0 p2wkh spend.
|
||||
name: "p2wkh script",
|
||||
pkScript: "OP_0 DATA_20 0x365ab47888e150ff46f8d51bce36dcd680f1283f",
|
||||
witness: []string{
|
||||
"3045022100ee9fe8f9487afa977" +
|
||||
"6647ebcf0883ce0cd37454d7ce19889d34ba2c9" +
|
||||
"9ce5a9f402200341cb469d0efd3955acb9e46" +
|
||||
"f568d7e2cc10f9084aaff94ced6dc50a59134ad01",
|
||||
"03f0000d0639a22bfaf217e4c9428" +
|
||||
"9c2b0cc7fa1036f7fd5d9f61a9d6ec153100e",
|
||||
},
|
||||
segwit: true,
|
||||
scriptInfo: ScriptInfo{
|
||||
PkScriptClass: WitnessV0PubKeyHashTy,
|
||||
NumInputs: 2,
|
||||
ExpectedInputs: 2,
|
||||
SigOps: 1,
|
||||
},
|
||||
},
|
||||
{
|
||||
// Nested p2sh v0
|
||||
name: "p2wkh nested inside p2sh",
|
||||
pkScript: "HASH160 DATA_20 " +
|
||||
"0xb3a84b564602a9d68b4c9f19c2ea61458ff7826c EQUAL",
|
||||
sigScript: "DATA_22 0x0014ad0ffa2e387f07e7ead14dc56d5a97dbd6ff5a23",
|
||||
witness: []string{
|
||||
"3045022100cb1c2ac1ff1d57d" +
|
||||
"db98f7bdead905f8bf5bcc8641b029ce8eef25" +
|
||||
"c75a9e22a4702203be621b5c86b771288706be5" +
|
||||
"a7eee1db4fceabf9afb7583c1cc6ee3f8297b21201",
|
||||
"03f0000d0639a22bfaf217e4c9" +
|
||||
"4289c2b0cc7fa1036f7fd5d9f61a9d6ec153100e",
|
||||
},
|
||||
segwit: true,
|
||||
bip16: true,
|
||||
scriptInfo: ScriptInfo{
|
||||
PkScriptClass: ScriptHashTy,
|
||||
NumInputs: 3,
|
||||
ExpectedInputs: 3,
|
||||
SigOps: 1,
|
||||
},
|
||||
},
|
||||
{
|
||||
// A v0 p2wsh spend.
|
||||
name: "p2wsh spend of a p2wkh witness script",
|
||||
pkScript: "0 DATA_32 0xe112b88a0cd87ba387f44" +
|
||||
"9d443ee2596eb353beb1f0351ab2cba8909d875db23",
|
||||
witness: []string{
|
||||
"3045022100cb1c2ac1ff1d57d" +
|
||||
"db98f7bdead905f8bf5bcc8641b029ce8eef25" +
|
||||
"c75a9e22a4702203be621b5c86b771288706be5" +
|
||||
"a7eee1db4fceabf9afb7583c1cc6ee3f8297b21201",
|
||||
"03f0000d0639a22bfaf217e4c9" +
|
||||
"4289c2b0cc7fa1036f7fd5d9f61a9d6ec153100e",
|
||||
"76a914064977cb7b4a2e0c9680df0ef696e9e0e296b39988ac",
|
||||
},
|
||||
segwit: true,
|
||||
scriptInfo: ScriptInfo{
|
||||
PkScriptClass: WitnessV0ScriptHashTy,
|
||||
NumInputs: 3,
|
||||
ExpectedInputs: 3,
|
||||
SigOps: 1,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
sigScript := mustParseShortForm(test.sigScript)
|
||||
pkScript := mustParseShortForm(test.pkScript)
|
||||
|
||||
var witness wire.TxWitness
|
||||
|
||||
for _, witElement := range test.witness {
|
||||
wit, err := hex.DecodeString(witElement)
|
||||
if err != nil {
|
||||
t.Fatalf("unable to decode witness "+
|
||||
"element: %v", err)
|
||||
}
|
||||
|
||||
witness = append(witness, wit)
|
||||
}
|
||||
|
||||
si, err := CalcScriptInfo(sigScript, pkScript, witness,
|
||||
test.bip16, test.segwit)
|
||||
si, err := CalcScriptInfo(sigScript, pkScript, test.bip16)
|
||||
if e := tstCheckScriptError(err, test.scriptInfoErr); e != nil {
|
||||
t.Errorf("scriptinfo test %q: %v", test.name, e)
|
||||
continue
|
||||
@ -1030,20 +948,6 @@ var scriptClassTests = []struct {
|
||||
"3 CHECKMULTISIG",
|
||||
class: NonStandardTy,
|
||||
},
|
||||
|
||||
// New standard segwit script templates.
|
||||
{
|
||||
// A pay to witness pub key hash pk script.
|
||||
name: "Pay To Witness PubkeyHash",
|
||||
script: "0 DATA_20 0x1d0f172a0ecb48aee1be1f2687d2963ae33f71a1",
|
||||
class: WitnessV0PubKeyHashTy,
|
||||
},
|
||||
{
|
||||
// A pay to witness scripthash pk script.
|
||||
name: "Pay To Witness Scripthash",
|
||||
script: "0 DATA_32 0x9f96ade4b41d5433f4eda31e1738ec2b36f6e7d1420d94a6af99801a88f7f7ff",
|
||||
class: WitnessV0ScriptHashTy,
|
||||
},
|
||||
}
|
||||
|
||||
// TestScriptClass ensures all the scripts in scriptClassTests have the expected
|
||||
@ -1087,21 +991,11 @@ func TestStringifyClass(t *testing.T) {
|
||||
class: PubKeyHashTy,
|
||||
stringed: "pubkeyhash",
|
||||
},
|
||||
{
|
||||
name: "witnesspubkeyhash",
|
||||
class: WitnessV0PubKeyHashTy,
|
||||
stringed: "witness_v0_keyhash",
|
||||
},
|
||||
{
|
||||
name: "scripthash",
|
||||
class: ScriptHashTy,
|
||||
stringed: "scripthash",
|
||||
},
|
||||
{
|
||||
name: "witnessscripthash",
|
||||
class: WitnessV0ScriptHashTy,
|
||||
stringed: "witness_v0_scripthash",
|
||||
},
|
||||
{
|
||||
name: "multisigty",
|
||||
class: MultiSigTy,
|
||||
|
Loading…
x
Reference in New Issue
Block a user