2 # Copyright (c) 2015-2016 The Bitcoin Core developers
3 # Distributed under the MIT software license, see the accompanying
4 # file COPYING or http://www.opensource.org/licenses/mit-license.php.
5 """Test transaction signing using the signrawtransaction RPC."""
7 from test_framework
.test_framework
import BitcoinTestFramework
8 from test_framework
.util
import *
11 class SignRawTransactionsTest(BitcoinTestFramework
):
14 self
.setup_clean_chain
= True
17 def successful_signing_test(self
):
18 """Create and sign a valid raw transaction with one input.
22 1) The transaction has a complete set of signatures
23 2) No script verification error occurred"""
24 privKeys
= ['cUeKHd5orzT3mz8P9pxyREHfsWtVfgsfDjiZZBcjUBAaGk1BTj7N', 'cVKpPfVKSJxKqVpE9awvXNWuLHCa5j5tiE7K6zbUSptFpTEtiFrA']
27 # Valid pay-to-pubkey scripts
28 {'txid': '9b907ef1e3c26fc71fe4a4b3580bc75264112f95050014157059c736f0202e71', 'vout': 0,
29 'scriptPubKey': '76a91460baa0f494b38ce3c940dea67f3804dc52d1fb9488ac'},
30 {'txid': '83a4f6a6b73660e13ee6cb3c6063fa3759c50c9b7521d0536022961898f4fb02', 'vout': 0,
31 'scriptPubKey': '76a914669b857c03a5ed269d5d85a1ffac9ed5d663072788ac'},
34 outputs
= {'mpLQjfK79b7CCV4VMJWEWAj5Mpx8Up5zxB': 0.1}
36 rawTx
= self
.nodes
[0].createrawtransaction(inputs
, outputs
)
37 rawTxSigned
= self
.nodes
[0].signrawtransaction(rawTx
, inputs
, privKeys
)
39 # 1) The transaction has a complete set of signatures
40 assert 'complete' in rawTxSigned
41 assert_equal(rawTxSigned
['complete'], True)
43 # 2) No script verification error occurred
44 assert 'errors' not in rawTxSigned
46 # Check that signrawtransaction doesn't blow up on garbage merge attempts
47 dummyTxInconsistent
= self
.nodes
[0].createrawtransaction([inputs
[0]], outputs
)
48 rawTxUnsigned
= self
.nodes
[0].signrawtransaction(rawTx
+ dummyTxInconsistent
, inputs
)
50 assert 'complete' in rawTxUnsigned
51 assert_equal(rawTxUnsigned
['complete'], False)
53 # Check that signrawtransaction properly merges unsigned and signed txn, even with garbage in the middle
54 rawTxSigned2
= self
.nodes
[0].signrawtransaction(rawTxUnsigned
["hex"] + dummyTxInconsistent
+ rawTxSigned
["hex"], inputs
)
56 assert 'complete' in rawTxSigned2
57 assert_equal(rawTxSigned2
['complete'], True)
59 assert 'errors' not in rawTxSigned2
62 def script_verification_error_test(self
):
63 """Create and sign a raw transaction with valid (vin 0), invalid (vin 1) and one missing (vin 2) input script.
67 3) The transaction has no complete set of signatures
68 4) Two script verification errors occurred
69 5) Script verification errors have certain properties ("txid", "vout", "scriptSig", "sequence", "error")
70 6) The verification errors refer to the invalid (vin 1) and missing input (vin 2)"""
71 privKeys
= ['cUeKHd5orzT3mz8P9pxyREHfsWtVfgsfDjiZZBcjUBAaGk1BTj7N']
74 # Valid pay-to-pubkey script
75 {'txid': '9b907ef1e3c26fc71fe4a4b3580bc75264112f95050014157059c736f0202e71', 'vout': 0},
77 {'txid': '5b8673686910442c644b1f4993d8f7753c7c8fcb5c87ee40d56eaeef25204547', 'vout': 7},
78 # Missing scriptPubKey
79 {'txid': '9b907ef1e3c26fc71fe4a4b3580bc75264112f95050014157059c736f0202e71', 'vout': 1},
83 # Valid pay-to-pubkey script
84 {'txid': '9b907ef1e3c26fc71fe4a4b3580bc75264112f95050014157059c736f0202e71', 'vout': 0,
85 'scriptPubKey': '76a91460baa0f494b38ce3c940dea67f3804dc52d1fb9488ac'},
87 {'txid': '5b8673686910442c644b1f4993d8f7753c7c8fcb5c87ee40d56eaeef25204547', 'vout': 7,
88 'scriptPubKey': 'badbadbadbad'}
91 outputs
= {'mpLQjfK79b7CCV4VMJWEWAj5Mpx8Up5zxB': 0.1}
93 rawTx
= self
.nodes
[0].createrawtransaction(inputs
, outputs
)
95 # Make sure decoderawtransaction is at least marginally sane
96 decodedRawTx
= self
.nodes
[0].decoderawtransaction(rawTx
)
97 for i
, inp
in enumerate(inputs
):
98 assert_equal(decodedRawTx
["vin"][i
]["txid"], inp
["txid"])
99 assert_equal(decodedRawTx
["vin"][i
]["vout"], inp
["vout"])
101 # Make sure decoderawtransaction throws if there is extra data
102 assert_raises(JSONRPCException
, self
.nodes
[0].decoderawtransaction
, rawTx
+ "00")
104 rawTxSigned
= self
.nodes
[0].signrawtransaction(rawTx
, scripts
, privKeys
)
106 # 3) The transaction has no complete set of signatures
107 assert 'complete' in rawTxSigned
108 assert_equal(rawTxSigned
['complete'], False)
110 # 4) Two script verification errors occurred
111 assert 'errors' in rawTxSigned
112 assert_equal(len(rawTxSigned
['errors']), 2)
114 # 5) Script verification errors have certain properties
115 assert 'txid' in rawTxSigned
['errors'][0]
116 assert 'vout' in rawTxSigned
['errors'][0]
117 assert 'scriptSig' in rawTxSigned
['errors'][0]
118 assert 'sequence' in rawTxSigned
['errors'][0]
119 assert 'error' in rawTxSigned
['errors'][0]
121 # 6) The verification errors refer to the invalid (vin 1) and missing input (vin 2)
122 assert_equal(rawTxSigned
['errors'][0]['txid'], inputs
[1]['txid'])
123 assert_equal(rawTxSigned
['errors'][0]['vout'], inputs
[1]['vout'])
124 assert_equal(rawTxSigned
['errors'][1]['txid'], inputs
[2]['txid'])
125 assert_equal(rawTxSigned
['errors'][1]['vout'], inputs
[2]['vout'])
128 self
.successful_signing_test()
129 self
.script_verification_error_test()
132 if __name__
== '__main__':
133 SignRawTransactionsTest().main()