1// Copyright (c) 2018 The btcsuite developers 2// Use of this source code is governed by an ISC 3// license that can be found in the LICENSE file. 4 5package psbt 6 7import ( 8 "bytes" 9 "encoding/base64" 10 "encoding/binary" 11 "encoding/hex" 12 "testing" 13 14 "github.com/btcsuite/btcd/chaincfg/chainhash" 15 "github.com/btcsuite/btcd/txscript" 16 "github.com/btcsuite/btcd/wire" 17 "github.com/btcsuite/btcutil" 18 "github.com/davecgh/go-spew/spew" 19) 20 21// Test vectors from: 22// // https://github.com/bitcoin/bips/blob/master/bip-0174.mediawiki#test-vectors 23 24// createPsbtFromSignedTx is a utility function to create a PSBT from an 25// already-signed transaction, so we can test reconstructing, signing and 26// extracting it. Returned are: an unsigned transaction serialization, a list 27// of scriptSigs, one per input, and a list of witnesses, one per input. 28func createPsbtFromSignedTx(serializedSignedTx []byte) ( 29 *Packet, [][]byte, []wire.TxWitness, error) { 30 31 tx := wire.NewMsgTx(2) 32 err := tx.Deserialize(bytes.NewReader(serializedSignedTx)) 33 if err != nil { 34 return nil, nil, nil, err 35 } 36 scriptSigs := make([][]byte, 0, len(tx.TxIn)) 37 witnesses := make([]wire.TxWitness, 0, len(tx.TxIn)) 38 tx2 := tx.Copy() 39 40 // Blank out signature info in inputs 41 for i, tin := range tx2.TxIn { 42 tin.SignatureScript = nil 43 scriptSigs = append(scriptSigs, tx.TxIn[i].SignatureScript) 44 tin.Witness = nil 45 witnesses = append(witnesses, tx.TxIn[i].Witness) 46 47 } 48 49 // Outputs always contain: (value, scriptPubkey) so don't need 50 // amending. Now tx2 is tx with all signing data stripped out 51 unsignedPsbt, err := NewFromUnsignedTx(tx2) 52 if err != nil { 53 return nil, nil, nil, err 54 } 55 return unsignedPsbt, scriptSigs, witnesses, nil 56} 57 58// These are all valid PSBTs 59var validPsbtHex = map[int]string{ 60 0: "70736274ff0100750200000001268171371edff285e937adeea4b37b78000c0566cbb3ad64641713ca42171bf60000000000feffffff02d3dff505000000001976a914d0c59903c5bac2868760e90fd521a4665aa7652088ac00e1f5050000000017a9143545e6e33b832c47050f24d3eeb93c9c03948bc787b32e1300000100fda5010100000000010289a3c71eab4d20e0371bbba4cc698fa295c9463afa2e397f8533ccb62f9567e50100000017160014be18d152a9b012039daf3da7de4f53349eecb985ffffffff86f8aa43a71dff1448893a530a7237ef6b4608bbb2dd2d0171e63aec6a4890b40100000017160014fe3e9ef1a745e974d902c4355943abcb34bd5353ffffffff0200c2eb0b000000001976a91485cff1097fd9e008bb34af709c62197b38978a4888ac72fef84e2c00000017a914339725ba21efd62ac753a9bcd067d6c7a6a39d05870247304402202712be22e0270f394f568311dc7ca9a68970b8025fdd3b240229f07f8a5f3a240220018b38d7dcd314e734c9276bd6fb40f673325bc4baa144c800d2f2f02db2765c012103d2e15674941bad4a996372cb87e1856d3652606d98562fe39c5e9e7e413f210502483045022100d12b852d85dcd961d2f5f4ab660654df6eedcc794c0c33ce5cc309ffb5fce58d022067338a8e0e1725c197fb1a88af59f51e44e4255b20167c8684031c05d1f2592a01210223b72beef0965d10be0778efecd61fcac6f79a4ea169393380734464f84f2ab300000000000000", 61 1: "70736274ff0100a00200000002ab0949a08c5af7c49b8212f417e2f15ab3f5c33dcf153821a8139f877a5b7be40000000000feffffffab0949a08c5af7c49b8212f417e2f15ab3f5c33dcf153821a8139f877a5b7be40100000000feffffff02603bea0b000000001976a914768a40bbd740cbe81d988e71de2a4d5c71396b1d88ac8e240000000000001976a9146f4620b553fa095e721b9ee0efe9fa039cca459788ac000000000001076a47304402204759661797c01b036b25928948686218347d89864b719e1f7fcf57d1e511658702205309eabf56aa4d8891ffd111fdf1336f3a29da866d7f8486d75546ceedaf93190121035cdc61fc7ba971c0b501a646a2a83b102cb43881217ca682dc86e2d73fa882920001012000e1f5050000000017a9143545e6e33b832c47050f24d3eeb93c9c03948bc787010416001485d13537f2e265405a34dbafa9e3dda01fb82308000000", 62 2: "70736274ff0100750200000001268171371edff285e937adeea4b37b78000c0566cbb3ad64641713ca42171bf60000000000feffffff02d3dff505000000001976a914d0c59903c5bac2868760e90fd521a4665aa7652088ac00e1f5050000000017a9143545e6e33b832c47050f24d3eeb93c9c03948bc787b32e1300000100fda5010100000000010289a3c71eab4d20e0371bbba4cc698fa295c9463afa2e397f8533ccb62f9567e50100000017160014be18d152a9b012039daf3da7de4f53349eecb985ffffffff86f8aa43a71dff1448893a530a7237ef6b4608bbb2dd2d0171e63aec6a4890b40100000017160014fe3e9ef1a745e974d902c4355943abcb34bd5353ffffffff0200c2eb0b000000001976a91485cff1097fd9e008bb34af709c62197b38978a4888ac72fef84e2c00000017a914339725ba21efd62ac753a9bcd067d6c7a6a39d05870247304402202712be22e0270f394f568311dc7ca9a68970b8025fdd3b240229f07f8a5f3a240220018b38d7dcd314e734c9276bd6fb40f673325bc4baa144c800d2f2f02db2765c012103d2e15674941bad4a996372cb87e1856d3652606d98562fe39c5e9e7e413f210502483045022100d12b852d85dcd961d2f5f4ab660654df6eedcc794c0c33ce5cc309ffb5fce58d022067338a8e0e1725c197fb1a88af59f51e44e4255b20167c8684031c05d1f2592a01210223b72beef0965d10be0778efecd61fcac6f79a4ea169393380734464f84f2ab30000000001030401000000000000", 63 3: "70736274ff0100a00200000002ab0949a08c5af7c49b8212f417e2f15ab3f5c33dcf153821a8139f877a5b7be40000000000feffffffab0949a08c5af7c49b8212f417e2f15ab3f5c33dcf153821a8139f877a5b7be40100000000feffffff02603bea0b000000001976a914768a40bbd740cbe81d988e71de2a4d5c71396b1d88ac8e240000000000001976a9146f4620b553fa095e721b9ee0efe9fa039cca459788ac00000000000100df0200000001268171371edff285e937adeea4b37b78000c0566cbb3ad64641713ca42171bf6000000006a473044022070b2245123e6bf474d60c5b50c043d4c691a5d2435f09a34a7662a9dc251790a022001329ca9dacf280bdf30740ec0390422422c81cb45839457aeb76fc12edd95b3012102657d118d3357b8e0f4c2cd46db7b39f6d9c38d9a70abcb9b2de5dc8dbfe4ce31feffffff02d3dff505000000001976a914d0c59903c5bac2868760e90fd521a4665aa7652088ac00e1f5050000000017a9143545e6e33b832c47050f24d3eeb93c9c03948bc787b32e13000001012000e1f5050000000017a9143545e6e33b832c47050f24d3eeb93c9c03948bc787010416001485d13537f2e265405a34dbafa9e3dda01fb8230800220202ead596687ca806043edc3de116cdf29d5e9257c196cd055cf698c8d02bf24e9910b4a6ba670000008000000080020000800022020394f62be9df19952c5587768aeb7698061ad2c4a25c894f47d8c162b4d7213d0510b4a6ba6700000080010000800200008000", 64 4: "70736274ff0100550200000001279a2323a5dfb51fc45f220fa58b0fc13e1e3342792a85d7e36cd6333b5cbc390000000000ffffffff01a05aea0b000000001976a914ffe9c0061097cc3b636f2cb0460fa4fc427d2b4588ac0000000000010120955eea0b0000000017a9146345200f68d189e1adc0df1c4d16ea8f14c0dbeb87220203b1341ccba7683b6af4f1238cd6e97e7167d569fac47f1e48d47541844355bd4646304302200424b58effaaa694e1559ea5c93bbfd4a89064224055cdf070b6771469442d07021f5c8eb0fea6516d60b8acb33ad64ede60e8785bfb3aa94b99bdf86151db9a9a010104220020771fd18ad459666dd49f3d564e3dbc42f4c84774e360ada16816a8ed488d5681010547522103b1341ccba7683b6af4f1238cd6e97e7167d569fac47f1e48d47541844355bd462103de55d1e1dac805e3f8a58c1fbf9b94c02f3dbaafe127fefca4995f26f82083bd52ae220603b1341ccba7683b6af4f1238cd6e97e7167d569fac47f1e48d47541844355bd4610b4a6ba67000000800000008004000080220603de55d1e1dac805e3f8a58c1fbf9b94c02f3dbaafe127fefca4995f26f82083bd10b4a6ba670000008000000080050000800000", 65 5: "70736274ff01003f0200000001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000000000ffffffff010000000000000000036a010000000000000a0f0102030405060708090f0102030405060708090a0b0c0d0e0f0000", 66} 67 68// These are all invalid PSBTs for the indicated 69// reasons. 70var invalidPsbtHex = map[int]string{ 71 // wire format, not PSBT format 72 0: "0200000001268171371edff285e937adeea4b37b78000c0566cbb3ad64641713ca42171bf6000000006a473044022070b2245123e6bf474d60c5b50c043d4c691a5d2435f09a34a7662a9dc251790a022001329ca9dacf280bdf30740ec0390422422c81cb45839457aeb76fc12edd95b3012102657d118d3357b8e0f4c2cd46db7b39f6d9c38d9a70abcb9b2de5dc8dbfe4ce31feffffff02d3dff505000000001976a914d0c59903c5bac2868760e90fd521a4665aa7652088ac00e1f5050000000017a9143545e6e33b832c47050f24d3eeb93c9c03948bc787b32e1300", 73 // missing outputs 74 1: "70736274ff0100750200000001268171371edff285e937adeea4b37b78000c0566cbb3ad64641713ca42171bf60000000000feffffff02d3dff505000000001976a914d0c59903c5bac2868760e90fd521a4665aa7652088ac00e1f5050000000017a9143545e6e33b832c47050f24d3eeb93c9c03948bc787b32e1300000100fda5010100000000010289a3c71eab4d20e0371bbba4cc698fa295c9463afa2e397f8533ccb62f9567e50100000017160014be18d152a9b012039daf3da7de4f53349eecb985ffffffff86f8aa43a71dff1448893a530a7237ef6b4608bbb2dd2d0171e63aec6a4890b40100000017160014fe3e9ef1a745e974d902c4355943abcb34bd5353ffffffff0200c2eb0b000000001976a91485cff1097fd9e008bb34af709c62197b38978a4888ac72fef84e2c00000017a914339725ba21efd62ac753a9bcd067d6c7a6a39d05870247304402202712be22e0270f394f568311dc7ca9a68970b8025fdd3b240229f07f8a5f3a240220018b38d7dcd314e734c9276bd6fb40f673325bc4baa144c800d2f2f02db2765c012103d2e15674941bad4a996372cb87e1856d3652606d98562fe39c5e9e7e413f210502483045022100d12b852d85dcd961d2f5f4ab660654df6eedcc794c0c33ce5cc309ffb5fce58d022067338a8e0e1725c197fb1a88af59f51e44e4255b20167c8684031c05d1f2592a01210223b72beef0965d10be0778efecd61fcac6f79a4ea169393380734464f84f2ab30000000000", 75 // Filled in scriptSig in unsigned tx 76 2: "70736274ff0100fd0a010200000002ab0949a08c5af7c49b8212f417e2f15ab3f5c33dcf153821a8139f877a5b7be4000000006a47304402204759661797c01b036b25928948686218347d89864b719e1f7fcf57d1e511658702205309eabf56aa4d8891ffd111fdf1336f3a29da866d7f8486d75546ceedaf93190121035cdc61fc7ba971c0b501a646a2a83b102cb43881217ca682dc86e2d73fa88292feffffffab0949a08c5af7c49b8212f417e2f15ab3f5c33dcf153821a8139f877a5b7be40100000000feffffff02603bea0b000000001976a914768a40bbd740cbe81d988e71de2a4d5c71396b1d88ac8e240000000000001976a9146f4620b553fa095e721b9ee0efe9fa039cca459788ac00000000000001012000e1f5050000000017a9143545e6e33b832c47050f24d3eeb93c9c03948bc787010416001485d13537f2e265405a34dbafa9e3dda01fb82308000000", 77 // No unsigned tx 78 3: "70736274ff000100fda5010100000000010289a3c71eab4d20e0371bbba4cc698fa295c9463afa2e397f8533ccb62f9567e50100000017160014be18d152a9b012039daf3da7de4f53349eecb985ffffffff86f8aa43a71dff1448893a530a7237ef6b4608bbb2dd2d0171e63aec6a4890b40100000017160014fe3e9ef1a745e974d902c4355943abcb34bd5353ffffffff0200c2eb0b000000001976a91485cff1097fd9e008bb34af709c62197b38978a4888ac72fef84e2c00000017a914339725ba21efd62ac753a9bcd067d6c7a6a39d05870247304402202712be22e0270f394f568311dc7ca9a68970b8025fdd3b240229f07f8a5f3a240220018b38d7dcd314e734c9276bd6fb40f673325bc4baa144c800d2f2f02db2765c012103d2e15674941bad4a996372cb87e1856d3652606d98562fe39c5e9e7e413f210502483045022100d12b852d85dcd961d2f5f4ab660654df6eedcc794c0c33ce5cc309ffb5fce58d022067338a8e0e1725c197fb1a88af59f51e44e4255b20167c8684031c05d1f2592a01210223b72beef0965d10be0778efecd61fcac6f79a4ea169393380734464f84f2ab30000000000", 79 // Duplicate keys in an input 80 4: "70736274ff0100750200000001268171371edff285e937adeea4b37b78000c0566cbb3ad64641713ca42171bf60000000000feffffff02d3dff505000000001976a914d0c59903c5bac2868760e90fd521a4665aa7652088ac00e1f5050000000017a9143545e6e33b832c47050f24d3eeb93c9c03948bc787b32e1300000100fda5010100000000010289a3c71eab4d20e0371bbba4cc698fa295c9463afa2e397f8533ccb62f9567e50100000017160014be18d152a9b012039daf3da7de4f53349eecb985ffffffff86f8aa43a71dff1448893a530a7237ef6b4608bbb2dd2d0171e63aec6a4890b40100000017160014fe3e9ef1a745e974d902c4355943abcb34bd5353ffffffff0200c2eb0b000000001976a91485cff1097fd9e008bb34af709c62197b38978a4888ac72fef84e2c00000017a914339725ba21efd62ac753a9bcd067d6c7a6a39d05870247304402202712be22e0270f394f568311dc7ca9a68970b8025fdd3b240229f07f8a5f3a240220018b38d7dcd314e734c9276bd6fb40f673325bc4baa144c800d2f2f02db2765c012103d2e15674941bad4a996372cb87e1856d3652606d98562fe39c5e9e7e413f210502483045022100d12b852d85dcd961d2f5f4ab660654df6eedcc794c0c33ce5cc309ffb5fce58d022067338a8e0e1725c197fb1a88af59f51e44e4255b20167c8684031c05d1f2592a01210223b72beef0965d10be0778efecd61fcac6f79a4ea169393380734464f84f2ab30000000001003f0200000001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000000000ffffffff010000000000000000036a010000000000000000", 81 // Invalid global transaction typed key 82 5: "70736274ff020001550200000001279a2323a5dfb51fc45f220fa58b0fc13e1e3342792a85d7e36cd6333b5cbc390000000000ffffffff01a05aea0b000000001976a914ffe9c0061097cc3b636f2cb0460fa4fc427d2b4588ac0000000000010120955eea0b0000000017a9146345200f68d189e1adc0df1c4d16ea8f14c0dbeb87220203b1341ccba7683b6af4f1238cd6e97e7167d569fac47f1e48d47541844355bd4646304302200424b58effaaa694e1559ea5c93bbfd4a89064224055cdf070b6771469442d07021f5c8eb0fea6516d60b8acb33ad64ede60e8785bfb3aa94b99bdf86151db9a9a010104220020771fd18ad459666dd49f3d564e3dbc42f4c84774e360ada16816a8ed488d5681010547522103b1341ccba7683b6af4f1238cd6e97e7167d569fac47f1e48d47541844355bd462103de55d1e1dac805e3f8a58c1fbf9b94c02f3dbaafe127fefca4995f26f82083bd52ae220603b1341ccba7683b6af4f1238cd6e97e7167d569fac47f1e48d47541844355bd4610b4a6ba67000000800000008004000080220603de55d1e1dac805e3f8a58c1fbf9b94c02f3dbaafe127fefca4995f26f82083bd10b4a6ba670000008000000080050000800000", 83 // Invalid input witness utxo typed key 84 6: "70736274ff0100550200000001279a2323a5dfb51fc45f220fa58b0fc13e1e3342792a85d7e36cd6333b5cbc390000000000ffffffff01a05aea0b000000001976a914ffe9c0061097cc3b636f2cb0460fa4fc427d2b4588ac000000000002010020955eea0b0000000017a9146345200f68d189e1adc0df1c4d16ea8f14c0dbeb87220203b1341ccba7683b6af4f1238cd6e97e7167d569fac47f1e48d47541844355bd4646304302200424b58effaaa694e1559ea5c93bbfd4a89064224055cdf070b6771469442d07021f5c8eb0fea6516d60b8acb33ad64ede60e8785bfb3aa94b99bdf86151db9a9a010104220020771fd18ad459666dd49f3d564e3dbc42f4c84774e360ada16816a8ed488d5681010547522103b1341ccba7683b6af4f1238cd6e97e7167d569fac47f1e48d47541844355bd462103de55d1e1dac805e3f8a58c1fbf9b94c02f3dbaafe127fefca4995f26f82083bd52ae220603b1341ccba7683b6af4f1238cd6e97e7167d569fac47f1e48d47541844355bd4610b4a6ba67000000800000008004000080220603de55d1e1dac805e3f8a58c1fbf9b94c02f3dbaafe127fefca4995f26f82083bd10b4a6ba670000008000000080050000800000", 85 // Invalid pubkey length for input partial signature typed key 86 7: "70736274ff0100550200000001279a2323a5dfb51fc45f220fa58b0fc13e1e3342792a85d7e36cd6333b5cbc390000000000ffffffff01a05aea0b000000001976a914ffe9c0061097cc3b636f2cb0460fa4fc427d2b4588ac0000000000010120955eea0b0000000017a9146345200f68d189e1adc0df1c4d16ea8f14c0dbeb87210203b1341ccba7683b6af4f1238cd6e97e7167d569fac47f1e48d47541844355bd46304302200424b58effaaa694e1559ea5c93bbfd4a89064224055cdf070b6771469442d07021f5c8eb0fea6516d60b8acb33ad64ede60e8785bfb3aa94b99bdf86151db9a9a010104220020771fd18ad459666dd49f3d564e3dbc42f4c84774e360ada16816a8ed488d5681010547522103b1341ccba7683b6af4f1238cd6e97e7167d569fac47f1e48d47541844355bd462103de55d1e1dac805e3f8a58c1fbf9b94c02f3dbaafe127fefca4995f26f82083bd52ae220603b1341ccba7683b6af4f1238cd6e97e7167d569fac47f1e48d47541844355bd4610b4a6ba67000000800000008004000080220603de55d1e1dac805e3f8a58c1fbf9b94c02f3dbaafe127fefca4995f26f82083bd10b4a6ba670000008000000080050000800000", 87 // Invalid redeemscript typed key 88 8: "70736274ff0100550200000001279a2323a5dfb51fc45f220fa58b0fc13e1e3342792a85d7e36cd6333b5cbc390000000000ffffffff01a05aea0b000000001976a914ffe9c0061097cc3b636f2cb0460fa4fc427d2b4588ac0000000000010120955eea0b0000000017a9146345200f68d189e1adc0df1c4d16ea8f14c0dbeb87220203b1341ccba7683b6af4f1238cd6e97e7167d569fac47f1e48d47541844355bd4646304302200424b58effaaa694e1559ea5c93bbfd4a89064224055cdf070b6771469442d07021f5c8eb0fea6516d60b8acb33ad64ede60e8785bfb3aa94b99bdf86151db9a9a01020400220020771fd18ad459666dd49f3d564e3dbc42f4c84774e360ada16816a8ed488d5681010547522103b1341ccba7683b6af4f1238cd6e97e7167d569fac47f1e48d47541844355bd462103de55d1e1dac805e3f8a58c1fbf9b94c02f3dbaafe127fefca4995f26f82083bd52ae220603b1341ccba7683b6af4f1238cd6e97e7167d569fac47f1e48d47541844355bd4610b4a6ba67000000800000008004000080220603de55d1e1dac805e3f8a58c1fbf9b94c02f3dbaafe127fefca4995f26f82083bd10b4a6ba670000008000000080050000800000", 89 // Invalid witness script typed key 90 9: "70736274ff0100550200000001279a2323a5dfb51fc45f220fa58b0fc13e1e3342792a85d7e36cd6333b5cbc390000000000ffffffff01a05aea0b000000001976a914ffe9c0061097cc3b636f2cb0460fa4fc427d2b4588ac0000000000010120955eea0b0000000017a9146345200f68d189e1adc0df1c4d16ea8f14c0dbeb87220203b1341ccba7683b6af4f1238cd6e97e7167d569fac47f1e48d47541844355bd4646304302200424b58effaaa694e1559ea5c93bbfd4a89064224055cdf070b6771469442d07021f5c8eb0fea6516d60b8acb33ad64ede60e8785bfb3aa94b99bdf86151db9a9a010104220020771fd18ad459666dd49f3d564e3dbc42f4c84774e360ada16816a8ed488d568102050047522103b1341ccba7683b6af4f1238cd6e97e7167d569fac47f1e48d47541844355bd462103de55d1e1dac805e3f8a58c1fbf9b94c02f3dbaafe127fefca4995f26f82083bd52ae220603b1341ccba7683b6af4f1238cd6e97e7167d569fac47f1e48d47541844355bd4610b4a6ba67000000800000008004000080220603de55d1e1dac805e3f8a58c1fbf9b94c02f3dbaafe127fefca4995f26f82083bd10b4a6ba670000008000000080050000800000", 91 // Invalid bip32 typed key 92 10: "70736274ff0100550200000001279a2323a5dfb51fc45f220fa58b0fc13e1e3342792a85d7e36cd6333b5cbc390000000000ffffffff01a05aea0b000000001976a914ffe9c0061097cc3b636f2cb0460fa4fc427d2b4588ac0000000000010120955eea0b0000000017a9146345200f68d189e1adc0df1c4d16ea8f14c0dbeb87220203b1341ccba7683b6af4f1238cd6e97e7167d569fac47f1e48d47541844355bd4646304302200424b58effaaa694e1559ea5c93bbfd4a89064224055cdf070b6771469442d07021f5c8eb0fea6516d60b8acb33ad64ede60e8785bfb3aa94b99bdf86151db9a9a010104220020771fd18ad459666dd49f3d564e3dbc42f4c84774e360ada16816a8ed488d5681010547522103b1341ccba7683b6af4f1238cd6e97e7167d569fac47f1e48d47541844355bd462103de55d1e1dac805e3f8a58c1fbf9b94c02f3dbaafe127fefca4995f26f82083bd52ae210603b1341ccba7683b6af4f1238cd6e97e7167d569fac47f1e48d47541844355bd10b4a6ba67000000800000008004000080220603de55d1e1dac805e3f8a58c1fbf9b94c02f3dbaafe127fefca4995f26f82083bd10b4a6ba670000008000000080050000800000", 93 // Invalid non-witness utxo typed key 94 11: "70736274ff01009a020000000258e87a21b56daf0c23be8e7070456c336f7cbaa5c8757924f545887bb2abdd750000000000ffffffff838d0427d0ec650a68aa46bb0b098aea4422c071b2ca78352a077959d07cea1d0100000000ffffffff0270aaf00800000000160014d85c2b71d0060b09c9886aeb815e50991dda124d00e1f5050000000016001400aea9a2e5f0f876a588df5546e8742d1d87008f0000000000020000bb0200000001aad73931018bd25f84ae400b68848be09db706eac2ac18298babee71ab656f8b0000000048473044022058f6fc7c6a33e1b31548d481c826c015bd30135aad42cd67790dab66d2ad243b02204a1ced2604c6735b6393e5b41691dd78b00f0c5942fb9f751856faa938157dba01feffffff0280f0fa020000000017a9140fb9463421696b82c833af241c78c17ddbde493487d0f20a270100000017a91429ca74f8a08f81999428185c97b5d852e4063f6187650000000107da00473044022074018ad4180097b873323c0015720b3684cc8123891048e7dbcd9b55ad679c99022073d369b740e3eb53dcefa33823c8070514ca55a7dd9544f157c167913261118c01483045022100f61038b308dc1da865a34852746f015772934208c6d24454393cd99bdf2217770220056e675a675a6d0a02b85b14e5e29074d8a25a9b5760bea2816f661910a006ea01475221029583bf39ae0a609747ad199addd634fa6108559d6c5cd39b4c2183f1ab96e07f2102dab61ff49a14db6a7d02b0cd1fbb78fc4b18312b5b4e54dae4dba2fbfef536d752ae0001012000c2eb0b0000000017a914b7f5faf40e3d40a5a459b1db3535f2b72fa921e8870107232200208c2353173743b595dfb4a07b72ba8e42e3797da74e87fe7d9d7497e3b20289030108da0400473044022062eb7a556107a7c73f45ac4ab5a1dddf6f7075fb1275969a7f383efff784bcb202200c05dbb7470dbf2f08557dd356c7325c1ed30913e996cd3840945db12228da5f01473044022065f45ba5998b59a27ffe1a7bed016af1f1f90d54b3aa8f7450aa5f56a25103bd02207f724703ad1edb96680b284b56d4ffcb88f7fb759eabbe08aa30f29b851383d20147522103089dc10c7ac6db54f91329af617333db388cead0c231f723379d1b99030b02dc21023add904f3d6dcf59ddb906b0dee23529b7ffb9ed50e5e86151926860221f0e7352ae00220203a9a4c37f5996d3aa25dbac6b570af0650394492942460b354753ed9eeca5877110d90c6a4f000000800000008004000080002202027f6399757d2eff55a136ad02c684b1838b6556e5f1b6b34282a94b6b5005109610d90c6a4f00000080000000800500008000", 95 // Invalid final scriptsig typed key 96 12: "70736274ff01009a020000000258e87a21b56daf0c23be8e7070456c336f7cbaa5c8757924f545887bb2abdd750000000000ffffffff838d0427d0ec650a68aa46bb0b098aea4422c071b2ca78352a077959d07cea1d0100000000ffffffff0270aaf00800000000160014d85c2b71d0060b09c9886aeb815e50991dda124d00e1f5050000000016001400aea9a2e5f0f876a588df5546e8742d1d87008f00000000000100bb0200000001aad73931018bd25f84ae400b68848be09db706eac2ac18298babee71ab656f8b0000000048473044022058f6fc7c6a33e1b31548d481c826c015bd30135aad42cd67790dab66d2ad243b02204a1ced2604c6735b6393e5b41691dd78b00f0c5942fb9f751856faa938157dba01feffffff0280f0fa020000000017a9140fb9463421696b82c833af241c78c17ddbde493487d0f20a270100000017a91429ca74f8a08f81999428185c97b5d852e4063f618765000000020700da00473044022074018ad4180097b873323c0015720b3684cc8123891048e7dbcd9b55ad679c99022073d369b740e3eb53dcefa33823c8070514ca55a7dd9544f157c167913261118c01483045022100f61038b308dc1da865a34852746f015772934208c6d24454393cd99bdf2217770220056e675a675a6d0a02b85b14e5e29074d8a25a9b5760bea2816f661910a006ea01475221029583bf39ae0a609747ad199addd634fa6108559d6c5cd39b4c2183f1ab96e07f2102dab61ff49a14db6a7d02b0cd1fbb78fc4b18312b5b4e54dae4dba2fbfef536d752ae0001012000c2eb0b0000000017a914b7f5faf40e3d40a5a459b1db3535f2b72fa921e8870107232200208c2353173743b595dfb4a07b72ba8e42e3797da74e87fe7d9d7497e3b20289030108da0400473044022062eb7a556107a7c73f45ac4ab5a1dddf6f7075fb1275969a7f383efff784bcb202200c05dbb7470dbf2f08557dd356c7325c1ed30913e996cd3840945db12228da5f01473044022065f45ba5998b59a27ffe1a7bed016af1f1f90d54b3aa8f7450aa5f56a25103bd02207f724703ad1edb96680b284b56d4ffcb88f7fb759eabbe08aa30f29b851383d20147522103089dc10c7ac6db54f91329af617333db388cead0c231f723379d1b99030b02dc21023add904f3d6dcf59ddb906b0dee23529b7ffb9ed50e5e86151926860221f0e7352ae00220203a9a4c37f5996d3aa25dbac6b570af0650394492942460b354753ed9eeca5877110d90c6a4f000000800000008004000080002202027f6399757d2eff55a136ad02c684b1838b6556e5f1b6b34282a94b6b5005109610d90c6a4f00000080000000800500008000", 97 // Invalid final script witness typed key 98 13: "70736274ff01009a020000000258e87a21b56daf0c23be8e7070456c336f7cbaa5c8757924f545887bb2abdd750000000000ffffffff838d0427d0ec650a68aa46bb0b098aea4422c071b2ca78352a077959d07cea1d0100000000ffffffff0270aaf00800000000160014d85c2b71d0060b09c9886aeb815e50991dda124d00e1f5050000000016001400aea9a2e5f0f876a588df5546e8742d1d87008f00000000000100bb0200000001aad73931018bd25f84ae400b68848be09db706eac2ac18298babee71ab656f8b0000000048473044022058f6fc7c6a33e1b31548d481c826c015bd30135aad42cd67790dab66d2ad243b02204a1ced2604c6735b6393e5b41691dd78b00f0c5942fb9f751856faa938157dba01feffffff0280f0fa020000000017a9140fb9463421696b82c833af241c78c17ddbde493487d0f20a270100000017a91429ca74f8a08f81999428185c97b5d852e4063f6187650000000107da00473044022074018ad4180097b873323c0015720b3684cc8123891048e7dbcd9b55ad679c99022073d369b740e3eb53dcefa33823c8070514ca55a7dd9544f157c167913261118c01483045022100f61038b308dc1da865a34852746f015772934208c6d24454393cd99bdf2217770220056e675a675a6d0a02b85b14e5e29074d8a25a9b5760bea2816f661910a006ea01475221029583bf39ae0a609747ad199addd634fa6108559d6c5cd39b4c2183f1ab96e07f2102dab61ff49a14db6a7d02b0cd1fbb78fc4b18312b5b4e54dae4dba2fbfef536d752ae0001012000c2eb0b0000000017a914b7f5faf40e3d40a5a459b1db3535f2b72fa921e8870107232200208c2353173743b595dfb4a07b72ba8e42e3797da74e87fe7d9d7497e3b2028903020800da0400473044022062eb7a556107a7c73f45ac4ab5a1dddf6f7075fb1275969a7f383efff784bcb202200c05dbb7470dbf2f08557dd356c7325c1ed30913e996cd3840945db12228da5f01473044022065f45ba5998b59a27ffe1a7bed016af1f1f90d54b3aa8f7450aa5f56a25103bd02207f724703ad1edb96680b284b56d4ffcb88f7fb759eabbe08aa30f29b851383d20147522103089dc10c7ac6db54f91329af617333db388cead0c231f723379d1b99030b02dc21023add904f3d6dcf59ddb906b0dee23529b7ffb9ed50e5e86151926860221f0e7352ae00220203a9a4c37f5996d3aa25dbac6b570af0650394492942460b354753ed9eeca5877110d90c6a4f000000800000008004000080002202027f6399757d2eff55a136ad02c684b1838b6556e5f1b6b34282a94b6b5005109610d90c6a4f00000080000000800500008000", 99 // Invalid pubkey in output BIP32 derivation paths typed key 100 14: "70736274ff01009a020000000258e87a21b56daf0c23be8e7070456c336f7cbaa5c8757924f545887bb2abdd750000000000ffffffff838d0427d0ec650a68aa46bb0b098aea4422c071b2ca78352a077959d07cea1d0100000000ffffffff0270aaf00800000000160014d85c2b71d0060b09c9886aeb815e50991dda124d00e1f5050000000016001400aea9a2e5f0f876a588df5546e8742d1d87008f00000000000100bb0200000001aad73931018bd25f84ae400b68848be09db706eac2ac18298babee71ab656f8b0000000048473044022058f6fc7c6a33e1b31548d481c826c015bd30135aad42cd67790dab66d2ad243b02204a1ced2604c6735b6393e5b41691dd78b00f0c5942fb9f751856faa938157dba01feffffff0280f0fa020000000017a9140fb9463421696b82c833af241c78c17ddbde493487d0f20a270100000017a91429ca74f8a08f81999428185c97b5d852e4063f6187650000000107da00473044022074018ad4180097b873323c0015720b3684cc8123891048e7dbcd9b55ad679c99022073d369b740e3eb53dcefa33823c8070514ca55a7dd9544f157c167913261118c01483045022100f61038b308dc1da865a34852746f015772934208c6d24454393cd99bdf2217770220056e675a675a6d0a02b85b14e5e29074d8a25a9b5760bea2816f661910a006ea01475221029583bf39ae0a609747ad199addd634fa6108559d6c5cd39b4c2183f1ab96e07f2102dab61ff49a14db6a7d02b0cd1fbb78fc4b18312b5b4e54dae4dba2fbfef536d752ae0001012000c2eb0b0000000017a914b7f5faf40e3d40a5a459b1db3535f2b72fa921e8870107232200208c2353173743b595dfb4a07b72ba8e42e3797da74e87fe7d9d7497e3b20289030108da0400473044022062eb7a556107a7c73f45ac4ab5a1dddf6f7075fb1275969a7f383efff784bcb202200c05dbb7470dbf2f08557dd356c7325c1ed30913e996cd3840945db12228da5f01473044022065f45ba5998b59a27ffe1a7bed016af1f1f90d54b3aa8f7450aa5f56a25103bd02207f724703ad1edb96680b284b56d4ffcb88f7fb759eabbe08aa30f29b851383d20147522103089dc10c7ac6db54f91329af617333db388cead0c231f723379d1b99030b02dc21023add904f3d6dcf59ddb906b0dee23529b7ffb9ed50e5e86151926860221f0e7352ae00210203a9a4c37f5996d3aa25dbac6b570af0650394492942460b354753ed9eeca58710d90c6a4f000000800000008004000080002202027f6399757d2eff55a136ad02c684b1838b6556e5f1b6b34282a94b6b5005109610d90c6a4f00000080000000800500008000", 101 // Invalid input sighash type typed key 102 15: "70736274ff0100730200000001301ae986e516a1ec8ac5b4bc6573d32f83b465e23ad76167d68b38e730b4dbdb0000000000ffffffff02747b01000000000017a91403aa17ae882b5d0d54b25d63104e4ffece7b9ea2876043993b0000000017a914b921b1ba6f722e4bfa83b6557a3139986a42ec8387000000000001011f00ca9a3b00000000160014d2d94b64ae08587eefc8eeb187c601e939f9037c0203000100000000010016001462e9e982fff34dd8239610316b090cd2a3b747cb000100220020876bad832f1d168015ed41232a9ea65a1815d9ef13c0ef8759f64b5b2b278a65010125512103b7ce23a01c5b4bf00a642537cdfabb315b668332867478ef51309d2bd57f8a8751ae00", 103 // Invalid output redeemscript typed key 104 16: "70736274ff0100730200000001301ae986e516a1ec8ac5b4bc6573d32f83b465e23ad76167d68b38e730b4dbdb0000000000ffffffff02747b01000000000017a91403aa17ae882b5d0d54b25d63104e4ffece7b9ea2876043993b0000000017a914b921b1ba6f722e4bfa83b6557a3139986a42ec8387000000000001011f00ca9a3b00000000160014d2d94b64ae08587eefc8eeb187c601e939f9037c0002000016001462e9e982fff34dd8239610316b090cd2a3b747cb000100220020876bad832f1d168015ed41232a9ea65a1815d9ef13c0ef8759f64b5b2b278a65010125512103b7ce23a01c5b4bf00a642537cdfabb315b668332867478ef51309d2bd57f8a8751ae00", 105 // Invalid output witnessScript typed key 106 17: "70736274ff0100730200000001301ae986e516a1ec8ac5b4bc6573d32f83b465e23ad76167d68b38e730b4dbdb0000000000ffffffff02747b01000000000017a91403aa17ae882b5d0d54b25d63104e4ffece7b9ea2876043993b0000000017a914b921b1ba6f722e4bfa83b6557a3139986a42ec8387000000000001011f00ca9a3b00000000160014d2d94b64ae08587eefc8eeb187c601e939f9037c00010016001462e9e982fff34dd8239610316b090cd2a3b747cb000100220020876bad832f1d168015ed41232a9ea65a1815d9ef13c0ef8759f64b5b2b278a6521010025512103b7ce23a01c5b4bf00a642537cdfabb315b668332867478ef51309d2bd57f8a8751ae00", 107 // Additional cases outside the existing test vectors. 108 // Invalid duplicate PartialSig 109 18: "70736274ff0100550200000001279a2323a5dfb51fc45f220fa58b0fc13e1e3342792a85d7e36cd6333b5cbc390000000000ffffffff01a05aea0b000000001976a914ffe9c0061097cc3b636f2cb0460fa4fc427d2b4588ac0000000000010120955eea0b0000000017a9146345200f68d189e1adc0df1c4d16ea8f14c0dbeb87220203b1341ccba7683b6af4f1238cd6e97e7167d569fac47f1e48d47541844355bd4646304302200424b58effaaa694e1559ea5c93bbfd4a89064224055cdf070b6771469442d07021f5c8eb0fea6516d60b8acb33ad64ede60e8785bfb3aa94b99bdf86151db9a9a01220203b1341ccba7683b6af4f1238cd6e97e7167d569fac47f1e48d47541844355bd4646304302200424b58effaaa694e1559ea5c93bbfd4a89064224055cdf070b6771469442d07021f5c8eb0fea6516d60b8acb33ad64ede60e8785bfb3aa94b99bdf86151db9a9a010104220020771fd18ad459666dd49f3d564e3dbc42f4c84774e360ada16816a8ed488d5681010547522103b1341ccba7683b6af4f1238cd6e97e7167d569fac47f1e48d47541844355bd462103de55d1e1dac805e3f8a58c1fbf9b94c02f3dbaafe127fefca4995f26f82083bd52ae220603b1341ccba7683b6af4f1238cd6e97e7167d569fac47f1e48d47541844355bd4610b4a6ba67000000800000008004000080220603de55d1e1dac805e3f8a58c1fbf9b94c02f3dbaafe127fefca4995f26f82083bd10b4a6ba670000008000000080050000800000", 110 // Invalid duplicate BIP32 derivation (different derivs, same key) 111 19: "70736274ff0100550200000001279a2323a5dfb51fc45f220fa58b0fc13e1e3342792a85d7e36cd6333b5cbc390000000000ffffffff01a05aea0b000000001976a914ffe9c0061097cc3b636f2cb0460fa4fc427d2b4588ac0000000000010120955eea0b0000000017a9146345200f68d189e1adc0df1c4d16ea8f14c0dbeb87220203b1341ccba7683b6af4f1238cd6e97e7167d569fac47f1e48d47541844355bd4646304302200424b58effaaa694e1559ea5c93bbfd4a89064224055cdf070b6771469442d07021f5c8eb0fea6516d60b8acb33ad64ede60e8785bfb3aa94b99bdf86151db9a9a010104220020771fd18ad459666dd49f3d564e3dbc42f4c84774e360ada16816a8ed488d5681010547522103b1341ccba7683b6af4f1238cd6e97e7167d569fac47f1e48d47541844355bd462103de55d1e1dac805e3f8a58c1fbf9b94c02f3dbaafe127fefca4995f26f82083bd52ae220603b1341ccba7683b6af4f1238cd6e97e7167d569fac47f1e48d47541844355bd4610b4a6ba67000000800000008004000080220603b1341ccba7683b6af4f1238cd6e97e7167d569fac47f1e48d47541844355bd4610b4a6ba670000008000000080050000800000", 112} 113 114// This tests that valid PSBT serializations can be parsed 115// into Psbt structs. 116func TestReadValidPsbtAndReserialize(t *testing.T) { 117 for _, v := range validPsbtHex { 118 PsbtBytes, err := hex.DecodeString(v) 119 if err != nil { 120 t.Fatalf("Unable to decode hex: %v", err) 121 } 122 123 testPsbt, err := NewFromRawBytes( 124 bytes.NewReader(PsbtBytes), false, 125 ) 126 if err != nil { 127 t.Fatalf("unable to parse psbt: %v", err) 128 } 129 130 t.Logf("Successfully parsed test, got transaction: %v", 131 spew.Sdump(testPsbt.UnsignedTx)) 132 133 var b bytes.Buffer 134 err = testPsbt.Serialize(&b) 135 if err != nil { 136 t.Fatalf("Unable to serialize created Psbt: %v", err) 137 } 138 139 raw := b.Bytes() 140 if !bytes.Equal(raw, PsbtBytes) { 141 t.Fatalf("Serialized PSBT didn't match: %v", 142 hex.EncodeToString(raw)) 143 } 144 } 145} 146 147func TestReadInvalidPsbt(t *testing.T) { 148 for _, v := range invalidPsbtHex { 149 PsbtBytes, err := hex.DecodeString(v) 150 if err != nil { 151 t.Fatalf("Unable to decode hex: %v", err) 152 } 153 154 _, err = NewFromRawBytes(bytes.NewReader(PsbtBytes), false) 155 if err == nil { 156 t.Fatalf("Incorrectly validated psbt: %v", 157 hex.EncodeToString(PsbtBytes)) 158 } 159 160 t.Logf("Correctly got error: %v", err) 161 } 162} 163 164func TestSanityCheck(t *testing.T) { 165 // TODO(guggero): Remove when checks for segwit v1 are implemented. 166 t.Skip("Skipping PSBT sanity checks for segwit v0.") 167 168 // Test strategy: 169 // 1. Create an invalid PSBT from a serialization 170 // Then ensure that the sanity check fails. 171 // 2. Create a valid PSBT from a serialization 172 // Then create an updater, add a witness utxo to a non-witness 173 // utxo. 174 // Then ensure that the sanity check fails. 175 // Then add a witnessScript field to a non-witness utxo. 176 // Then ensure that the sanity check fails. 177 178 // index 1 contains a psbt with two inputs, first non-witness, 179 // second witness. 180 psbtraw1, err := hex.DecodeString(validPsbtHex[1]) 181 if err != nil { 182 t.Fatalf("Unable to decode hex: %v", err) 183 } 184 psbt1, err := NewFromRawBytes(bytes.NewReader(psbtraw1), false) 185 if err != nil { 186 t.Fatalf("Unable to create Psbt struct: %v", err) 187 } 188 189 // Add a non-witness utxo field to input2 using raw insertion function, 190 // so that it becomes invalid, then NewUpdater should fail. 191 nonWitnessUtxoRaw, err := hex.DecodeString( 192 CUTestHexData["NonWitnessUtxo"], 193 ) 194 if err != nil { 195 t.Fatalf("Unable to decode hex: %v", err) 196 } 197 nonWitnessUtxo := wire.NewMsgTx(2) 198 err = nonWitnessUtxo.Deserialize(bytes.NewReader(nonWitnessUtxoRaw)) 199 if err != nil { 200 t.Fatalf("Unable to deserialize: %v", err) 201 } 202 inputs1 := &psbt1.Inputs[1] 203 inputs1.NonWitnessUtxo = nonWitnessUtxo 204 205 // The PSBT is now in an inconsistent state; Updater creation should 206 // fail. 207 updater, err := NewUpdater(psbt1) 208 if err == nil { 209 t.Fatalf("Failed to identify invalid PSBT state ( " + 210 "witness, non-witness fields)") 211 } 212 213 // Overwrite back with the correct psbt 214 psbtraw1, err = hex.DecodeString(validPsbtHex[1]) 215 if err != nil { 216 t.Fatalf("Unable to decode hex: %v", err) 217 } 218 psbt1, err = NewFromRawBytes(bytes.NewReader(psbtraw1), false) 219 updater, err = NewUpdater(psbt1) 220 if err != nil { 221 t.Fatalf("Unable to create Updater: %v", err) 222 } 223 224 // Create a fake non-witness utxo field to overlap with 225 // the existing witness input at index 1. 226 tx := wire.NewMsgTx(2) 227 err = tx.Deserialize(bytes.NewReader(nonWitnessUtxoRaw)) 228 if err != nil { 229 t.Fatalf("Error deserializing transaction: %v", err) 230 } 231 err = updater.AddInNonWitnessUtxo(tx, 1) 232 if err == nil { 233 t.Fatalf("Incorrectly accepted Psbt with conflicting witness " + 234 "and non-witness utxo entries in the same input.") 235 } 236 237 // Now we try again; this time we try to add a witnessScript 238 // key-value pair to an input which is non-witness, which should 239 // also be rejected. 240 psbt2, err := NewFromRawBytes( 241 bytes.NewReader(psbtraw1), false, 242 ) 243 if err != nil { 244 t.Fatalf("Unable to create Psbt struct: %v", err) 245 } 246 updater2, err := NewUpdater(psbt2) 247 if err != nil { 248 t.Fatalf("Got error creating updater2: %v", err) 249 } 250 witnessScript, err := hex.DecodeString( 251 CUTestHexData["Input2WitnessScript"]) 252 if err != nil { 253 t.Fatalf("Unable to decode hex: %v", err) 254 } 255 err = updater2.AddInWitnessScript(witnessScript, 0) 256 if err == nil { 257 t.Fatalf("Incorrectly accepted adding witness script field " + 258 "to non-witness utxo") 259 } 260} 261 262// Data for creation and updating tests 263// =============================================================================== 264var CUTestHexData = map[string]string{ 265 "scriptPubkey1": "0014d85c2b71d0060b09c9886aeb815e50991dda124d", 266 "scriptPubkey2": "001400aea9a2e5f0f876a588df5546e8742d1d87008f", 267 "txid1": "75ddabb27b8845f5247975c8a5ba7c6f336c4570708ebe230caf6db5217ae858", 268 "txid2": "1dea7cd05979072a3578cab271c02244ea8a090bbb46aa680a65ecd027048d83", 269 "COPsbtHex": "70736274ff01009a020000000258e87a21b56daf0c23be8e7070456c336f7cbaa5c8757924f545887bb2abdd750000000000ffffffff838d0427d0ec650a68aa46bb0b098aea4422c071b2ca78352a077959d07cea1d0100000000ffffffff0270aaf00800000000160014d85c2b71d0060b09c9886aeb815e50991dda124d00e1f5050000000016001400aea9a2e5f0f876a588df5546e8742d1d87008f000000000000000000", 270 "NonWitnessUtxo": "0200000001aad73931018bd25f84ae400b68848be09db706eac2ac18298babee71ab656f8b0000000048473044022058f6fc7c6a33e1b31548d481c826c015bd30135aad42cd67790dab66d2ad243b02204a1ced2604c6735b6393e5b41691dd78b00f0c5942fb9f751856faa938157dba01feffffff0280f0fa020000000017a9140fb9463421696b82c833af241c78c17ddbde493487d0f20a270100000017a91429ca74f8a08f81999428185c97b5d852e4063f618765000000", 271 "WitnessUtxo": "00c2eb0b0000000017a914b7f5faf40e3d40a5a459b1db3535f2b72fa921e887", 272 // After adding witnessutxo and nonwitness utxo to inputs: 273 "UOPsbtHex": "70736274ff01009a020000000258e87a21b56daf0c23be8e7070456c336f7cbaa5c8757924f545887bb2abdd750000000000ffffffff838d0427d0ec650a68aa46bb0b098aea4422c071b2ca78352a077959d07cea1d0100000000ffffffff0270aaf00800000000160014d85c2b71d0060b09c9886aeb815e50991dda124d00e1f5050000000016001400aea9a2e5f0f876a588df5546e8742d1d87008f00000000000100bb0200000001aad73931018bd25f84ae400b68848be09db706eac2ac18298babee71ab656f8b0000000048473044022058f6fc7c6a33e1b31548d481c826c015bd30135aad42cd67790dab66d2ad243b02204a1ced2604c6735b6393e5b41691dd78b00f0c5942fb9f751856faa938157dba01feffffff0280f0fa020000000017a9140fb9463421696b82c833af241c78c17ddbde493487d0f20a270100000017a91429ca74f8a08f81999428185c97b5d852e4063f6187650000000001012000c2eb0b0000000017a914b7f5faf40e3d40a5a459b1db3535f2b72fa921e887000000", 274 "Input1RedeemScript": "5221029583bf39ae0a609747ad199addd634fa6108559d6c5cd39b4c2183f1ab96e07f2102dab61ff49a14db6a7d02b0cd1fbb78fc4b18312b5b4e54dae4dba2fbfef536d752ae", 275 "Input2RedeemScript": "00208c2353173743b595dfb4a07b72ba8e42e3797da74e87fe7d9d7497e3b2028903", 276 "Input2WitnessScript": "522103089dc10c7ac6db54f91329af617333db388cead0c231f723379d1b99030b02dc21023add904f3d6dcf59ddb906b0dee23529b7ffb9ed50e5e86151926860221f0e7352ae", 277 // After adding redeemscripts and witness scripts to inputs: 278 "UOPsbtHex2": "70736274ff01009a020000000258e87a21b56daf0c23be8e7070456c336f7cbaa5c8757924f545887bb2abdd750000000000ffffffff838d0427d0ec650a68aa46bb0b098aea4422c071b2ca78352a077959d07cea1d0100000000ffffffff0270aaf00800000000160014d85c2b71d0060b09c9886aeb815e50991dda124d00e1f5050000000016001400aea9a2e5f0f876a588df5546e8742d1d87008f00000000000100bb0200000001aad73931018bd25f84ae400b68848be09db706eac2ac18298babee71ab656f8b0000000048473044022058f6fc7c6a33e1b31548d481c826c015bd30135aad42cd67790dab66d2ad243b02204a1ced2604c6735b6393e5b41691dd78b00f0c5942fb9f751856faa938157dba01feffffff0280f0fa020000000017a9140fb9463421696b82c833af241c78c17ddbde493487d0f20a270100000017a91429ca74f8a08f81999428185c97b5d852e4063f6187650000000104475221029583bf39ae0a609747ad199addd634fa6108559d6c5cd39b4c2183f1ab96e07f2102dab61ff49a14db6a7d02b0cd1fbb78fc4b18312b5b4e54dae4dba2fbfef536d752ae0001012000c2eb0b0000000017a914b7f5faf40e3d40a5a459b1db3535f2b72fa921e88701042200208c2353173743b595dfb4a07b72ba8e42e3797da74e87fe7d9d7497e3b2028903010547522103089dc10c7ac6db54f91329af617333db388cead0c231f723379d1b99030b02dc21023add904f3d6dcf59ddb906b0dee23529b7ffb9ed50e5e86151926860221f0e7352ae000000", 279 // After adding bip32 derivations to inputs and outputs: 280 "UOPsbtHex3": "70736274ff01009a020000000258e87a21b56daf0c23be8e7070456c336f7cbaa5c8757924f545887bb2abdd750000000000ffffffff838d0427d0ec650a68aa46bb0b098aea4422c071b2ca78352a077959d07cea1d0100000000ffffffff0270aaf00800000000160014d85c2b71d0060b09c9886aeb815e50991dda124d00e1f5050000000016001400aea9a2e5f0f876a588df5546e8742d1d87008f00000000000100bb0200000001aad73931018bd25f84ae400b68848be09db706eac2ac18298babee71ab656f8b0000000048473044022058f6fc7c6a33e1b31548d481c826c015bd30135aad42cd67790dab66d2ad243b02204a1ced2604c6735b6393e5b41691dd78b00f0c5942fb9f751856faa938157dba01feffffff0280f0fa020000000017a9140fb9463421696b82c833af241c78c17ddbde493487d0f20a270100000017a91429ca74f8a08f81999428185c97b5d852e4063f6187650000000104475221029583bf39ae0a609747ad199addd634fa6108559d6c5cd39b4c2183f1ab96e07f2102dab61ff49a14db6a7d02b0cd1fbb78fc4b18312b5b4e54dae4dba2fbfef536d752ae2206029583bf39ae0a609747ad199addd634fa6108559d6c5cd39b4c2183f1ab96e07f10d90c6a4f000000800000008000000080220602dab61ff49a14db6a7d02b0cd1fbb78fc4b18312b5b4e54dae4dba2fbfef536d710d90c6a4f0000008000000080010000800001012000c2eb0b0000000017a914b7f5faf40e3d40a5a459b1db3535f2b72fa921e88701042200208c2353173743b595dfb4a07b72ba8e42e3797da74e87fe7d9d7497e3b2028903010547522103089dc10c7ac6db54f91329af617333db388cead0c231f723379d1b99030b02dc21023add904f3d6dcf59ddb906b0dee23529b7ffb9ed50e5e86151926860221f0e7352ae2206023add904f3d6dcf59ddb906b0dee23529b7ffb9ed50e5e86151926860221f0e7310d90c6a4f000000800000008003000080220603089dc10c7ac6db54f91329af617333db388cead0c231f723379d1b99030b02dc10d90c6a4f00000080000000800200008000220203a9a4c37f5996d3aa25dbac6b570af0650394492942460b354753ed9eeca5877110d90c6a4f000000800000008004000080002202027f6399757d2eff55a136ad02c684b1838b6556e5f1b6b34282a94b6b5005109610d90c6a4f00000080000000800500008000", 281 //After adding sighash types to inputs 282 "UOPsbtHex4": "70736274ff01009a020000000258e87a21b56daf0c23be8e7070456c336f7cbaa5c8757924f545887bb2abdd750000000000ffffffff838d0427d0ec650a68aa46bb0b098aea4422c071b2ca78352a077959d07cea1d0100000000ffffffff0270aaf00800000000160014d85c2b71d0060b09c9886aeb815e50991dda124d00e1f5050000000016001400aea9a2e5f0f876a588df5546e8742d1d87008f00000000000100bb0200000001aad73931018bd25f84ae400b68848be09db706eac2ac18298babee71ab656f8b0000000048473044022058f6fc7c6a33e1b31548d481c826c015bd30135aad42cd67790dab66d2ad243b02204a1ced2604c6735b6393e5b41691dd78b00f0c5942fb9f751856faa938157dba01feffffff0280f0fa020000000017a9140fb9463421696b82c833af241c78c17ddbde493487d0f20a270100000017a91429ca74f8a08f81999428185c97b5d852e4063f618765000000010304010000000104475221029583bf39ae0a609747ad199addd634fa6108559d6c5cd39b4c2183f1ab96e07f2102dab61ff49a14db6a7d02b0cd1fbb78fc4b18312b5b4e54dae4dba2fbfef536d752ae2206029583bf39ae0a609747ad199addd634fa6108559d6c5cd39b4c2183f1ab96e07f10d90c6a4f000000800000008000000080220602dab61ff49a14db6a7d02b0cd1fbb78fc4b18312b5b4e54dae4dba2fbfef536d710d90c6a4f0000008000000080010000800001012000c2eb0b0000000017a914b7f5faf40e3d40a5a459b1db3535f2b72fa921e8870103040100000001042200208c2353173743b595dfb4a07b72ba8e42e3797da74e87fe7d9d7497e3b2028903010547522103089dc10c7ac6db54f91329af617333db388cead0c231f723379d1b99030b02dc21023add904f3d6dcf59ddb906b0dee23529b7ffb9ed50e5e86151926860221f0e7352ae2206023add904f3d6dcf59ddb906b0dee23529b7ffb9ed50e5e86151926860221f0e7310d90c6a4f000000800000008003000080220603089dc10c7ac6db54f91329af617333db388cead0c231f723379d1b99030b02dc10d90c6a4f00000080000000800200008000220203a9a4c37f5996d3aa25dbac6b570af0650394492942460b354753ed9eeca5877110d90c6a4f000000800000008004000080002202027f6399757d2eff55a136ad02c684b1838b6556e5f1b6b34282a94b6b5005109610d90c6a4f00000080000000800500008000", 283} 284 285// Just one example sanity check of B64 construction; after sighash appending above 286var CUTestB64Data = map[string]string{ 287 "UOPsbtB644": "cHNidP8BAJoCAAAAAljoeiG1ba8MI76OcHBFbDNvfLqlyHV5JPVFiHuyq911AAAAAAD/////g40EJ9DsZQpoqka7CwmK6kQiwHGyyng1Kgd5WdB86h0BAAAAAP////8CcKrwCAAAAAAWABTYXCtx0AYLCcmIauuBXlCZHdoSTQDh9QUAAAAAFgAUAK6pouXw+HaliN9VRuh0LR2HAI8AAAAAAAEAuwIAAAABqtc5MQGL0l+ErkALaISL4J23BurCrBgpi6vucatlb4sAAAAASEcwRAIgWPb8fGoz4bMVSNSByCbAFb0wE1qtQs1neQ2rZtKtJDsCIEoc7SYExnNbY5PltBaR3XiwDwxZQvufdRhW+qk4FX26Af7///8CgPD6AgAAAAAXqRQPuUY0IWlrgsgzryQceMF9295JNIfQ8gonAQAAABepFCnKdPigj4GZlCgYXJe12FLkBj9hh2UAAAABAwQBAAAAAQRHUiEClYO/Oa4KYJdHrRma3dY0+mEIVZ1sXNObTCGD8auW4H8hAtq2H/SaFNtqfQKwzR+7ePxLGDErW05U2uTbovv+9TbXUq4iBgKVg785rgpgl0etGZrd1jT6YQhVnWxc05tMIYPxq5bgfxDZDGpPAAAAgAAAAIAAAACAIgYC2rYf9JoU22p9ArDNH7t4/EsYMStbTlTa5Nui+/71NtcQ2QxqTwAAAIAAAACAAQAAgAABASAAwusLAAAAABepFLf1+vQOPUClpFmx2zU18rcvqSHohwEDBAEAAAABBCIAIIwjUxc3Q7WV37Sge3K6jkLjeX2nTof+fZ10l+OyAokDAQVHUiEDCJ3BDHrG21T5EymvYXMz2ziM6tDCMfcjN50bmQMLAtwhAjrdkE89bc9Z3bkGsN7iNSm3/7ntUOXoYVGSaGAiHw5zUq4iBgI63ZBPPW3PWd25BrDe4jUpt/+57VDl6GFRkmhgIh8OcxDZDGpPAAAAgAAAAIADAACAIgYDCJ3BDHrG21T5EymvYXMz2ziM6tDCMfcjN50bmQMLAtwQ2QxqTwAAAIAAAACAAgAAgAAiAgOppMN/WZbTqiXbrGtXCvBlA5RJKUJGCzVHU+2e7KWHcRDZDGpPAAAAgAAAAIAEAACAACICAn9jmXV9Lv9VoTatAsaEsYOLZVbl8bazQoKpS2tQBRCWENkMak8AAACAAAAAgAUAAIAA", 288} 289 290var CUTestAmountData = map[string]int64{ 291 "amount1": 149990000, 292 "amount2": 100000000, 293 "amount3": 200000000, 294} 295 296var CUTestIndexData = map[string]uint32{ 297 "index1": 0, 298 "index2": 1, 299} 300 301var CUMasterKeyFingerPrint = "d90c6a4f" 302 303var CUTestPathData = map[string][]uint32{ 304 "dpath1": {0 + 0x80000000, 0 + 0x80000000, 0 + 0x80000000}, 305 "dpath2": {0 + 0x80000000, 0 + 0x80000000, 1 + 0x80000000}, 306 "dpath3": {0 + 0x80000000, 0 + 0x80000000, 2 + 0x80000000}, 307 "dpath4": {0 + 0x80000000, 0 + 0x80000000, 3 + 0x80000000}, 308 "dpath5": {0 + 0x80000000, 0 + 0x80000000, 4 + 0x80000000}, 309 "dpath6": {0 + 0x80000000, 0 + 0x80000000, 5 + 0x80000000}, 310} 311 312var CUTestPubkeyData = map[string]string{ 313 "pub1": "029583bf39ae0a609747ad199addd634fa6108559d6c5cd39b4c2183f1ab96e07f", 314 "pub2": "02dab61ff49a14db6a7d02b0cd1fbb78fc4b18312b5b4e54dae4dba2fbfef536d7", 315 "pub3": "03089dc10c7ac6db54f91329af617333db388cead0c231f723379d1b99030b02dc", 316 "pub4": "023add904f3d6dcf59ddb906b0dee23529b7ffb9ed50e5e86151926860221f0e73", 317 "pub5": "03a9a4c37f5996d3aa25dbac6b570af0650394492942460b354753ed9eeca58771", 318 "pub6": "027f6399757d2eff55a136ad02c684b1838b6556e5f1b6b34282a94b6b50051096", 319} 320 321// =============================================================================== 322 323func TestPsbtCreator(t *testing.T) { 324 spkOut1, err := hex.DecodeString(CUTestHexData["scriptPubkey1"]) 325 if err != nil { 326 t.Fatalf("Error: %v", err) 327 } 328 spkOut2, err := hex.DecodeString(CUTestHexData["scriptPubkey2"]) 329 if err != nil { 330 t.Fatalf("Error: %v", err) 331 } 332 out1 := wire.NewTxOut(CUTestAmountData["amount1"], spkOut1) 333 out2 := wire.NewTxOut(CUTestAmountData["amount2"], spkOut2) 334 outputs := []*wire.TxOut{out1, out2} 335 hash1, err := chainhash.NewHashFromStr(CUTestHexData["txid1"]) 336 if err != nil { 337 t.Fatalf("Error: %v", err) 338 } 339 prevOut1 := wire.NewOutPoint(hash1, uint32(0)) 340 hash2, err := chainhash.NewHashFromStr(CUTestHexData["txid2"]) 341 if err != nil { 342 t.Fatalf("Error: %v", err) 343 } 344 prevOut2 := wire.NewOutPoint(hash2, uint32(1)) 345 inputs := []*wire.OutPoint{prevOut1, prevOut2} 346 347 // Check creation fails with invalid sequences: 348 nSequences := []uint32{wire.MaxTxInSequenceNum} 349 _, err = New(inputs, outputs, int32(3), uint32(0), nSequences) 350 if err == nil { 351 t.Fatalf("Did not error when creating transaction with " + 352 "invalid nSequences") 353 } 354 nSequences = append(nSequences, wire.MaxTxInSequenceNum) 355 356 // Check creation fails with invalid version 357 _, err = New(inputs, outputs, int32(0), uint32(0), nSequences) 358 if err == nil { 359 t.Fatalf("Did not error when creating transaction with " + 360 "invalid version (3)") 361 } 362 363 // Use valid data to create: 364 cPsbt, err := New(inputs, outputs, int32(2), uint32(0), nSequences) 365 var b bytes.Buffer 366 err = cPsbt.Serialize(&b) 367 if err != nil { 368 t.Fatalf("Unable to serialize created Psbt: %v", err) 369 } 370 if CUTestHexData["COPsbtHex"] != hex.EncodeToString(b.Bytes()) { 371 t.Fatalf("Failed to create expected psbt, instead got: %v", 372 hex.EncodeToString(b.Bytes())) 373 } 374 375 // Now simulate passing the created PSBT to an Updater 376 updater, err := NewUpdater(cPsbt) 377 if err != nil { 378 t.Fatalf("Unable to create Updater object") 379 } 380 tx := wire.NewMsgTx(2) 381 nonWitnessUtxoHex, err := hex.DecodeString( 382 CUTestHexData["NonWitnessUtxo"]) 383 if err != nil { 384 t.Fatalf("Unable to decode hex: %v", err) 385 } 386 err = tx.Deserialize(bytes.NewReader(nonWitnessUtxoHex)) 387 if err != nil { 388 t.Fatalf("Error deserializing transaction: %v", err) 389 } 390 witnessUtxoHex, err := hex.DecodeString( 391 CUTestHexData["WitnessUtxo"]) 392 if err != nil { 393 t.Fatalf("Unable to decode hex: %v", err) 394 } 395 txout := wire.TxOut{Value: CUTestAmountData["amount3"], 396 PkScript: witnessUtxoHex[9:]} 397 err = updater.AddInNonWitnessUtxo(tx, 0) 398 if err != nil { 399 t.Fatalf("Unable to add NonWitness Utxo to inputs: %v", err) 400 } 401 err = updater.AddInWitnessUtxo(&txout, 1) 402 if err != nil { 403 t.Fatalf("Unable to add Witness Utxo to inputs: %v", err) 404 } 405 406 b.Reset() 407 408 err = updater.Upsbt.Serialize(&b) 409 if err != nil { 410 t.Fatalf("Unable to serialize updated Psbt: %v", err) 411 } 412 if CUTestHexData["UOPsbtHex"] != hex.EncodeToString(b.Bytes()) { 413 t.Fatal("Failed to create valid updated PSBT after utxos") 414 } 415 input1RedeemScript, err := hex.DecodeString(CUTestHexData["Input1RedeemScript"]) 416 if err != nil { 417 t.Fatalf("Unable to decode hex: %v", err) 418 } 419 err = updater.AddInRedeemScript(input1RedeemScript, 0) 420 if err != nil { 421 t.Fatalf("Unable to add redeem script: %v", err) 422 } 423 input2RedeemScript, err := hex.DecodeString(CUTestHexData["Input2RedeemScript"]) 424 if err != nil { 425 t.Fatalf("Unable to decode hex: %v", err) 426 } 427 err = updater.AddInRedeemScript(input2RedeemScript, 1) 428 if err != nil { 429 t.Fatalf("Unable to add redeem script: %v", err) 430 } 431 input2WitnessScript, err := hex.DecodeString(CUTestHexData["Input2WitnessScript"]) 432 if err != nil { 433 t.Fatalf("Unable to decode hex: %v", err) 434 } 435 err = updater.AddInWitnessScript(input2WitnessScript, 1) 436 if err != nil { 437 t.Fatalf("Unable to add witness script: %v", err) 438 } 439 440 b.Reset() 441 err = updater.Upsbt.Serialize(&b) 442 if err != nil { 443 t.Fatalf("Unable to serialize updated Psbt: %v", err) 444 } 445 if CUTestHexData["UOPsbtHex2"] != hex.EncodeToString(b.Bytes()) { 446 t.Fatal("Failed to create valid updated PSBT after redeem scripts") 447 } 448 masterKey, err := hex.DecodeString(CUMasterKeyFingerPrint) 449 masterKeyInt := binary.LittleEndian.Uint32(masterKey) 450 if err != nil { 451 t.Fatalf("Unable to decode hex: %v", err) 452 } 453 input1Path1 := CUTestPathData["dpath1"] 454 input1Path2 := CUTestPathData["dpath2"] 455 input1Key1, err := hex.DecodeString(CUTestPubkeyData["pub1"]) 456 if err != nil { 457 t.Fatalf("Unable to decode hex: %v", err) 458 } 459 input1Key2, err := hex.DecodeString(CUTestPubkeyData["pub2"]) 460 if err != nil { 461 t.Fatalf("Unable to decode hex: %v", err) 462 } 463 err = updater.AddInBip32Derivation(masterKeyInt, input1Path1, input1Key1, 0) 464 if err != nil { 465 t.Fatal("Failed to add first key derivation for input 1") 466 } 467 err = updater.AddInBip32Derivation(masterKeyInt, input1Path2, input1Key2, 0) 468 if err != nil { 469 t.Fatal("Failed to add second key derivation for input 1") 470 } 471 input2Path1 := CUTestPathData["dpath3"] 472 input2Path2 := CUTestPathData["dpath4"] 473 input2Key1, err := hex.DecodeString(CUTestPubkeyData["pub3"]) 474 if err != nil { 475 t.Fatalf("Unable to decode hex: %v", err) 476 } 477 input2Key2, err := hex.DecodeString(CUTestPubkeyData["pub4"]) 478 if err != nil { 479 t.Fatalf("Unable to decode hex: %v", err) 480 } 481 482 // check invalid pubkeys are not accepted 483 borkedInput2Key1 := append([]byte{0xff}, input2Key1...) 484 err = updater.AddInBip32Derivation(masterKeyInt, input2Path1, 485 borkedInput2Key1, 1) 486 if err == nil { 487 t.Fatalf("Expected invalid pubkey, got: %v", err) 488 } 489 490 err = updater.AddInBip32Derivation(masterKeyInt, input2Path1, input2Key1, 1) 491 if err != nil { 492 t.Fatal("Failed to add first key derivation for input 2") 493 } 494 err = updater.AddInBip32Derivation(masterKeyInt, input2Path2, input2Key2, 1) 495 if err != nil { 496 t.Fatal("Failed to add second key derivation for input 2") 497 } 498 output1Key1, err := hex.DecodeString(CUTestPubkeyData["pub5"]) 499 if err != nil { 500 t.Fatalf("Unable to decode hex: %v", err) 501 } 502 output1Path := CUTestPathData["dpath5"] 503 504 // check invalid pubkeys are not accepted 505 borkedOutput1Key1 := append([]byte{0xab}, output1Key1[:13]...) 506 err = updater.AddOutBip32Derivation(masterKeyInt, output1Path, 507 borkedOutput1Key1, 0) 508 if err == nil { 509 t.Fatalf("Expected invalid pubkey, got: %v", err) 510 } 511 512 err = updater.AddOutBip32Derivation(masterKeyInt, output1Path, output1Key1, 0) 513 if err != nil { 514 t.Fatal("Failed to add key to first output") 515 } 516 output2Key1, err := hex.DecodeString(CUTestPubkeyData["pub6"]) 517 if err != nil { 518 t.Fatalf("Unable to decode hex: %v", err) 519 } 520 output2Path := CUTestPathData["dpath6"] 521 err = updater.AddOutBip32Derivation(masterKeyInt, output2Path, output2Key1, 1) 522 if err != nil { 523 t.Fatal("Failed to add key to second output") 524 } 525 526 b.Reset() 527 err = updater.Upsbt.Serialize(&b) 528 if err != nil { 529 t.Fatalf("Unable to serialize updated Psbt: %v", err) 530 } 531 if CUTestHexData["UOPsbtHex3"] != hex.EncodeToString(b.Bytes()) { 532 t.Fatal("Failed to create valid updated PSBT after BIP32 derivations") 533 } 534 err = updater.AddInSighashType(txscript.SigHashType(1), 0) 535 if err != nil { 536 t.Fatal("Failed to add sighash type to first input") 537 } 538 err = updater.AddInSighashType(txscript.SigHashType(1), 1) 539 if err != nil { 540 t.Fatal("Failed to add sighash type to second input") 541 } 542 543 b.Reset() 544 err = updater.Upsbt.Serialize(&b) 545 if err != nil { 546 t.Fatalf("Unable to serialize updated Psbt: %v", err) 547 } 548 if CUTestHexData["UOPsbtHex4"] != hex.EncodeToString(b.Bytes()) { 549 t.Fatal("Failed to create valid updated PSBT after sighash types") 550 } 551 b644, err := updater.Upsbt.B64Encode() 552 if err != nil { 553 t.Fatalf("Unable to B64Encode updated Psbt: %v", err) 554 } 555 if b644 != CUTestB64Data["UOPsbtB644"] { 556 t.Fatalf("Failed to base64 encode updated PSBT after sighash "+ 557 "types: %v", b644) 558 } 559} 560 561// Signing test data taken from 562// https://github.com/achow101/bitcoin/blob/020628e3a4e88e36647eaf92bac4b3552796ac6a/test/functional/data/rpc_psbt.json 563var signerPsbtData = map[string]string{ 564 "signer1Privkey1": "cP53pDbR5WtAD8dYAW9hhTjuvvTVaEiQBdrz9XPrgLBeRFiyCbQr", 565 "signer1Privkey2": "cR6SXDoyfQrcp4piaiHE97Rsgta9mNhGTen9XeonVgwsh4iSgw6d", 566 "signer1PsbtB64": "cHNidP8BAJoCAAAAAljoeiG1ba8MI76OcHBFbDNvfLqlyHV5JPVFiHuyq911AAAAAAD/////g40EJ9DsZQpoqka7CwmK6kQiwHGyyng1Kgd5WdB86h0BAAAAAP////8CcKrwCAAAAAAWABTYXCtx0AYLCcmIauuBXlCZHdoSTQDh9QUAAAAAFgAUAK6pouXw+HaliN9VRuh0LR2HAI8AAAAAAAEAuwIAAAABqtc5MQGL0l+ErkALaISL4J23BurCrBgpi6vucatlb4sAAAAASEcwRAIgWPb8fGoz4bMVSNSByCbAFb0wE1qtQs1neQ2rZtKtJDsCIEoc7SYExnNbY5PltBaR3XiwDwxZQvufdRhW+qk4FX26Af7///8CgPD6AgAAAAAXqRQPuUY0IWlrgsgzryQceMF9295JNIfQ8gonAQAAABepFCnKdPigj4GZlCgYXJe12FLkBj9hh2UAAAABBEdSIQKVg785rgpgl0etGZrd1jT6YQhVnWxc05tMIYPxq5bgfyEC2rYf9JoU22p9ArDNH7t4/EsYMStbTlTa5Nui+/71NtdSriIGApWDvzmuCmCXR60Zmt3WNPphCFWdbFzTm0whg/GrluB/ENkMak8AAACAAAAAgAAAAIAiBgLath/0mhTban0CsM0fu3j8SxgxK1tOVNrk26L7/vU21xDZDGpPAAAAgAAAAIABAACAAQMEAQAAAAABASAAwusLAAAAABepFLf1+vQOPUClpFmx2zU18rcvqSHohwEEIgAgjCNTFzdDtZXftKB7crqOQuN5fadOh/59nXSX47ICiQMBBUdSIQMIncEMesbbVPkTKa9hczPbOIzq0MIx9yM3nRuZAwsC3CECOt2QTz1tz1nduQaw3uI1Kbf/ue1Q5ehhUZJoYCIfDnNSriIGAjrdkE89bc9Z3bkGsN7iNSm3/7ntUOXoYVGSaGAiHw5zENkMak8AAACAAAAAgAMAAIAiBgMIncEMesbbVPkTKa9hczPbOIzq0MIx9yM3nRuZAwsC3BDZDGpPAAAAgAAAAIACAACAAQMEAQAAAAAiAgOppMN/WZbTqiXbrGtXCvBlA5RJKUJGCzVHU+2e7KWHcRDZDGpPAAAAgAAAAIAEAACAACICAn9jmXV9Lv9VoTatAsaEsYOLZVbl8bazQoKpS2tQBRCWENkMak8AAACAAAAAgAUAAIAA", 567 "signer1Result": "70736274ff01009a020000000258e87a21b56daf0c23be8e7070456c336f7cbaa5c8757924f545887bb2abdd750000000000ffffffff838d0427d0ec650a68aa46bb0b098aea4422c071b2ca78352a077959d07cea1d0100000000ffffffff0270aaf00800000000160014d85c2b71d0060b09c9886aeb815e50991dda124d00e1f5050000000016001400aea9a2e5f0f876a588df5546e8742d1d87008f00000000000100bb0200000001aad73931018bd25f84ae400b68848be09db706eac2ac18298babee71ab656f8b0000000048473044022058f6fc7c6a33e1b31548d481c826c015bd30135aad42cd67790dab66d2ad243b02204a1ced2604c6735b6393e5b41691dd78b00f0c5942fb9f751856faa938157dba01feffffff0280f0fa020000000017a9140fb9463421696b82c833af241c78c17ddbde493487d0f20a270100000017a91429ca74f8a08f81999428185c97b5d852e4063f6187650000002202029583bf39ae0a609747ad199addd634fa6108559d6c5cd39b4c2183f1ab96e07f473044022074018ad4180097b873323c0015720b3684cc8123891048e7dbcd9b55ad679c99022073d369b740e3eb53dcefa33823c8070514ca55a7dd9544f157c167913261118c01010304010000000104475221029583bf39ae0a609747ad199addd634fa6108559d6c5cd39b4c2183f1ab96e07f2102dab61ff49a14db6a7d02b0cd1fbb78fc4b18312b5b4e54dae4dba2fbfef536d752ae2206029583bf39ae0a609747ad199addd634fa6108559d6c5cd39b4c2183f1ab96e07f10d90c6a4f000000800000008000000080220602dab61ff49a14db6a7d02b0cd1fbb78fc4b18312b5b4e54dae4dba2fbfef536d710d90c6a4f0000008000000080010000800001012000c2eb0b0000000017a914b7f5faf40e3d40a5a459b1db3535f2b72fa921e887220203089dc10c7ac6db54f91329af617333db388cead0c231f723379d1b99030b02dc473044022062eb7a556107a7c73f45ac4ab5a1dddf6f7075fb1275969a7f383efff784bcb202200c05dbb7470dbf2f08557dd356c7325c1ed30913e996cd3840945db12228da5f010103040100000001042200208c2353173743b595dfb4a07b72ba8e42e3797da74e87fe7d9d7497e3b2028903010547522103089dc10c7ac6db54f91329af617333db388cead0c231f723379d1b99030b02dc21023add904f3d6dcf59ddb906b0dee23529b7ffb9ed50e5e86151926860221f0e7352ae2206023add904f3d6dcf59ddb906b0dee23529b7ffb9ed50e5e86151926860221f0e7310d90c6a4f000000800000008003000080220603089dc10c7ac6db54f91329af617333db388cead0c231f723379d1b99030b02dc10d90c6a4f00000080000000800200008000220203a9a4c37f5996d3aa25dbac6b570af0650394492942460b354753ed9eeca5877110d90c6a4f000000800000008004000080002202027f6399757d2eff55a136ad02c684b1838b6556e5f1b6b34282a94b6b5005109610d90c6a4f00000080000000800500008000", 568 "signer2Privkey1": "cT7J9YpCwY3AVRFSjN6ukeEeWY6mhpbJPxRaDaP5QTdygQRxP9Au", 569 "signer2Privkey2": "cNBc3SWUip9PPm1GjRoLEJT6T41iNzCYtD7qro84FMnM5zEqeJsE", 570 "signer2Psbt": "70736274ff01009a020000000258e87a21b56daf0c23be8e7070456c336f7cbaa5c8757924f545887bb2abdd750000000000ffffffff838d0427d0ec650a68aa46bb0b098aea4422c071b2ca78352a077959d07cea1d0100000000ffffffff0270aaf00800000000160014d85c2b71d0060b09c9886aeb815e50991dda124d00e1f5050000000016001400aea9a2e5f0f876a588df5546e8742d1d87008f00000000000100bb0200000001aad73931018bd25f84ae400b68848be09db706eac2ac18298babee71ab656f8b0000000048473044022058f6fc7c6a33e1b31548d481c826c015bd30135aad42cd67790dab66d2ad243b02204a1ced2604c6735b6393e5b41691dd78b00f0c5942fb9f751856faa938157dba01feffffff0280f0fa020000000017a9140fb9463421696b82c833af241c78c17ddbde493487d0f20a270100000017a91429ca74f8a08f81999428185c97b5d852e4063f6187650000000104475221029583bf39ae0a609747ad199addd634fa6108559d6c5cd39b4c2183f1ab96e07f2102dab61ff49a14db6a7d02b0cd1fbb78fc4b18312b5b4e54dae4dba2fbfef536d752ae2206029583bf39ae0a609747ad199addd634fa6108559d6c5cd39b4c2183f1ab96e07f10d90c6a4f000000800000008000000080220602dab61ff49a14db6a7d02b0cd1fbb78fc4b18312b5b4e54dae4dba2fbfef536d710d90c6a4f000000800000008001000080010304010000000001012000c2eb0b0000000017a914b7f5faf40e3d40a5a459b1db3535f2b72fa921e88701042200208c2353173743b595dfb4a07b72ba8e42e3797da74e87fe7d9d7497e3b2028903010547522103089dc10c7ac6db54f91329af617333db388cead0c231f723379d1b99030b02dc21023add904f3d6dcf59ddb906b0dee23529b7ffb9ed50e5e86151926860221f0e7352ae2206023add904f3d6dcf59ddb906b0dee23529b7ffb9ed50e5e86151926860221f0e7310d90c6a4f000000800000008003000080220603089dc10c7ac6db54f91329af617333db388cead0c231f723379d1b99030b02dc10d90c6a4f0000008000000080020000800103040100000000220203a9a4c37f5996d3aa25dbac6b570af0650394492942460b354753ed9eeca5877110d90c6a4f000000800000008004000080002202027f6399757d2eff55a136ad02c684b1838b6556e5f1b6b34282a94b6b5005109610d90c6a4f00000080000000800500008000", 571 "signer2Result": "70736274ff01009a020000000258e87a21b56daf0c23be8e7070456c336f7cbaa5c8757924f545887bb2abdd750000000000ffffffff838d0427d0ec650a68aa46bb0b098aea4422c071b2ca78352a077959d07cea1d0100000000ffffffff0270aaf00800000000160014d85c2b71d0060b09c9886aeb815e50991dda124d00e1f5050000000016001400aea9a2e5f0f876a588df5546e8742d1d87008f00000000000100bb0200000001aad73931018bd25f84ae400b68848be09db706eac2ac18298babee71ab656f8b0000000048473044022058f6fc7c6a33e1b31548d481c826c015bd30135aad42cd67790dab66d2ad243b02204a1ced2604c6735b6393e5b41691dd78b00f0c5942fb9f751856faa938157dba01feffffff0280f0fa020000000017a9140fb9463421696b82c833af241c78c17ddbde493487d0f20a270100000017a91429ca74f8a08f81999428185c97b5d852e4063f618765000000220202dab61ff49a14db6a7d02b0cd1fbb78fc4b18312b5b4e54dae4dba2fbfef536d7483045022100f61038b308dc1da865a34852746f015772934208c6d24454393cd99bdf2217770220056e675a675a6d0a02b85b14e5e29074d8a25a9b5760bea2816f661910a006ea01010304010000000104475221029583bf39ae0a609747ad199addd634fa6108559d6c5cd39b4c2183f1ab96e07f2102dab61ff49a14db6a7d02b0cd1fbb78fc4b18312b5b4e54dae4dba2fbfef536d752ae2206029583bf39ae0a609747ad199addd634fa6108559d6c5cd39b4c2183f1ab96e07f10d90c6a4f000000800000008000000080220602dab61ff49a14db6a7d02b0cd1fbb78fc4b18312b5b4e54dae4dba2fbfef536d710d90c6a4f0000008000000080010000800001012000c2eb0b0000000017a914b7f5faf40e3d40a5a459b1db3535f2b72fa921e8872202023add904f3d6dcf59ddb906b0dee23529b7ffb9ed50e5e86151926860221f0e73473044022065f45ba5998b59a27ffe1a7bed016af1f1f90d54b3aa8f7450aa5f56a25103bd02207f724703ad1edb96680b284b56d4ffcb88f7fb759eabbe08aa30f29b851383d2010103040100000001042200208c2353173743b595dfb4a07b72ba8e42e3797da74e87fe7d9d7497e3b2028903010547522103089dc10c7ac6db54f91329af617333db388cead0c231f723379d1b99030b02dc21023add904f3d6dcf59ddb906b0dee23529b7ffb9ed50e5e86151926860221f0e7352ae2206023add904f3d6dcf59ddb906b0dee23529b7ffb9ed50e5e86151926860221f0e7310d90c6a4f000000800000008003000080220603089dc10c7ac6db54f91329af617333db388cead0c231f723379d1b99030b02dc10d90c6a4f00000080000000800200008000220203a9a4c37f5996d3aa25dbac6b570af0650394492942460b354753ed9eeca5877110d90c6a4f000000800000008004000080002202027f6399757d2eff55a136ad02c684b1838b6556e5f1b6b34282a94b6b5005109610d90c6a4f00000080000000800500008000", 572} 573 574func TestPsbtSigner(t *testing.T) { 575 psbt1, err := NewFromRawBytes( 576 bytes.NewReader([]byte(signerPsbtData["signer1PsbtB64"])), 577 true, 578 ) 579 if err != nil { 580 t.Fatalf("Failed to parse PSBT: %v", err) 581 } 582 psbtUpdater1 := Updater{ 583 Upsbt: psbt1, 584 } 585 sig1, err := hex.DecodeString("3044022074018ad4180097b873323c0015720b3684cc8123891048e7dbcd9b55ad679c99022073d369b740e3eb53dcefa33823c8070514ca55a7dd9544f157c167913261118c01") 586 pub1, err := hex.DecodeString("029583bf39ae0a609747ad199addd634fa6108559d6c5cd39b4c2183f1ab96e07f") 587 res, err := psbtUpdater1.Sign(0, sig1, pub1, nil, nil) 588 if err != nil || res != 0 { 589 t.Fatalf("Error from adding signatures: %v %v", err, res) 590 } 591 sig2, err := hex.DecodeString("3044022062eb7a556107a7c73f45ac4ab5a1dddf6f7075fb1275969a7f383efff784bcb202200c05dbb7470dbf2f08557dd356c7325c1ed30913e996cd3840945db12228da5f01") 592 pub2, err := hex.DecodeString("03089dc10c7ac6db54f91329af617333db388cead0c231f723379d1b99030b02dc") 593 res, err = psbtUpdater1.Sign(1, sig2, pub2, nil, nil) 594 if err != nil || res != 0 { 595 t.Fatalf("Error from adding signatures: %v %v", err, res) 596 } 597 signer1Result, err := hex.DecodeString(signerPsbtData["signer1Result"]) 598 if err != nil { 599 t.Fatalf("Unable to decode hex: %v", err) 600 } 601 602 var b bytes.Buffer 603 err = psbtUpdater1.Upsbt.Serialize(&b) 604 if err != nil { 605 t.Fatalf("Unable to serialize updated Psbt: %v", err) 606 } 607 if !bytes.Equal(b.Bytes(), signer1Result) { 608 t.Fatalf("Failed to add signatures correctly") 609 } 610} 611 612// Finalizer-extractor test 613 614var finalizerPsbtData = map[string]string{ 615 "finalizeb64": "cHNidP8BAJoCAAAAAljoeiG1ba8MI76OcHBFbDNvfLqlyHV5JPVFiHuyq911AAAAAAD/////g40EJ9DsZQpoqka7CwmK6kQiwHGyyng1Kgd5WdB86h0BAAAAAP////8CcKrwCAAAAAAWABTYXCtx0AYLCcmIauuBXlCZHdoSTQDh9QUAAAAAFgAUAK6pouXw+HaliN9VRuh0LR2HAI8AAAAAAAEAuwIAAAABqtc5MQGL0l+ErkALaISL4J23BurCrBgpi6vucatlb4sAAAAASEcwRAIgWPb8fGoz4bMVSNSByCbAFb0wE1qtQs1neQ2rZtKtJDsCIEoc7SYExnNbY5PltBaR3XiwDwxZQvufdRhW+qk4FX26Af7///8CgPD6AgAAAAAXqRQPuUY0IWlrgsgzryQceMF9295JNIfQ8gonAQAAABepFCnKdPigj4GZlCgYXJe12FLkBj9hh2UAAAAiAgKVg785rgpgl0etGZrd1jT6YQhVnWxc05tMIYPxq5bgf0cwRAIgdAGK1BgAl7hzMjwAFXILNoTMgSOJEEjn282bVa1nnJkCIHPTabdA4+tT3O+jOCPIBwUUylWn3ZVE8VfBZ5EyYRGMASICAtq2H/SaFNtqfQKwzR+7ePxLGDErW05U2uTbovv+9TbXSDBFAiEA9hA4swjcHahlo0hSdG8BV3KTQgjG0kRUOTzZm98iF3cCIAVuZ1pnWm0KArhbFOXikHTYolqbV2C+ooFvZhkQoAbqAQEDBAEAAAABBEdSIQKVg785rgpgl0etGZrd1jT6YQhVnWxc05tMIYPxq5bgfyEC2rYf9JoU22p9ArDNH7t4/EsYMStbTlTa5Nui+/71NtdSriIGApWDvzmuCmCXR60Zmt3WNPphCFWdbFzTm0whg/GrluB/ENkMak8AAACAAAAAgAAAAIAiBgLath/0mhTban0CsM0fu3j8SxgxK1tOVNrk26L7/vU21xDZDGpPAAAAgAAAAIABAACAAAEBIADC6wsAAAAAF6kUt/X69A49QKWkWbHbNTXyty+pIeiHIgIDCJ3BDHrG21T5EymvYXMz2ziM6tDCMfcjN50bmQMLAtxHMEQCIGLrelVhB6fHP0WsSrWh3d9vcHX7EnWWmn84Pv/3hLyyAiAMBdu3Rw2/LwhVfdNWxzJcHtMJE+mWzThAlF2xIijaXwEiAgI63ZBPPW3PWd25BrDe4jUpt/+57VDl6GFRkmhgIh8Oc0cwRAIgZfRbpZmLWaJ//hp77QFq8fH5DVSzqo90UKpfVqJRA70CIH9yRwOtHtuWaAsoS1bU/8uI9/t1nqu+CKow8puFE4PSAQEDBAEAAAABBCIAIIwjUxc3Q7WV37Sge3K6jkLjeX2nTof+fZ10l+OyAokDAQVHUiEDCJ3BDHrG21T5EymvYXMz2ziM6tDCMfcjN50bmQMLAtwhAjrdkE89bc9Z3bkGsN7iNSm3/7ntUOXoYVGSaGAiHw5zUq4iBgI63ZBPPW3PWd25BrDe4jUpt/+57VDl6GFRkmhgIh8OcxDZDGpPAAAAgAAAAIADAACAIgYDCJ3BDHrG21T5EymvYXMz2ziM6tDCMfcjN50bmQMLAtwQ2QxqTwAAAIAAAACAAgAAgAAiAgOppMN/WZbTqiXbrGtXCvBlA5RJKUJGCzVHU+2e7KWHcRDZDGpPAAAAgAAAAIAEAACAACICAn9jmXV9Lv9VoTatAsaEsYOLZVbl8bazQoKpS2tQBRCWENkMak8AAACAAAAAgAUAAIAA", 616 "finalize": "70736274ff01009a020000000258e87a21b56daf0c23be8e7070456c336f7cbaa5c8757924f545887bb2abdd750000000000ffffffff838d0427d0ec650a68aa46bb0b098aea4422c071b2ca78352a077959d07cea1d0100000000ffffffff0270aaf00800000000160014d85c2b71d0060b09c9886aeb815e50991dda124d00e1f5050000000016001400aea9a2e5f0f876a588df5546e8742d1d87008f00000000000100bb0200000001aad73931018bd25f84ae400b68848be09db706eac2ac18298babee71ab656f8b0000000048473044022058f6fc7c6a33e1b31548d481c826c015bd30135aad42cd67790dab66d2ad243b02204a1ced2604c6735b6393e5b41691dd78b00f0c5942fb9f751856faa938157dba01feffffff0280f0fa020000000017a9140fb9463421696b82c833af241c78c17ddbde493487d0f20a270100000017a91429ca74f8a08f81999428185c97b5d852e4063f6187650000002202029583bf39ae0a609747ad199addd634fa6108559d6c5cd39b4c2183f1ab96e07f473044022074018ad4180097b873323c0015720b3684cc8123891048e7dbcd9b55ad679c99022073d369b740e3eb53dcefa33823c8070514ca55a7dd9544f157c167913261118c01220202dab61ff49a14db6a7d02b0cd1fbb78fc4b18312b5b4e54dae4dba2fbfef536d7483045022100f61038b308dc1da865a34852746f015772934208c6d24454393cd99bdf2217770220056e675a675a6d0a02b85b14e5e29074d8a25a9b5760bea2816f661910a006ea01010304010000000104475221029583bf39ae0a609747ad199addd634fa6108559d6c5cd39b4c2183f1ab96e07f2102dab61ff49a14db6a7d02b0cd1fbb78fc4b18312b5b4e54dae4dba2fbfef536d752ae2206029583bf39ae0a609747ad199addd634fa6108559d6c5cd39b4c2183f1ab96e07f10d90c6a4f000000800000008000000080220602dab61ff49a14db6a7d02b0cd1fbb78fc4b18312b5b4e54dae4dba2fbfef536d710d90c6a4f0000008000000080010000800001012000c2eb0b0000000017a914b7f5faf40e3d40a5a459b1db3535f2b72fa921e887220203089dc10c7ac6db54f91329af617333db388cead0c231f723379d1b99030b02dc473044022062eb7a556107a7c73f45ac4ab5a1dddf6f7075fb1275969a7f383efff784bcb202200c05dbb7470dbf2f08557dd356c7325c1ed30913e996cd3840945db12228da5f012202023add904f3d6dcf59ddb906b0dee23529b7ffb9ed50e5e86151926860221f0e73473044022065f45ba5998b59a27ffe1a7bed016af1f1f90d54b3aa8f7450aa5f56a25103bd02207f724703ad1edb96680b284b56d4ffcb88f7fb759eabbe08aa30f29b851383d2010103040100000001042200208c2353173743b595dfb4a07b72ba8e42e3797da74e87fe7d9d7497e3b2028903010547522103089dc10c7ac6db54f91329af617333db388cead0c231f723379d1b99030b02dc21023add904f3d6dcf59ddb906b0dee23529b7ffb9ed50e5e86151926860221f0e7352ae2206023add904f3d6dcf59ddb906b0dee23529b7ffb9ed50e5e86151926860221f0e7310d90c6a4f000000800000008003000080220603089dc10c7ac6db54f91329af617333db388cead0c231f723379d1b99030b02dc10d90c6a4f00000080000000800200008000220203a9a4c37f5996d3aa25dbac6b570af0650394492942460b354753ed9eeca5877110d90c6a4f000000800000008004000080002202027f6399757d2eff55a136ad02c684b1838b6556e5f1b6b34282a94b6b5005109610d90c6a4f00000080000000800500008000", 617 "resultb64": "cHNidP8BAJoCAAAAAljoeiG1ba8MI76OcHBFbDNvfLqlyHV5JPVFiHuyq911AAAAAAD/////g40EJ9DsZQpoqka7CwmK6kQiwHGyyng1Kgd5WdB86h0BAAAAAP////8CcKrwCAAAAAAWABTYXCtx0AYLCcmIauuBXlCZHdoSTQDh9QUAAAAAFgAUAK6pouXw+HaliN9VRuh0LR2HAI8AAAAAAAEAuwIAAAABqtc5MQGL0l+ErkALaISL4J23BurCrBgpi6vucatlb4sAAAAASEcwRAIgWPb8fGoz4bMVSNSByCbAFb0wE1qtQs1neQ2rZtKtJDsCIEoc7SYExnNbY5PltBaR3XiwDwxZQvufdRhW+qk4FX26Af7///8CgPD6AgAAAAAXqRQPuUY0IWlrgsgzryQceMF9295JNIfQ8gonAQAAABepFCnKdPigj4GZlCgYXJe12FLkBj9hh2UAAAABB9oARzBEAiB0AYrUGACXuHMyPAAVcgs2hMyBI4kQSOfbzZtVrWecmQIgc9Npt0Dj61Pc76M4I8gHBRTKVafdlUTxV8FnkTJhEYwBSDBFAiEA9hA4swjcHahlo0hSdG8BV3KTQgjG0kRUOTzZm98iF3cCIAVuZ1pnWm0KArhbFOXikHTYolqbV2C+ooFvZhkQoAbqAUdSIQKVg785rgpgl0etGZrd1jT6YQhVnWxc05tMIYPxq5bgfyEC2rYf9JoU22p9ArDNH7t4/EsYMStbTlTa5Nui+/71NtdSrgABASAAwusLAAAAABepFLf1+vQOPUClpFmx2zU18rcvqSHohwEHIyIAIIwjUxc3Q7WV37Sge3K6jkLjeX2nTof+fZ10l+OyAokDAQjaBABHMEQCIGLrelVhB6fHP0WsSrWh3d9vcHX7EnWWmn84Pv/3hLyyAiAMBdu3Rw2/LwhVfdNWxzJcHtMJE+mWzThAlF2xIijaXwFHMEQCIGX0W6WZi1mif/4ae+0BavHx+Q1Us6qPdFCqX1aiUQO9AiB/ckcDrR7blmgLKEtW1P/LiPf7dZ6rvgiqMPKbhROD0gFHUiEDCJ3BDHrG21T5EymvYXMz2ziM6tDCMfcjN50bmQMLAtwhAjrdkE89bc9Z3bkGsN7iNSm3/7ntUOXoYVGSaGAiHw5zUq4AIgIDqaTDf1mW06ol26xrVwrwZQOUSSlCRgs1R1Ptnuylh3EQ2QxqTwAAAIAAAACABAAAgAAiAgJ/Y5l1fS7/VaE2rQLGhLGDi2VW5fG2s0KCqUtrUAUQlhDZDGpPAAAAgAAAAIAFAACAAA==", 618 "result": "70736274ff01009a020000000258e87a21b56daf0c23be8e7070456c336f7cbaa5c8757924f545887bb2abdd750000000000ffffffff838d0427d0ec650a68aa46bb0b098aea4422c071b2ca78352a077959d07cea1d0100000000ffffffff0270aaf00800000000160014d85c2b71d0060b09c9886aeb815e50991dda124d00e1f5050000000016001400aea9a2e5f0f876a588df5546e8742d1d87008f00000000000100bb0200000001aad73931018bd25f84ae400b68848be09db706eac2ac18298babee71ab656f8b0000000048473044022058f6fc7c6a33e1b31548d481c826c015bd30135aad42cd67790dab66d2ad243b02204a1ced2604c6735b6393e5b41691dd78b00f0c5942fb9f751856faa938157dba01feffffff0280f0fa020000000017a9140fb9463421696b82c833af241c78c17ddbde493487d0f20a270100000017a91429ca74f8a08f81999428185c97b5d852e4063f6187650000000107da00473044022074018ad4180097b873323c0015720b3684cc8123891048e7dbcd9b55ad679c99022073d369b740e3eb53dcefa33823c8070514ca55a7dd9544f157c167913261118c01483045022100f61038b308dc1da865a34852746f015772934208c6d24454393cd99bdf2217770220056e675a675a6d0a02b85b14e5e29074d8a25a9b5760bea2816f661910a006ea01475221029583bf39ae0a609747ad199addd634fa6108559d6c5cd39b4c2183f1ab96e07f2102dab61ff49a14db6a7d02b0cd1fbb78fc4b18312b5b4e54dae4dba2fbfef536d752ae0001012000c2eb0b0000000017a914b7f5faf40e3d40a5a459b1db3535f2b72fa921e8870107232200208c2353173743b595dfb4a07b72ba8e42e3797da74e87fe7d9d7497e3b20289030108da0400473044022062eb7a556107a7c73f45ac4ab5a1dddf6f7075fb1275969a7f383efff784bcb202200c05dbb7470dbf2f08557dd356c7325c1ed30913e996cd3840945db12228da5f01473044022065f45ba5998b59a27ffe1a7bed016af1f1f90d54b3aa8f7450aa5f56a25103bd02207f724703ad1edb96680b284b56d4ffcb88f7fb759eabbe08aa30f29b851383d20147522103089dc10c7ac6db54f91329af617333db388cead0c231f723379d1b99030b02dc21023add904f3d6dcf59ddb906b0dee23529b7ffb9ed50e5e86151926860221f0e7352ae00220203a9a4c37f5996d3aa25dbac6b570af0650394492942460b354753ed9eeca5877110d90c6a4f000000800000008004000080002202027f6399757d2eff55a136ad02c684b1838b6556e5f1b6b34282a94b6b5005109610d90c6a4f00000080000000800500008000", 619 "network": "0200000000010258e87a21b56daf0c23be8e7070456c336f7cbaa5c8757924f545887bb2abdd7500000000da00473044022074018ad4180097b873323c0015720b3684cc8123891048e7dbcd9b55ad679c99022073d369b740e3eb53dcefa33823c8070514ca55a7dd9544f157c167913261118c01483045022100f61038b308dc1da865a34852746f015772934208c6d24454393cd99bdf2217770220056e675a675a6d0a02b85b14e5e29074d8a25a9b5760bea2816f661910a006ea01475221029583bf39ae0a609747ad199addd634fa6108559d6c5cd39b4c2183f1ab96e07f2102dab61ff49a14db6a7d02b0cd1fbb78fc4b18312b5b4e54dae4dba2fbfef536d752aeffffffff838d0427d0ec650a68aa46bb0b098aea4422c071b2ca78352a077959d07cea1d01000000232200208c2353173743b595dfb4a07b72ba8e42e3797da74e87fe7d9d7497e3b2028903ffffffff0270aaf00800000000160014d85c2b71d0060b09c9886aeb815e50991dda124d00e1f5050000000016001400aea9a2e5f0f876a588df5546e8742d1d87008f000400473044022062eb7a556107a7c73f45ac4ab5a1dddf6f7075fb1275969a7f383efff784bcb202200c05dbb7470dbf2f08557dd356c7325c1ed30913e996cd3840945db12228da5f01473044022065f45ba5998b59a27ffe1a7bed016af1f1f90d54b3aa8f7450aa5f56a25103bd02207f724703ad1edb96680b284b56d4ffcb88f7fb759eabbe08aa30f29b851383d20147522103089dc10c7ac6db54f91329af617333db388cead0c231f723379d1b99030b02dc21023add904f3d6dcf59ddb906b0dee23529b7ffb9ed50e5e86151926860221f0e7352ae00000000", 620 "twoOfThree": "70736274ff01005e01000000019a5fdb3c36f2168ea34a031857863c63bb776fd8a8a9149efd7341dfaf81c9970000000000ffffffff01e013a8040000000022002001c3a65ccfa5b39e31e6bafa504446200b9c88c58b4f21eb7e18412aff154e3f000000000001012bc817a80400000000220020114c9ab91ea00eb3e81a7aa4d0d8f1bc6bd8761f8f00dbccb38060dc2b9fdd5522020242ecd19afda551d58f496c17e3f51df4488089df4caafac3285ed3b9c590f6a847304402207c6ab50f421c59621323460aaf0f731a1b90ca76eddc635aed40e4d2fc86f97e02201b3f8fe931f1f94fde249e2b5b4dbfaff2f9df66dd97c6b518ffa746a4390bd1012202039f0acfe5a292aafc5331f18f6360a3cc53d645ebf0cc7f0509630b22b5d9f547473044022075329343e01033ebe5a22ea6eecf6361feca58752716bdc2260d7f449360a0810220299740ed32f694acc5f99d80c988bb270a030f63947f775382daf4669b272da0010103040100000001056952210242ecd19afda551d58f496c17e3f51df4488089df4caafac3285ed3b9c590f6a821035a654524d301dd0265c2370225a6837298b8ca2099085568cc61a8491287b63921039f0acfe5a292aafc5331f18f6360a3cc53d645ebf0cc7f0509630b22b5d9f54753ae22060242ecd19afda551d58f496c17e3f51df4488089df4caafac3285ed3b9c590f6a818d5f7375b2c000080000000800000008000000000010000002206035a654524d301dd0265c2370225a6837298b8ca2099085568cc61a8491287b63918e2314cf32c000080000000800000008000000000010000002206039f0acfe5a292aafc5331f18f6360a3cc53d645ebf0cc7f0509630b22b5d9f54718e524a1ce2c000080000000800000008000000000010000000000", 621} 622 623func TestFinalize2of3(t *testing.T) { 624 b, err := hex.DecodeString(finalizerPsbtData["twoOfThree"]) 625 if err != nil { 626 t.Fatalf("Error decoding hex: %v", err) 627 } 628 p, err := NewFromRawBytes(bytes.NewReader(b), false) 629 if p.IsComplete() { 630 t.Fatalf("Psbt is complete") 631 } 632 err = MaybeFinalizeAll(p) 633 if err != nil { 634 t.Fatalf("Error in MaybeFinalizeAll: %v", err) 635 } 636 if !p.IsComplete() { 637 t.Fatalf("Psbt is not complete") 638 } 639} 640 641func TestPsbtExtractor(t *testing.T) { 642 rawToFinalize, err := base64.StdEncoding.DecodeString( 643 finalizerPsbtData["finalizeb64"], 644 ) 645 if err != nil { 646 t.Fatalf("Error decoding b64: %v", err) 647 } 648 649 psbt1, err := NewFromRawBytes( 650 bytes.NewReader(rawToFinalize), false, 651 ) 652 if err != nil { 653 t.Fatalf("Failed to parse PSBT: %v", err) 654 } 655 656 for i := range psbt1.Inputs { 657 err = Finalize(psbt1, i) 658 if err != nil { 659 t.Fatalf("Error from finalizing PSBT: %v", err) 660 } 661 } 662 663 finalizer1Result, err := base64.StdEncoding.DecodeString( 664 finalizerPsbtData["resultb64"], 665 ) 666 if err != nil { 667 t.Fatalf("Unable to decode b64: %v", err) 668 } 669 finalToNetworkExpected, err := hex.DecodeString(finalizerPsbtData["network"]) 670 if err != nil { 671 t.Fatalf("Unable to decode hex: %v", err) 672 } 673 tx, err := Extract(psbt1) 674 if err != nil { 675 t.Fatalf("Failed to extract: %v", err) 676 } 677 var resultToNetwork bytes.Buffer 678 if err := tx.Serialize(&resultToNetwork); err != nil { 679 t.Fatalf("unable to serialize: %v", err) 680 } 681 682 var b bytes.Buffer 683 err = psbt1.Serialize(&b) 684 if err != nil { 685 t.Fatalf("Unable to serialize updated Psbt: %v", err) 686 } 687 if !bytes.Equal(b.Bytes(), finalizer1Result) { 688 t.Fatalf("Failed to finalize transaction: expected %x, "+ 689 "got %x", finalizer1Result, b.Bytes()) 690 } 691 if !bytes.Equal(finalToNetworkExpected, resultToNetwork.Bytes()) { 692 t.Fatalf("Failed to network serialize transaction: %x", b.Bytes()) 693 } 694} 695 696func TestImportFromCore1(t *testing.T) { 697 // This example #1 was created manually using Bitcoin Core 0.17 regtest. 698 // It contains two inputs, one p2wkh and one p2pkh (non-witness). 699 // We take the created PSBT as input, then add the fields for each input 700 // separately, then finalize and extract, and compare with the network 701 // serialized tx output from Core. 702 imported := "cHNidP8BAJwCAAAAAjaoF6eKeGsPiDQxxqqhFDfHWjBtZzRqmaZmvyCVWZ5JAQAAAAD/////RhypNiFfnQSMNpo0SGsgIvDOyMQFAYEHZXD5jp4kCrUAAAAAAP////8CgCcSjAAAAAAXqRQFWy8ScSkkhlGMwfOnx15YwRzApofwX5MDAAAAABepFAt4TyLfGnL9QY6GLYHbpSQj+QclhwAAAAAAAAAAAA==" 703 psbt1, err := NewFromRawBytes(bytes.NewReader([]byte(imported)), true) 704 if err != nil { 705 t.Fatalf("Failed to parse PSBT: %v", err) 706 } 707 708 // update with the first input's utxo (witness) and the second input's utxo 709 // (non-witness) 710 fundingTxInput1Hex := "02000000014f2cbac7d7691fafca30313097d79be9e78aa6670752fcb1fc15508e77586efb000000004847304402201b5568d7cab977ae0892840b779d84e36d62e42fd93b95e648aaebeacd2577d602201d2ebda2b0cddfa0c1a71d3cbcb602e7c9c860a41ed8b4d18d40c92ccbe92aed01feffffff028c636f91000000001600147447b6d7e6193499565779c8eb5184fcfdfee6ef00879303000000001600149e88f2828a074ebf64af23c2168d1816258311d72d010000" 711 fundingTxInput2Hex := "020000000001012f03f70c673d83d65da0e8d0db3867b3e7d7bfbd34fd6be65892042e57576eb00000000000feffffff028027128c000000001976a91485780899b61a5506f342bd67a2f635181f50c8b788acb8032c040000000017a914e2e3d32d42d6f043cab39708a6073301df5039db8702473044022047ae396fd8aba8f67482ad16e315fe680db585c1ac6422ffb18dacd9cf5bac350220321176fd6157ef51d9eae9230b0b5bd7dd29bb6247a879189e6aaa8091f3020201210368081f7ff37dfadbed407eba17b232f959e41e6ac78741192c805ebf80d487852f010000" 712 fundingTxInput1Bytes, err := hex.DecodeString(fundingTxInput1Hex) 713 if err != nil { 714 t.Fatalf("Unable to decode hex: %v", err) 715 } 716 txFund1 := wire.NewMsgTx(2) 717 err = txFund1.Deserialize(bytes.NewReader(fundingTxInput1Bytes)) 718 if err != nil { 719 t.Fatalf("Error deserializing transaction: %v", err) 720 } 721 // First input is witness, take correct output: 722 txFund1Out := txFund1.TxOut[1] 723 724 fundingTxInput2Bytes, err := hex.DecodeString(fundingTxInput2Hex) 725 if err != nil { 726 t.Fatalf("Unable to decode hex: %v", err) 727 } 728 txFund2 := wire.NewMsgTx(2) 729 err = txFund2.Deserialize(bytes.NewReader(fundingTxInput2Bytes)) 730 if err != nil { 731 t.Fatalf("Error deserializing transaction: %v", err) 732 } 733 psbtupdater1 := Updater{Upsbt: psbt1} 734 psbtupdater1.AddInWitnessUtxo(txFund1Out, 0) 735 err = psbtupdater1.AddInNonWitnessUtxo(txFund2, 1) 736 if err != nil { 737 t.Fatalf("Error inserting non-witness utxo: %v", err) 738 } 739 740 // Signing was done with Core; we manually insert the relevant input 741 // entries here. 742 sig1Hex := "304402200da03ac9890f5d724c42c83c2a62844c08425a274f1a5bca50dcde4126eb20dd02205278897b65cb8e390a0868c9582133c7157b2ad3e81c1c70d8fbd65f51a5658b01" 743 sig1, err := hex.DecodeString(sig1Hex) 744 if err != nil { 745 t.Fatalf("Unable to decode hex: %v", err) 746 } 747 pub1Hex := "024d6b24f372dd4551277c8df4ecc0655101e11c22894c8e05a3468409c865a72c" 748 pub1, err := hex.DecodeString(pub1Hex) 749 if err != nil { 750 t.Fatalf("Unable to decode hex: %v", err) 751 } 752 753 // Check that invalid pubkeys are not accepted. 754 pubInvalid := append(pub1, 0x00) 755 756 res, err := psbtupdater1.Sign(0, sig1, pubInvalid, nil, nil) 757 if err == nil { 758 t.Fatalf("Incorrectly accepted invalid pubkey: %v", 759 pubInvalid) 760 } 761 762 res, err = psbtupdater1.Sign(0, sig1, pub1, nil, nil) 763 if err != nil || res != 0 { 764 t.Fatalf("Error from adding signatures: %v %v", err, res) 765 } 766 767 sig2Hex := "3044022014eb9c4858f71c9f280bc68402aa742a5187f54c56c8eb07c902eb1eb5804e5502203d66656de8386b9b044346d5605f5ae2b200328fb30476f6ac993fc0dbb0455901" 768 sig2, err := hex.DecodeString(sig2Hex) 769 if err != nil { 770 t.Fatalf("Unable to decode hex: %v", err) 771 } 772 pub2Hex := "03b4c79acdf4e7d978bef4019c421e4c6c67044ed49d27322dc90e808d8080e862" 773 pub2, err := hex.DecodeString(pub2Hex) 774 if err != nil { 775 t.Fatalf("Unable to decode hex: %v", err) 776 } 777 778 // =============================================================== 779 // Before adding the signature, we'll make a new PSBT with 780 // modifications to the input data and check it fails sanity checks. 781 782 // First an invalid tx: 783 psbtBorkedInput2, _ := NewFromRawBytes(bytes.NewReader([]byte(imported)), true) 784 borkedUpdater, err := NewUpdater(psbtBorkedInput2) 785 if err != nil { 786 t.Fatalf("NewUpdater failed while trying to create borked "+ 787 "version: %v", err) 788 } 789 borkedUpdater.AddInWitnessUtxo(txFund1Out, 0) 790 791 res, err = borkedUpdater.Sign(0, sig2, pub2, nil, nil) 792 if err != ErrInvalidSignatureForInput { 793 t.Fatalf("AddPartialSig succeeded, but should have failed "+ 794 "due to mismatch between pubkey and prevOut; err was: %v", err) 795 } 796 797 // Next, a valid tx serialization, but not the right one 798 wrongTxBytes, err := hex.DecodeString("020000000001012d1d7b17356d0ad8232a5817d2d2fa5cd97d803c0ed03e013e97b65f4f1e5e7501000000171600147848cfb25bb163c7c63732615980a25eddbadc7bfeffffff022a8227630000000017a91472128ae6b6a1b74e499bedb5efb1cb09c9a6713287107240000000000017a91485f81cb970d854e2513ebf5c5b5d09e4509f4af3870247304402201c09aa8bcd18753ef01d8712a55eea5a0f69b6c4cc2944ac942264ff0662c91402201fc1390bf8b0023dd12ae78d7ec181124e106de57bc8f00812ae92bd024d3045012103ba077fc011aa59393bfe17cf491b3a02a9c4d39df122b2148322da0ec23508f459430800") 799 if err != nil { 800 t.Fatalf("Unable to decode hex: %v", err) 801 } 802 wrongTx := wire.NewMsgTx(2) 803 err = wrongTx.Deserialize(bytes.NewReader(wrongTxBytes)) 804 if err != nil { 805 t.Fatalf("Error deserializing transaction: %v", err) 806 } 807 psbtBorkedInput2.Inputs[1] = *NewPsbtInput(wrongTx, nil) 808 res, err = borkedUpdater.Sign(1, sig2, pub2, nil, nil) 809 if err != ErrInvalidSignatureForInput { 810 t.Fatalf("Error should have been invalid sig for input, was: %v", err) 811 } 812 // ====================================================== 813 814 res, err = psbtupdater1.Sign(1, sig2, pub2, nil, nil) 815 if err != nil || res != 0 { 816 t.Fatalf("Failed to add signature to second input: %v %v", err, res) 817 } 818 819 // Neither input (p2pkh and p2wkh) require redeem script nor witness script, 820 // so there are no more fields to add; we are ready to finalize. 821 err = Finalize(psbt1, 0) 822 if err != nil { 823 t.Fatalf("Failed to finalize the first input, %v", err) 824 } 825 if psbt1.IsComplete() { 826 t.Fatalf("PSBT was complete but has not been fully finalized") 827 } 828 err = Finalize(psbt1, 1) 829 if err != nil { 830 t.Fatalf("Failed to finalize second input, %v", err) 831 } 832 833 tx, err := Extract(psbt1) 834 if err != nil { 835 t.Fatalf("unable to extract tx: %v", err) 836 } 837 var networkSerializedTx bytes.Buffer 838 if err := tx.Serialize(&networkSerializedTx); err != nil { 839 t.Fatalf("unable to encode tx: %v", err) 840 } 841 842 expectedTx := "0200000000010236a817a78a786b0f883431c6aaa11437c75a306d67346a99a666bf2095599e490100000000ffffffff461ca936215f9d048c369a34486b2022f0cec8c4050181076570f98e9e240ab5000000006a473044022014eb9c4858f71c9f280bc68402aa742a5187f54c56c8eb07c902eb1eb5804e5502203d66656de8386b9b044346d5605f5ae2b200328fb30476f6ac993fc0dbb04559012103b4c79acdf4e7d978bef4019c421e4c6c67044ed49d27322dc90e808d8080e862ffffffff028027128c0000000017a914055b2f1271292486518cc1f3a7c75e58c11cc0a687f05f93030000000017a9140b784f22df1a72fd418e862d81dba52423f90725870247304402200da03ac9890f5d724c42c83c2a62844c08425a274f1a5bca50dcde4126eb20dd02205278897b65cb8e390a0868c9582133c7157b2ad3e81c1c70d8fbd65f51a5658b0121024d6b24f372dd4551277c8df4ecc0655101e11c22894c8e05a3468409c865a72c0000000000" 843 expectedTxBytes, err := hex.DecodeString(expectedTx) 844 if err != nil { 845 t.Fatalf("Unable to decode hex: %v", err) 846 } 847 if !bytes.Equal(expectedTxBytes, networkSerializedTx.Bytes()) { 848 t.Fatalf("The produced network transaction did not match the expected: %x \n %x \n", 849 networkSerializedTx.Bytes(), expectedTxBytes) 850 } 851 852} 853 854func TestImportFromCore2(t *testing.T) { 855 // This example #2 was created manually using Bitcoin Core 0.17 regtest. 856 // It contains two inputs, one p2sh-p2wkh and one fake utxo. 857 // The PSBT has been created with walletcreatepsbt and then partial-signed 858 // on the real input with walletprocessbst in Core. 859 // We first check that the updating here, using the Core created signature, 860 // redeem script and signature for the p2sh-p2wkh input, creates the 861 // same partial-signed intermediate transaction as Core did after 862 // walletprocesspsbt. 863 // We then attach a fake 864 // input of type p2sh-p2wsh, attach its witnessUtxo, redeemscript and 865 // witnessscript fields, and then finalize the whole transaction. Unlike 866 // the previous example, we cannot here compare with a Core produced 867 // network serialized final transaction, because of the fake input. 868 imported := "cHNidP8BAJsCAAAAAkxTQ+rig5QNnUS5nMc+Pccow4IcOJeQRcNNw+7p5ZA5AQAAAAD/////qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqoNAAAAAP////8CAIYOcAAAAAAWABQ1l7nn13RubTwqRQU2BnVV5WlXBWAxMbUAAAAAF6kUkiuXUjfWFgTp6nl/gf9+8zIWR6KHAAAAAAAAAAAA" 869 psbt1, err := NewFromRawBytes(bytes.NewReader([]byte(imported)), true) 870 if err != nil { 871 t.Fatalf("Failed to parse PSBT: %v", err) 872 } 873 874 // update with the first input's utxo, taken from its funding 875 // transaction 876 fundingTxInput1Hex := "02000000017b260536a3c17aee49c41a9b36fdf01a418e0c04df06fbabcb0d4f590b95d175000000006a473044022074a5a13159b6c12d77881c9501aa5c18616fb76c1809fc4d55f18a2e63159a6702200d1aa72be6056a41808898d24da93c0c0192cad65b7c2cc86e00b3e0fbbd57f601210212cc429d61fde565d0c2271a3e4fdb063cb49ae2257fa71460be753ceb56d175feffffff02bc060d8f0000000017a9140b56c31b5dc5a5a22c45a7850e707ad602d94a3087008352840000000017a9149f3679d67a9a486238764f618a93b82a7d999103879a000000" 877 fundingTxInput1Bytes, err := hex.DecodeString(fundingTxInput1Hex) 878 if err != nil { 879 t.Fatalf("Unable to decode hex: %v", err) 880 } 881 txFund1 := wire.NewMsgTx(2) 882 err = txFund1.Deserialize(bytes.NewReader(fundingTxInput1Bytes)) 883 if err != nil { 884 t.Fatalf("Error deserializing transaction: %v", err) 885 } 886 // First input is witness, take correct output: 887 txFund1Out := txFund1.TxOut[1] 888 889 psbtupdater1 := Updater{Upsbt: psbt1} 890 psbtupdater1.AddInWitnessUtxo(txFund1Out, 0) 891 892 // This input is p2sh-p2wkh, so it requires a redeemscript but not 893 // a witness script. The redeemscript is the witness program. 894 redeemScript, err := hex.DecodeString("00147aed39420a8b7ab98a83791327ccb70819d1fbe2") 895 if err != nil { 896 t.Fatalf("Unable to decode hex: %v", err) 897 } 898 psbtupdater1.AddInRedeemScript(redeemScript, 0) 899 900 // Signing for the first input was done with Core; we manually insert the 901 // relevant input entries here. 902 sig1Hex := "30440220546d182d00e45ef659c329dce6197dc19e0abc795e2c9279873f5a887998b273022044143113fc3475d04fc8d5113e0bbcb42d80514a9f1a2247e9b2a7878e20d44901" 903 sig1, err := hex.DecodeString(sig1Hex) 904 if err != nil { 905 t.Fatalf("Unable to decode hex: %v", err) 906 } 907 pub1Hex := "02bb3ce35af26f4c826eab3e5fc263ef56871b26686a8a995599b7ee6576613104" 908 pub1, err := hex.DecodeString(pub1Hex) 909 if err != nil { 910 t.Fatalf("Unable to decode hex: %v", err) 911 } 912 913 res, err := psbtupdater1.Sign(0, sig1, pub1, nil, nil) 914 if err != nil || res != 0 { 915 t.Fatalf("Unable to add partial signature: %v %v", err, res) 916 } 917 918 // Since this input is now finalizable, we do so: 919 err = Finalize(psbt1, 0) 920 if err != nil { 921 t.Fatalf("Failed to finalize the first input: %v", err) 922 } 923 if psbt1.IsComplete() { 924 t.Fatalf("PSBT was complete but has not been fully finalized") 925 } 926 927 // Core also adds the OutRedeemScript field for the output it knows about. 928 // Note that usually we would not of course re-create, but rather start 929 // from the half-signed version; so this is needed only for a sanity check 930 // that we can recreate the half-signed. 931 output2RedeemScript, err := hex.DecodeString("0014e0846bd17848ab40ca1f56b655c6fa31667880cc") 932 if err != nil { 933 t.Fatalf("Unable to decode hex: %v", err) 934 } 935 psbtupdater1.AddOutRedeemScript(output2RedeemScript, 1) 936 // The main function of the test is to compare the thus-generated 937 // partially (not completely) signed transaction with that generated and 938 // encoded by Core. 939 expectedPsbtPartialB64 := "cHNidP8BAJsCAAAAAkxTQ+rig5QNnUS5nMc+Pccow4IcOJeQRcNNw+7p5ZA5AQAAAAD/////qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqoNAAAAAP////8CAIYOcAAAAAAWABQ1l7nn13RubTwqRQU2BnVV5WlXBWAxMbUAAAAAF6kUkiuXUjfWFgTp6nl/gf9+8zIWR6KHAAAAAAABASAAg1KEAAAAABepFJ82edZ6mkhiOHZPYYqTuCp9mZEDhwEHFxYAFHrtOUIKi3q5ioN5EyfMtwgZ0fviAQhrAkcwRAIgVG0YLQDkXvZZwync5hl9wZ4KvHleLJJ5hz9aiHmYsnMCIEQUMRP8NHXQT8jVET4LvLQtgFFKnxoiR+myp4eOINRJASECuzzjWvJvTIJuqz5fwmPvVocbJmhqiplVmbfuZXZhMQQAAAABABYAFOCEa9F4SKtAyh9WtlXG+jFmeIDMAA==" 940 generatedPsbtPartialB64, err := psbt1.B64Encode() 941 if err != nil { 942 t.Fatalf("Unable to B64Encode Psbt: %v", err) 943 } 944 if expectedPsbtPartialB64 != generatedPsbtPartialB64 { 945 t.Fatalf("Partial did not match expected: %v", generatedPsbtPartialB64) 946 } 947 948 // We now simulate adding the signing data for the second (fake) input, 949 // and check that we can finalize and extract. This input is p2sh-p2wsh. 950 // the second input is fake, we're going to make it witness type, 951 // so create a TxOut struct that fits 952 fakeTxOutSerialized, err := hex.DecodeString("00c2eb0b0000000017a914b7f5faf40e3d40a5a459b1db3535f2b72fa921e887") 953 if err != nil { 954 t.Fatalf("Failed to decode hex: %v", err) 955 } 956 fakevalSerialized := binary.LittleEndian.Uint64(fakeTxOutSerialized[:8]) 957 fakeScriptPubKey := fakeTxOutSerialized[9:] 958 txFund2Out := wire.NewTxOut(int64(fakevalSerialized), fakeScriptPubKey) 959 psbt2, err := NewFromRawBytes(bytes.NewReader([]byte(expectedPsbtPartialB64)), true) 960 if err != nil { 961 t.Fatalf("Failed to load partial PSBT: %v", err) 962 } 963 psbtupdater2, err := NewUpdater(psbt2) 964 if err != nil { 965 t.Fatalf("Failed to create updater: %v", err) 966 } 967 psbtupdater2.AddInWitnessUtxo(txFund2Out, 1) 968 // Add redeemScript, which is the witnessscript/program: 969 redeemScript, err = hex.DecodeString("00208c2353173743b595dfb4a07b72ba8e42e3797da74e87fe7d9d7497e3b2028903") 970 if err != nil { 971 t.Fatalf("Failed to decode hex: %v", err) 972 } 973 err = psbtupdater2.AddInRedeemScript(redeemScript, 1) 974 if err != nil { 975 t.Fatalf("Failed to add redeemscript to second input: %v", err) 976 } 977 // Add witnessScript, which here is multisig: 978 witnessScript, err := hex.DecodeString("522103089dc10c7ac6db54f91329af617333db388cead0c231f723379d1b99030b02dc21023add904f3d6dcf59ddb906b0dee23529b7ffb9ed50e5e86151926860221f0e7352ae") 979 if err != nil { 980 t.Fatalf("Failed to decode hex: %v", err) 981 } 982 // To test multisig checks, add a nonsense version of the multisig script 983 witnessScriptNonsense, err := hex.DecodeString("52ffff") 984 if err != nil { 985 t.Fatalf("Failed to decode hex: %v", err) 986 } 987 err = psbtupdater2.AddInWitnessScript(witnessScript, 1) 988 if err != nil { 989 t.Fatalf("Failed to add witnessscript to second input: %v", err) 990 } 991 // Construct the two partial signatures to be added 992 sig21, err := hex.DecodeString("3044022062eb7a556107a7c73f45ac4ab5a1dddf6f7075fb1275969a7f383efff784bcb202200c05dbb7470dbf2f08557dd356c7325c1ed30913e996cd3840945db12228da5f01") 993 if err != nil { 994 t.Fatalf("Failed to decode hex: %v", err) 995 } 996 pub21, err := hex.DecodeString("03089dc10c7ac6db54f91329af617333db388cead0c231f723379d1b99030b02dc") 997 if err != nil { 998 t.Fatalf("Failed to decode hex: %v", err) 999 } 1000 sig22, err := hex.DecodeString("3044022065f45ba5998b59a27ffe1a7bed016af1f1f90d54b3aa8f7450aa5f56a25103bd02207f724703ad1edb96680b284b56d4ffcb88f7fb759eabbe08aa30f29b851383d201") 1001 if err != nil { 1002 t.Fatalf("Failed to decode hex: %v", err) 1003 } 1004 pub22, err := hex.DecodeString("023add904f3d6dcf59ddb906b0dee23529b7ffb9ed50e5e86151926860221f0e73") 1005 if err != nil { 1006 t.Fatalf("Failed to decode hex: %v", err) 1007 } 1008 res, err = psbtupdater2.Sign(1, sig21, pub21, nil, nil) 1009 1010 // Check that the finalization procedure fails here due to not 1011 // meeting the multisig policy 1012 success, err := MaybeFinalize(psbt2, 1) 1013 if success { 1014 t.Fatalf("Incorrectly succeeded in finalizing without sigs") 1015 } 1016 if err != ErrUnsupportedScriptType { 1017 t.Fatalf("Got unexpected error type: %v", err) 1018 } 1019 1020 res, err = psbtupdater2.Sign(1, sig22, pub22, nil, nil) 1021 1022 // Check that the finalization procedure also fails with a nonsense 1023 // script 1024 err = psbtupdater2.AddInWitnessScript(witnessScriptNonsense, 1) 1025 if err != nil { 1026 t.Fatalf("Failed to add witnessscript to second input: %v", err) 1027 } 1028 success, err = MaybeFinalize(psbt2, 1) 1029 if success { 1030 t.Fatalf("Incorrectly succeeded in finalizing with invalid msigscript") 1031 } 1032 if err != ErrUnsupportedScriptType { 1033 t.Fatalf("Got unexpected error type: %v", err) 1034 } 1035 1036 // Restore the correct witnessScript to complete correctly 1037 err = psbtupdater2.AddInWitnessScript(witnessScript, 1) 1038 if err != nil { 1039 t.Fatalf("Failed to add witnessscript to second input: %v", err) 1040 } 1041 1042 success, err = MaybeFinalize(psbt2, 1) 1043 if !success { 1044 if err != nil { 1045 t.Fatalf("Failed to finalize second input: %v", err) 1046 } else { 1047 t.Fatalf("Input was not finalizable") 1048 } 1049 } 1050 1051 // Add a (fake) witnessOut descriptor field to one of the outputs, 1052 // for coverage purposes (we aren't currently using this field) 1053 psbtupdater2.AddOutWitnessScript([]byte{0xff, 0xff, 0xff}, 0) 1054 1055 // Sanity check; we should not have lost the additional output entry 1056 // provided by Core initially 1057 uoutput1 := psbtupdater2.Upsbt.Outputs[1] 1058 if uoutput1.RedeemScript == nil { 1059 t.Fatalf("PSBT should contain outredeemscript entry, but it does not.") 1060 } 1061 // Nor should we have lost our fake witnessscript output entry 1062 uoutput2 := psbtupdater2.Upsbt.Outputs[0] 1063 if uoutput2.WitnessScript == nil { 1064 t.Fatalf("PSBT should contain outwitnessscript but it does not.") 1065 } 1066 var tx bytes.Buffer 1067 networkSerializedTx, err := Extract(psbt2) 1068 if err != nil { 1069 t.Fatalf("unable to extract tx: %v", err) 1070 } 1071 if err := networkSerializedTx.Serialize(&tx); err != nil { 1072 t.Fatalf("unable to encode tx: %v", err) 1073 } 1074 expectedSerializedTx, err := hex.DecodeString("020000000001024c5343eae283940d9d44b99cc73e3dc728c3821c38979045c34dc3eee9e5903901000000171600147aed39420a8b7ab98a83791327ccb70819d1fbe2ffffffffaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa0d000000232200208c2353173743b595dfb4a07b72ba8e42e3797da74e87fe7d9d7497e3b2028903ffffffff0200860e70000000001600143597b9e7d7746e6d3c2a450536067555e5695705603131b50000000017a914922b975237d61604e9ea797f81ff7ef3321647a287024730440220546d182d00e45ef659c329dce6197dc19e0abc795e2c9279873f5a887998b273022044143113fc3475d04fc8d5113e0bbcb42d80514a9f1a2247e9b2a7878e20d449012102bb3ce35af26f4c826eab3e5fc263ef56871b26686a8a995599b7ee65766131040400473044022062eb7a556107a7c73f45ac4ab5a1dddf6f7075fb1275969a7f383efff784bcb202200c05dbb7470dbf2f08557dd356c7325c1ed30913e996cd3840945db12228da5f01473044022065f45ba5998b59a27ffe1a7bed016af1f1f90d54b3aa8f7450aa5f56a25103bd02207f724703ad1edb96680b284b56d4ffcb88f7fb759eabbe08aa30f29b851383d20147522103089dc10c7ac6db54f91329af617333db388cead0c231f723379d1b99030b02dc21023add904f3d6dcf59ddb906b0dee23529b7ffb9ed50e5e86151926860221f0e7352ae00000000") 1075 if err != nil { 1076 t.Fatalf("Failed to decode hex: %v", err) 1077 } 1078 if !bytes.Equal(expectedSerializedTx, tx.Bytes()) { 1079 t.Fatalf("Failed to create correct network serialized "+ 1080 "transaction: expected %x, got %x", 1081 expectedSerializedTx, tx.Bytes()) 1082 } 1083} 1084 1085func TestMaybeFinalizeAll(t *testing.T) { 1086 // The following data is from a 3rd transaction from Core, 1087 // using 3 inputs, all p2wkh. 1088 imported := "cHNidP8BAKQCAAAAAzJyXH13IqBFvvZ7y1VSgUgkMvMoPgP5CfFNqsjQexKQAQAAAAD/////fMdLydu5bsoiHN9cFSaBL0Qnq2KLSKx0RA4b938CAgQAAAAAAP/////yKNgfsDAHr/zFz8R9k8EFI26allfg9DdE8Gzj6tGlegEAAAAA/////wHw9E0OAAAAABYAFDnPCRduiEWmmSc1j30SJ8k9u7PHAAAAAAAAAAAA" 1089 psbt1, err := NewFromRawBytes(bytes.NewReader([]byte(imported)), true) 1090 if err != nil { 1091 t.Fatalf("Failed to parse PSBT: %v", err) 1092 } 1093 1094 // update with the first input's utxo, taken from its funding 1095 // transaction 1096 fundingTxInput1, err := hex.DecodeString("020000000001017b260536a3c17aee49c41a9b36fdf01a418e0c04df06fbabcb0d4f590b95d1750100000017160014af82cd4409241b1de892726324bd780e3b5cd8aafeffffff02a85f9800000000001600149d21f8b306ddfd4dd035080689e88b4c3471e3cc801d2c0400000000160014d97ccd3dfb60820d7d33d862371ca5a73039bd560247304402201a1d2fdb5a7190b7fa59907769f0fc9c91fd3b34f6424acf5868a8ac21ec287102200a59b9d076ecf98c88f2196ed2be0aafff4966ead754041182fff5f92115a783012103604ffd31dc71db2e32c20f09eafe6353cd7515d3648aff829bb4879b553e30629a000000") 1097 if err != nil { 1098 t.Fatalf("Unable to decode hex: %v", err) 1099 } 1100 fundingTxInput2, err := hex.DecodeString("020000000001019c27b886e420fcadb077706b0933efa8bb53e3a250c3ec45cfdba5e05e233f360100000000feffffff0200b4c404000000001600140853f50c7d2d5d2af326a75efdbc83b62551e89afce31c0d000000001600142d6936c082c35607ec3bdb334a932d928150b75802473044022000d962f5e5e6425f9de21da7ac65b4fd8af8f6bfbd33c7ba022827c73866b477022034c59935c1ea10b5ba335d93f55a200c2588ec6058b8c7aedd10d5cbc4654f99012102c30e9f0cd98f6a805464d6b8a326b5679b6c3262934341855ee0436eaedfd2869a000000") 1101 if err != nil { 1102 t.Fatalf("Unable to decode hex: %v", err) 1103 } 1104 fundingTxInput3, err := hex.DecodeString("02000000012bf4331bb95df4eadb14f7a28db3fecdc5e87f08c29c2332b66338dd606699f60000000048473044022075ed43f508528da47673550a785702e9a93eca84a11faea91c4e9c66fcab3c9e022054a37610bd40b12263a5933188f062b718e007f290cecde2b6e41da3e1ebbddf01feffffff020c99a8240100000016001483bd916985726094d6d1c5b969722da580b5966a804a5d05000000001600140a2ee13a6696d75006af5e8a026ea49316087dae9a000000") 1105 if err != nil { 1106 t.Fatalf("Unable to decode hex: %v", err) 1107 } 1108 1109 psbtupdater1 := Updater{Upsbt: psbt1} 1110 tx := wire.NewMsgTx(2) 1111 err = tx.Deserialize(bytes.NewReader(fundingTxInput1)) 1112 if err != nil { 1113 t.Fatalf("Error deserializing transaction: %v", err) 1114 } 1115 txFund1Out := tx.TxOut[1] 1116 psbtupdater1.AddInWitnessUtxo(txFund1Out, 0) 1117 1118 tx = wire.NewMsgTx(2) 1119 err = tx.Deserialize(bytes.NewReader(fundingTxInput2)) 1120 if err != nil { 1121 t.Fatalf("Error deserializing transaction: %v", err) 1122 } 1123 txFund2Out := tx.TxOut[0] 1124 psbtupdater1.AddInWitnessUtxo(txFund2Out, 1) 1125 1126 tx = wire.NewMsgTx(2) 1127 err = tx.Deserialize(bytes.NewReader(fundingTxInput3)) 1128 if err != nil { 1129 t.Fatalf("Error deserializing transaction: %v", err) 1130 } 1131 txFund3Out := tx.TxOut[1] 1132 psbtupdater1.AddInWitnessUtxo(txFund3Out, 2) 1133 1134 // To be ready for finalization, we need to have partial signature 1135 // fields for each input 1136 sig1, _ := hex.DecodeString("30440220027605ee8015970baf02a72652967a543e1b29a6882d799738ed1baee508822702203818a2f1b9770c46a473f47ad7ae90bcc129a5d047f00fae354c80197a7cf50601") 1137 pub1, _ := hex.DecodeString("03235fc1f9dc8bbf6fa3df35dfeb0dd486f2d488f139579885eb684510f004f6c1") 1138 sig2, _ := hex.DecodeString("304402206f5aea4621696610de48736b95a89b1d3a434a4e536d9aae65e039c477cf4c7202203b27a18b0f63be7d3bbf5be1bc2306a7ec8c2da12c2820ff07b73c7f3f1d4d7301") 1139 pub2, _ := hex.DecodeString("022011b496f0603a268b55a781c7be0c3849f605f09cb2e917ed44288b8144a752") 1140 sig3, _ := hex.DecodeString("3044022036dbc6f8f85a856e7803cbbcf0a97b7a74806fc592e92d7c06826f911610b98e0220111d43c4b20f756581791334d9c5cbb1a9c07558f28404cabf01c782897ad50501") 1141 pub3, _ := hex.DecodeString("0381772a80c69e275e20d7f014555b13031e9cacf1c54a44a67ab2bc7eba64f227") 1142 res, err := psbtupdater1.Sign(0, sig1, pub1, nil, nil) 1143 if err != nil || res != 0 { 1144 t.Fatalf("Failed to add partial signature for input 0: %v %v", err, res) 1145 } 1146 res, err = psbtupdater1.Sign(1, sig2, pub2, nil, nil) 1147 if err != nil || res != 0 { 1148 t.Fatalf("Failed to add partial signature for input 1: %v %v", err, res) 1149 } 1150 1151 // Not ready for finalize all, check it fails: 1152 err = MaybeFinalizeAll(psbt1) 1153 if err != ErrNotFinalizable { 1154 t.Fatalf("Expected finalization failure, got: %v", err) 1155 } 1156 1157 res, err = psbtupdater1.Sign(2, sig3, pub3, nil, nil) 1158 1159 // Since this input is now finalizable and is p2wkh only, we can do 1160 // all at once: 1161 err = MaybeFinalizeAll(psbt1) 1162 if err != nil { 1163 t.Fatalf("Failed to finalize PSBT: %v", err) 1164 } 1165 if !psbt1.IsComplete() { 1166 t.Fatalf("PSBT was finalized but not marked complete") 1167 } 1168 1169} 1170 1171func TestFromUnsigned(t *testing.T) { 1172 serTx, err := hex.DecodeString("00000000000101e165f072311e71825b47a4797221d7ae56d4b40b7707c540049aee43302448a40000000000feffffff0212f1126a0000000017a9143e836801b2b15aa193449d815c62d6c4b6227c898780778e060000000017a914ba4bdb0b07d67bc60f59c1f4fe54170565254974870000000000") 1173 if err != nil { 1174 t.Fatalf("Error: %v", err) 1175 } 1176 tx := wire.NewMsgTx(2) 1177 err = tx.Deserialize(bytes.NewReader(serTx)) 1178 if err != nil { 1179 t.Fatalf("Error: %v", err) 1180 } 1181 psbt1, err := NewFromUnsignedTx(tx) 1182 if err != nil { 1183 t.Fatalf("Error: %v", err) 1184 } 1185 encoded, err := psbt1.B64Encode() 1186 if err != nil { 1187 t.Fatalf("Unable to B64Encode Psbt: %v", err) 1188 } 1189 1190 // Compare with output of Core: 1191 fromCoreB64 := "cHNidP8BAHMAAAAAAeFl8HIxHnGCW0ekeXIh165W1LQLdwfFQASa7kMwJEikAAAAAAD+////AhLxEmoAAAAAF6kUPoNoAbKxWqGTRJ2BXGLWxLYifImHgHeOBgAAAAAXqRS6S9sLB9Z7xg9ZwfT+VBcFZSVJdIcAAAAAAAAAAA==" 1192 if encoded != fromCoreB64 { 1193 t.Fatalf("Got incorrect b64: %v", encoded) 1194 } 1195 _, err = NewFromRawBytes(bytes.NewReader([]byte(fromCoreB64)), true) 1196 if err != nil { 1197 t.Fatalf("Error: %v", err) 1198 } 1199} 1200 1201func TestNonWitnessToWitness(t *testing.T) { 1202 // We'll start with a PSBT produced by Core for which 1203 // the first input is signed and we'll provided the signatures for 1204 // the other three inputs; they are p2sh-p2wkh, p2wkh and legacy 1205 // respectively. 1206 // In each case we'll *first* attach the NonWitnessUtxo field, 1207 // and then call sign; in the first two but not the third case, the 1208 // NonWitnessUtxo will automatically be replaced with the WitnessUtxo. 1209 // Finally we'll check that the fully finalized PSBT produced matches 1210 // the one produced by Core for the same keys. 1211 1212 psbt1B64 := "cHNidP8BAM4CAAAABHtBMXY+SX95xidmWJP67CTQ02FPUpbNhIxNplAdlvk+AQAAAAD/////G2mt4bX7+sVi1jdbuBa5Q/xsJdgzFCgdHHSZq3ewK6YAAAAAAP/////NrbZb7GzfAg4kOqFWAIbXabq4cAvtVGv+eecIIv1KggEAAAAA/////73s9ifprgErlaONH1rgpNs3l6+t+mz2XGTHsTVWCem/AQAAAAD/////AfAmclMAAAAAF6kUQwsEC5nzbdY5meON2ZQ2thmeFgOHAAAAAAABASAAZc0dAAAAABepFPAv3VTMu5+4WN+/HIji6kG9RpzKhwEHFxYAFLN3PqXSyIHWKqm4ah5m9erc/3OoAQhrAkcwRAIgH7kzGO2iskfCvX0dgkDuzfqJ7tAu7KUZOeykTkJ1SYkCIBv4QRZK1hLz45D0gs+Lz93OE4s37lkPVE+SlXZtazWEASEC3jaf19MMferBn0Bn5lxXJGOqoqmfSvnHclQvB5gJ3nEAAAAAAQAWABTB+Qcq6iqdSvvc6959kd7XHrhYFgA=" 1213 nwutxo1ser, _ := hex.DecodeString("02000000017f7baa6b7377541c4aca372d2dce8e1098ba44aa8379b7ea87644ef27e08ec240000000048473044022072e3b94c33cb5128518cd3903cc0ca19e8c234ac6d462e01ae2bb1da7768ed7d0220167d7ad89f6e1bbb3b866ae6fc2f67b5e7d51eb4f33f7bfe3f4b2673856b815001feffffff0200c2eb0b0000000017a9142dd25c78db2e2e09376eab9cb342e1b03005abe487e4ab953e0000000017a914120b8ca3fb4c7f852e30d4e3714fb64027a0b4c38721020000") 1214 nwutxo2ser, _ := hex.DecodeString("0200000001f51b0bb5d945dd5532448a4d3fb88134d0bd90493813515f9c2ddb1fa15b9ba60000000048473044022047d83caf88d398245c006374bfa9f27ae968f5f51d640cacd5a214ed2cba397a02204519b26035496855f574a72b73bdcfa46d53995faf64c8f0ab394b628cc5383901feffffff020ccb9f3800000000160014e13544a3c718faa6c5ad7089a6660383c12b072700a3e11100000000160014a5439b477c116b79bd4c7c5131f3e58d54f27bb721020000") 1215 nwutxo3ser, _ := hex.DecodeString("0200000001eb452f0fc9a8c39edb79f7174763f3cb25dc56db455926e411719a115ef16509000000004847304402205aa80cc615eb4b3f6e89696db4eadd192581a6c46f5c09807d3d98ece1d77355022025007e58c1992a1e5d877ee324bfe0a65db26d29f80941cfa277ac3efbcad2a701feffffff02bce9a9320000000017a9141590e852ac66eb8798afeb2a5ed67c568a2d6561870084d717000000001976a914a57ea05eacf94900d5fb92bccd273cfdb90af36f88ac21020000") 1216 1217 nwutxo1 := wire.NewMsgTx(2) 1218 err := nwutxo1.Deserialize(bytes.NewReader(nwutxo1ser)) 1219 if err != nil { 1220 t.Fatalf("Error deserializing transaction: %v", err) 1221 } 1222 nwutxo2 := wire.NewMsgTx(2) 1223 err = nwutxo2.Deserialize(bytes.NewReader(nwutxo2ser)) 1224 if err != nil { 1225 t.Fatalf("Error deserializing transaction: %v", err) 1226 } 1227 nwutxo3 := wire.NewMsgTx(2) 1228 err = nwutxo3.Deserialize(bytes.NewReader(nwutxo3ser)) 1229 if err != nil { 1230 t.Fatalf("Error deserializing transaction: %v", err) 1231 } 1232 1233 // import the PSBT 1234 psbt1, err := NewFromRawBytes(bytes.NewReader([]byte(psbt1B64)), true) 1235 if err != nil { 1236 t.Fatalf("Failed to create PSBT: %v", err) 1237 } 1238 1239 // check that we recognize the finality of the first input 1240 if !isFinalized(psbt1, 0) { 1241 t.Fatalf("First input incorrectly read as not finalized.") 1242 } 1243 1244 // Add NonWitnessUtxo fields for each of the other three inputs 1245 u := Updater{Upsbt: psbt1} 1246 u.AddInNonWitnessUtxo(nwutxo1, 1) 1247 u.AddInNonWitnessUtxo(nwutxo2, 2) 1248 u.AddInNonWitnessUtxo(nwutxo3, 3) 1249 1250 // Signatures for each of those inputs were created with Core: 1251 sig1, _ := hex.DecodeString("304402205676877e6162ce40a49ee5a74443cdc1e7915637c42da7b872c2ec2298fd371b02203c1d4a05b1e2a7a588d9ec9b8d4892d2cd59bebe0e777483477a0ec692ebbe6d01") 1252 pub1, _ := hex.DecodeString("02534f23cb88a048b649672967263bd7570312d5d31d066fa7b303970010a77b2b") 1253 redeemScript1, _ := hex.DecodeString("00142412be29368c0260cb841eecd9b59d7e01174aa1") 1254 1255 sig2, _ := hex.DecodeString("3044022065d0a349709b8d8043cfd644cf6c196c1f601a22e1b3fdfbf8c0cc2a80fe2f1702207c87d36b666a8862e81ec5df288707f517d2f35ea1548feb82019de2c8de90f701") 1256 pub2, _ := hex.DecodeString("0257d88eaf1e79b72ea0a33ae89b57dae95ea68499bdc6770257e010ab899f0abb") 1257 1258 sig3, _ := hex.DecodeString("30440220290abcaacbd759c4f989762a9ee3468a9231788aab8f50bf65955d8597d8dd3602204d7e394f4419dc5392c6edba6945837458dd750a030ac67a746231903a8eb7db01") 1259 pub3, _ := hex.DecodeString("0388025f50bb51c0469421ed13381f22f9d46a070ec2837e055c49c5876f0d0968") 1260 1261 // Add the signatures and any scripts needed to the inputs 1262 res, err := u.Sign(1, sig1, pub1, redeemScript1, nil) 1263 if res != 0 || err != nil { 1264 t.Fatalf("Failed to sign at index %v res %v err %v", 1, res, err) 1265 } 1266 res, err = u.Sign(2, sig2, pub2, nil, nil) 1267 if res != 0 || err != nil { 1268 t.Fatalf("Failed to sign at index %v res %v err %v", 2, res, err) 1269 } 1270 res, err = u.Sign(3, sig3, pub3, nil, nil) 1271 if res != 0 || err != nil { 1272 t.Fatalf("Failed to sign at index %v res %v err %v", 3, res, err) 1273 } 1274 1275 // Attempt to finalize the rest of the transaction 1276 _, err = MaybeFinalize(psbt1, 1) 1277 if err != nil { 1278 t.Fatalf("Failed to finalize input 1 %v", err) 1279 } 1280 _, err = MaybeFinalize(psbt1, 2) 1281 if err != nil { 1282 t.Fatalf("Failed to finalize input 2 %v", err) 1283 } 1284 _, err = MaybeFinalize(psbt1, 3) 1285 if err != nil { 1286 t.Fatalf("Failed to finalize input 3 %v", err) 1287 } 1288 1289 // Finally we can check whether both the B64 encoding of the PSBT, 1290 // and the final network serialized signed transaction, that we generated 1291 // with Core using the 2 wallets, matches what this code produces: 1292 expectedFinalizedPsbt := "cHNidP8BAM4CAAAABHtBMXY+SX95xidmWJP67CTQ02FPUpbNhIxNplAdlvk+AQAAAAD/////G2mt4bX7+sVi1jdbuBa5Q/xsJdgzFCgdHHSZq3ewK6YAAAAAAP/////NrbZb7GzfAg4kOqFWAIbXabq4cAvtVGv+eecIIv1KggEAAAAA/////73s9ifprgErlaONH1rgpNs3l6+t+mz2XGTHsTVWCem/AQAAAAD/////AfAmclMAAAAAF6kUQwsEC5nzbdY5meON2ZQ2thmeFgOHAAAAAAABASAAZc0dAAAAABepFPAv3VTMu5+4WN+/HIji6kG9RpzKhwEHFxYAFLN3PqXSyIHWKqm4ah5m9erc/3OoAQhrAkcwRAIgH7kzGO2iskfCvX0dgkDuzfqJ7tAu7KUZOeykTkJ1SYkCIBv4QRZK1hLz45D0gs+Lz93OE4s37lkPVE+SlXZtazWEASEC3jaf19MMferBn0Bn5lxXJGOqoqmfSvnHclQvB5gJ3nEAAQEgAMLrCwAAAAAXqRQt0lx42y4uCTduq5yzQuGwMAWr5IcBBxcWABQkEr4pNowCYMuEHuzZtZ1+ARdKoQEIawJHMEQCIFZ2h35hYs5ApJ7lp0RDzcHnkVY3xC2nuHLC7CKY/TcbAiA8HUoFseKnpYjZ7JuNSJLSzVm+vg53dINHeg7Gkuu+bQEhAlNPI8uIoEi2SWcpZyY711cDEtXTHQZvp7MDlwAQp3srAAEBHwCj4REAAAAAFgAUpUObR3wRa3m9THxRMfPljVTye7cBCGsCRzBEAiBl0KNJcJuNgEPP1kTPbBlsH2AaIuGz/fv4wMwqgP4vFwIgfIfTa2ZqiGLoHsXfKIcH9RfS816hVI/rggGd4sjekPcBIQJX2I6vHnm3LqCjOuibV9rpXqaEmb3GdwJX4BCriZ8KuwABAL0CAAAAAetFLw/JqMOe23n3F0dj88sl3FbbRVkm5BFxmhFe8WUJAAAAAEhHMEQCIFqoDMYV60s/bolpbbTq3RklgabEb1wJgH09mOzh13NVAiAlAH5YwZkqHl2HfuMkv+CmXbJtKfgJQc+id6w++8rSpwH+////ArzpqTIAAAAAF6kUFZDoUqxm64eYr+sqXtZ8VootZWGHAITXFwAAAAAZdqkUpX6gXqz5SQDV+5K8zSc8/bkK82+IrCECAAABB2pHMEQCICkKvKrL11nE+Yl2Kp7jRoqSMXiKq49Qv2WVXYWX2N02AiBNfjlPRBncU5LG7bppRYN0WN11CgMKxnp0YjGQOo632wEhA4gCX1C7UcBGlCHtEzgfIvnUagcOwoN+BVxJxYdvDQloAAEAFgAUwfkHKuoqnUr73OvefZHe1x64WBYA" 1293 calculatedPsbt, err := u.Upsbt.B64Encode() 1294 if err != nil { 1295 t.Fatalf("Failed to base64 encode") 1296 } 1297 if expectedFinalizedPsbt != calculatedPsbt { 1298 t.Fatalf("Failed to generate correct PSBT") 1299 } 1300 1301 expectedNetworkSer, _ := hex.DecodeString("020000000001047b4131763e497f79c627665893faec24d0d3614f5296cd848c4da6501d96f93e0100000017160014b3773ea5d2c881d62aa9b86a1e66f5eadcff73a8ffffffff1b69ade1b5fbfac562d6375bb816b943fc6c25d83314281d1c7499ab77b02ba600000000171600142412be29368c0260cb841eecd9b59d7e01174aa1ffffffffcdadb65bec6cdf020e243aa1560086d769bab8700bed546bfe79e70822fd4a820100000000ffffffffbdecf627e9ae012b95a38d1f5ae0a4db3797afadfa6cf65c64c7b1355609e9bf010000006a4730440220290abcaacbd759c4f989762a9ee3468a9231788aab8f50bf65955d8597d8dd3602204d7e394f4419dc5392c6edba6945837458dd750a030ac67a746231903a8eb7db01210388025f50bb51c0469421ed13381f22f9d46a070ec2837e055c49c5876f0d0968ffffffff01f02672530000000017a914430b040b99f36dd63999e38dd99436b6199e1603870247304402201fb93318eda2b247c2bd7d1d8240eecdfa89eed02eeca51939eca44e4275498902201bf841164ad612f3e390f482cf8bcfddce138b37ee590f544f9295766d6b3584012102de369fd7d30c7deac19f4067e65c572463aaa2a99f4af9c772542f079809de710247304402205676877e6162ce40a49ee5a74443cdc1e7915637c42da7b872c2ec2298fd371b02203c1d4a05b1e2a7a588d9ec9b8d4892d2cd59bebe0e777483477a0ec692ebbe6d012102534f23cb88a048b649672967263bd7570312d5d31d066fa7b303970010a77b2b02473044022065d0a349709b8d8043cfd644cf6c196c1f601a22e1b3fdfbf8c0cc2a80fe2f1702207c87d36b666a8862e81ec5df288707f517d2f35ea1548feb82019de2c8de90f701210257d88eaf1e79b72ea0a33ae89b57dae95ea68499bdc6770257e010ab899f0abb0000000000") 1302 tx, err := Extract(psbt1) 1303 if err != nil { 1304 t.Fatalf("Failed to extract: %v", err) 1305 } 1306 var b bytes.Buffer 1307 if err := tx.Serialize(&b); err != nil { 1308 t.Fatalf("unable to encode tx: %v", err) 1309 } 1310 if !bytes.Equal(expectedNetworkSer, b.Bytes()) { 1311 t.Fatalf("Expected serialized transaction was not produced: %x", b.Bytes()) 1312 } 1313} 1314 1315// TestEmptyInputSerialization tests the special serialization case for a wire 1316// transaction that has no inputs. 1317func TestEmptyInputSerialization(t *testing.T) { 1318 // Create and serialize a new, empty PSBT. The wire package will assume 1319 // it's a non-witness transaction, as there are no inputs. 1320 psbt, err := New(nil, nil, 2, 0, nil) 1321 if err != nil { 1322 t.Fatalf("failed to create empty PSBT: %v", err) 1323 } 1324 var buf bytes.Buffer 1325 err = psbt.Serialize(&buf) 1326 if err != nil { 1327 t.Fatalf("failed to serialize empty PSBT: %v", err) 1328 } 1329 1330 // Try to deserialize the empty transaction again. The wire package will 1331 // assume it's a witness transaction because of the special case where 1332 // there are no inputs. This assumption is wrong and the first attempt 1333 // will fail. But a workaround should try again to deserialize the TX 1334 // with the non-witness format. 1335 psbt2, err := NewFromRawBytes(&buf, false) 1336 if err != nil { 1337 t.Fatalf("failed to deserialize empty PSBT: %v", err) 1338 } 1339 if len(psbt2.UnsignedTx.TxIn) > 0 || len(psbt2.UnsignedTx.TxOut) > 0 { 1340 t.Fatalf("deserialized transaction not empty") 1341 } 1342} 1343 1344// TestWitnessForNonWitnessUtxo makes sure that a packet that only has a non- 1345// witness UTXO set can still be signed correctly by adding witness data. This 1346// is to make sure that PSBTs following the CVE-2020-14199 bugfix are not 1347// rejected. See https://github.com/bitcoin/bitcoin/pull/19215. 1348func TestWitnessForNonWitnessUtxo(t *testing.T) { 1349 // Our witness UTXO is index 1 of this raw transaction from the test 1350 // vectors. 1351 prevTxRaw, _ := hex.DecodeString("0200000000010158e87a21b56daf0c23be8e7070456c336f7cbaa5c8757924f545887bb2abdd7501000000171600145f275f436b09a8cc9a2eb2a2f528485c68a56323feffffff02d8231f1b0100000017a914aed962d6654f9a2b36608eb9d64d2b260db4f1118700c2eb0b0000000017a914b7f5faf40e3d40a5a459b1db3535f2b72fa921e88702483045022100a22edcc6e5bc511af4cc4ae0de0fcd75c7e04d8c1c3a8aa9d820ed4b967384ec02200642963597b9b1bc22c75e9f3e117284a962188bf5e8a74c895089046a20ad770121035509a48eb623e10aace8bfd0212fdb8a8e5af3c94b0b133b95e114cab89e4f7965000000") 1352 prevTx := wire.NewMsgTx(2) 1353 err := prevTx.Deserialize(bytes.NewReader(prevTxRaw)) 1354 if err != nil { 1355 t.Fatalf("failed to deserialize previous TX: %v", err) 1356 } 1357 1358 // First create a packet that contains one input and one output. 1359 outPkScript, _ := hex.DecodeString(CUTestHexData["scriptPubkey1"]) 1360 packet := &Packet{ 1361 UnsignedTx: &wire.MsgTx{ 1362 Version: 2, 1363 LockTime: 0, 1364 TxIn: []*wire.TxIn{{ 1365 PreviousOutPoint: wire.OutPoint{ 1366 Hash: prevTx.TxHash(), 1367 Index: 1, 1368 }, 1369 }}, 1370 TxOut: []*wire.TxOut{{ 1371 PkScript: outPkScript, 1372 Value: 1.9 * btcutil.SatoshiPerBitcoin, 1373 }}, 1374 }, 1375 Inputs: []PInput{{}}, 1376 Outputs: []POutput{{}}, 1377 } 1378 1379 // Create an updater for the packet. This also performs a sanity check. 1380 updater, err := NewUpdater(packet) 1381 if err != nil { 1382 t.Fatalf("failed to sanity check raw packet: %v", err) 1383 } 1384 1385 // Now add our witness UTXO to the input. But because hardware wallets 1386 // that are patched against CVE-2020-14199 require the full non-witness 1387 // UTXO to be set for all inputs, we do what Core does and add the full 1388 // transaction in the NonWitnessUtxo instead of just the outpoint in 1389 // WitnessUtxo. 1390 err = updater.AddInNonWitnessUtxo(prevTx, 0) 1391 if err != nil { 1392 t.Fatalf("failed to update non-witness UTXO: %v", err) 1393 } 1394 1395 // Then add the redeem scripts and witness scripts. 1396 redeemScript, _ := hex.DecodeString(CUTestHexData["Input2RedeemScript"]) 1397 err = updater.AddInRedeemScript(redeemScript, 0) 1398 if err != nil { 1399 t.Fatalf("failed to update redeem script: %v", err) 1400 } 1401 witnessScript, _ := hex.DecodeString(CUTestHexData["Input2WitnessScript"]) 1402 err = updater.AddInWitnessScript(witnessScript, 0) 1403 if err != nil { 1404 t.Fatalf("failed to update redeem script: %v", err) 1405 } 1406 1407 // Add the first of the two partial signatures. 1408 sig1, _ := hex.DecodeString("3044022062eb7a556107a7c73f45ac4ab5a1dddf6f7075fb1275969a7f383efff784bcb202200c05dbb7470dbf2f08557dd356c7325c1ed30913e996cd3840945db12228da5f01") 1409 pub1, _ := hex.DecodeString("03089dc10c7ac6db54f91329af617333db388cead0c231f723379d1b99030b02dc") 1410 res, err := updater.Sign(0, sig1, pub1, nil, nil) 1411 if err != nil { 1412 t.Fatalf("failed to sign with pubkey 1: %v", err) 1413 } 1414 if res != SignSuccesful { 1415 t.Fatalf("signing was not successful, got result %v", res) 1416 } 1417 1418 // Check that the finalization procedure fails here due to not 1419 // meeting the multisig policy 1420 success, err := MaybeFinalize(packet, 0) 1421 if success { 1422 t.Fatalf("Incorrectly succeeded in finalizing without sigs") 1423 } 1424 if err != ErrUnsupportedScriptType { 1425 t.Fatalf("Got unexpected error type: %v", err) 1426 } 1427 1428 // Add the second partial signature. 1429 sig2, _ := hex.DecodeString("3044022065f45ba5998b59a27ffe1a7bed016af1f1f90d54b3aa8f7450aa5f56a25103bd02207f724703ad1edb96680b284b56d4ffcb88f7fb759eabbe08aa30f29b851383d201") 1430 pub2, _ := hex.DecodeString("023add904f3d6dcf59ddb906b0dee23529b7ffb9ed50e5e86151926860221f0e73") 1431 res, err = updater.Sign(0, sig2, pub2, nil, nil) 1432 if err != nil { 1433 t.Fatalf("failed to sign with pubkey 2: %v", err) 1434 } 1435 if res != SignSuccesful { 1436 t.Fatalf("signing was not successful, got result %v", res) 1437 } 1438 1439 // Finally make sure we can finalize the packet and extract the raw TX. 1440 err = MaybeFinalizeAll(packet) 1441 if err != nil { 1442 t.Fatalf("error finalizing PSBT: %v", err) 1443 } 1444 _, err = Extract(packet) 1445 if err != nil { 1446 t.Fatalf("unable to extract funding TX: %v", err) 1447 } 1448} 1449