You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

fundrawtransaction.py 24KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604
  1. #!/usr/bin/env python2
  2. # Copyright (c) 2014-2015 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. from test_framework.test_framework import BitcoinTestFramework
  6. from test_framework.util import *
  7. from pprint import pprint
  8. from time import sleep
  9. # Create one-input, one-output, no-fee transaction:
  10. class RawTransactionsTest(BitcoinTestFramework):
  11. def setup_chain(self):
  12. print("Initializing test directory "+self.options.tmpdir)
  13. initialize_chain_clean(self.options.tmpdir, 4)
  14. def setup_network(self, split=False):
  15. self.nodes = start_nodes(4, self.options.tmpdir)
  16. connect_nodes_bi(self.nodes,0,1)
  17. connect_nodes_bi(self.nodes,1,2)
  18. connect_nodes_bi(self.nodes,0,2)
  19. connect_nodes_bi(self.nodes,0,3)
  20. self.is_network_split=False
  21. self.sync_all()
  22. def run_test(self):
  23. print "Mining blocks..."
  24. min_relay_tx_fee = self.nodes[0].getnetworkinfo()['relayfee']
  25. # if the fee's positive delta is higher than this value tests will fail,
  26. # neg. delta always fail the tests.
  27. # The size of the signature of every input may be at most 2 bytes larger
  28. # than a minimum sized signature.
  29. # = 2 bytes * minRelayTxFeePerByte
  30. feeTolerance = 2 * min_relay_tx_fee/1000
  31. self.nodes[2].generate(1)
  32. self.sync_all()
  33. self.nodes[0].generate(121)
  34. self.sync_all()
  35. watchonly_address = self.nodes[0].getnewaddress()
  36. watchonly_pubkey = self.nodes[0].validateaddress(watchonly_address)["pubkey"]
  37. watchonly_amount = 200
  38. self.nodes[3].importpubkey(watchonly_pubkey, "", True)
  39. watchonly_txid = self.nodes[0].sendtoaddress(watchonly_address, watchonly_amount)
  40. self.nodes[0].sendtoaddress(self.nodes[3].getnewaddress(), watchonly_amount / 10);
  41. self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(),1.5);
  42. self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(),1.0);
  43. self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(),5.0);
  44. self.sync_all()
  45. self.nodes[0].generate(1)
  46. self.sync_all()
  47. ###############
  48. # simple test #
  49. ###############
  50. inputs = [ ]
  51. outputs = { self.nodes[0].getnewaddress() : 1.0 }
  52. rawtx = self.nodes[2].createrawtransaction(inputs, outputs)
  53. dec_tx = self.nodes[2].decoderawtransaction(rawtx)
  54. rawtxfund = self.nodes[2].fundrawtransaction(rawtx)
  55. fee = rawtxfund['fee']
  56. dec_tx = self.nodes[2].decoderawtransaction(rawtxfund['hex'])
  57. assert_equal(len(dec_tx['vin']) > 0, True) #test if we have enought inputs
  58. ##############################
  59. # simple test with two coins #
  60. ##############################
  61. inputs = [ ]
  62. outputs = { self.nodes[0].getnewaddress() : 2.2 }
  63. rawtx = self.nodes[2].createrawtransaction(inputs, outputs)
  64. dec_tx = self.nodes[2].decoderawtransaction(rawtx)
  65. rawtxfund = self.nodes[2].fundrawtransaction(rawtx)
  66. fee = rawtxfund['fee']
  67. dec_tx = self.nodes[2].decoderawtransaction(rawtxfund['hex'])
  68. assert_equal(len(dec_tx['vin']) > 0, True) #test if we have enough inputs
  69. ##############################
  70. # simple test with two coins #
  71. ##############################
  72. inputs = [ ]
  73. outputs = { self.nodes[0].getnewaddress() : 2.6 }
  74. rawtx = self.nodes[2].createrawtransaction(inputs, outputs)
  75. dec_tx = self.nodes[2].decoderawtransaction(rawtx)
  76. rawtxfund = self.nodes[2].fundrawtransaction(rawtx)
  77. fee = rawtxfund['fee']
  78. dec_tx = self.nodes[2].decoderawtransaction(rawtxfund['hex'])
  79. assert_equal(len(dec_tx['vin']) > 0, True)
  80. assert_equal(dec_tx['vin'][0]['scriptSig']['hex'], '')
  81. ################################
  82. # simple test with two outputs #
  83. ################################
  84. inputs = [ ]
  85. outputs = { self.nodes[0].getnewaddress() : 2.6, self.nodes[1].getnewaddress() : 2.5 }
  86. rawtx = self.nodes[2].createrawtransaction(inputs, outputs)
  87. dec_tx = self.nodes[2].decoderawtransaction(rawtx)
  88. rawtxfund = self.nodes[2].fundrawtransaction(rawtx)
  89. fee = rawtxfund['fee']
  90. dec_tx = self.nodes[2].decoderawtransaction(rawtxfund['hex'])
  91. totalOut = 0
  92. for out in dec_tx['vout']:
  93. totalOut += out['value']
  94. assert_equal(len(dec_tx['vin']) > 0, True)
  95. assert_equal(dec_tx['vin'][0]['scriptSig']['hex'], '')
  96. #########################################################################
  97. # test a fundrawtransaction with a VIN greater than the required amount #
  98. #########################################################################
  99. utx = False
  100. listunspent = self.nodes[2].listunspent()
  101. for aUtx in listunspent:
  102. if aUtx['amount'] == 5.0:
  103. utx = aUtx
  104. break;
  105. assert_equal(utx!=False, True)
  106. inputs = [ {'txid' : utx['txid'], 'vout' : utx['vout']}]
  107. outputs = { self.nodes[0].getnewaddress() : 1.0 }
  108. rawtx = self.nodes[2].createrawtransaction(inputs, outputs)
  109. dec_tx = self.nodes[2].decoderawtransaction(rawtx)
  110. assert_equal(utx['txid'], dec_tx['vin'][0]['txid'])
  111. rawtxfund = self.nodes[2].fundrawtransaction(rawtx)
  112. fee = rawtxfund['fee']
  113. dec_tx = self.nodes[2].decoderawtransaction(rawtxfund['hex'])
  114. totalOut = 0
  115. for out in dec_tx['vout']:
  116. totalOut += out['value']
  117. assert_equal(fee + totalOut, utx['amount']) #compare vin total and totalout+fee
  118. #####################################################################
  119. # test a fundrawtransaction with which will not get a change output #
  120. #####################################################################
  121. utx = False
  122. listunspent = self.nodes[2].listunspent()
  123. for aUtx in listunspent:
  124. if aUtx['amount'] == 5.0:
  125. utx = aUtx
  126. break;
  127. assert_equal(utx!=False, True)
  128. inputs = [ {'txid' : utx['txid'], 'vout' : utx['vout']}]
  129. outputs = { self.nodes[0].getnewaddress() : Decimal(5.0) - fee - feeTolerance }
  130. rawtx = self.nodes[2].createrawtransaction(inputs, outputs)
  131. dec_tx = self.nodes[2].decoderawtransaction(rawtx)
  132. assert_equal(utx['txid'], dec_tx['vin'][0]['txid'])
  133. rawtxfund = self.nodes[2].fundrawtransaction(rawtx)
  134. fee = rawtxfund['fee']
  135. dec_tx = self.nodes[2].decoderawtransaction(rawtxfund['hex'])
  136. totalOut = 0
  137. for out in dec_tx['vout']:
  138. totalOut += out['value']
  139. assert_equal(rawtxfund['changepos'], -1)
  140. assert_equal(fee + totalOut, utx['amount']) #compare vin total and totalout+fee
  141. #########################################################################
  142. # test a fundrawtransaction with a VIN smaller than the required amount #
  143. #########################################################################
  144. utx = False
  145. listunspent = self.nodes[2].listunspent()
  146. for aUtx in listunspent:
  147. if aUtx['amount'] == 1.0:
  148. utx = aUtx
  149. break;
  150. assert_equal(utx!=False, True)
  151. inputs = [ {'txid' : utx['txid'], 'vout' : utx['vout']}]
  152. outputs = { self.nodes[0].getnewaddress() : 1.0 }
  153. rawtx = self.nodes[2].createrawtransaction(inputs, outputs)
  154. # 4-byte version + 1-byte vin count + 36-byte prevout then script_len
  155. rawtx = rawtx[:82] + "0100" + rawtx[84:]
  156. dec_tx = self.nodes[2].decoderawtransaction(rawtx)
  157. assert_equal(utx['txid'], dec_tx['vin'][0]['txid'])
  158. assert_equal("00", dec_tx['vin'][0]['scriptSig']['hex'])
  159. rawtxfund = self.nodes[2].fundrawtransaction(rawtx)
  160. fee = rawtxfund['fee']
  161. dec_tx = self.nodes[2].decoderawtransaction(rawtxfund['hex'])
  162. totalOut = 0
  163. matchingOuts = 0
  164. for i, out in enumerate(dec_tx['vout']):
  165. totalOut += out['value']
  166. if outputs.has_key(out['scriptPubKey']['addresses'][0]):
  167. matchingOuts+=1
  168. else:
  169. assert_equal(i, rawtxfund['changepos'])
  170. assert_equal(utx['txid'], dec_tx['vin'][0]['txid'])
  171. assert_equal("00", dec_tx['vin'][0]['scriptSig']['hex'])
  172. assert_equal(matchingOuts, 1)
  173. assert_equal(len(dec_tx['vout']), 2)
  174. ###########################################
  175. # test a fundrawtransaction with two VINs #
  176. ###########################################
  177. utx = False
  178. utx2 = False
  179. listunspent = self.nodes[2].listunspent()
  180. for aUtx in listunspent:
  181. if aUtx['amount'] == 1.0:
  182. utx = aUtx
  183. if aUtx['amount'] == 5.0:
  184. utx2 = aUtx
  185. assert_equal(utx!=False, True)
  186. inputs = [ {'txid' : utx['txid'], 'vout' : utx['vout']},{'txid' : utx2['txid'], 'vout' : utx2['vout']} ]
  187. outputs = { self.nodes[0].getnewaddress() : 6.0 }
  188. rawtx = self.nodes[2].createrawtransaction(inputs, outputs)
  189. dec_tx = self.nodes[2].decoderawtransaction(rawtx)
  190. assert_equal(utx['txid'], dec_tx['vin'][0]['txid'])
  191. rawtxfund = self.nodes[2].fundrawtransaction(rawtx)
  192. fee = rawtxfund['fee']
  193. dec_tx = self.nodes[2].decoderawtransaction(rawtxfund['hex'])
  194. totalOut = 0
  195. matchingOuts = 0
  196. for out in dec_tx['vout']:
  197. totalOut += out['value']
  198. if outputs.has_key(out['scriptPubKey']['addresses'][0]):
  199. matchingOuts+=1
  200. assert_equal(matchingOuts, 1)
  201. assert_equal(len(dec_tx['vout']), 2)
  202. matchingIns = 0
  203. for vinOut in dec_tx['vin']:
  204. for vinIn in inputs:
  205. if vinIn['txid'] == vinOut['txid']:
  206. matchingIns+=1
  207. assert_equal(matchingIns, 2) #we now must see two vins identical to vins given as params
  208. #########################################################
  209. # test a fundrawtransaction with two VINs and two vOUTs #
  210. #########################################################
  211. utx = False
  212. utx2 = False
  213. listunspent = self.nodes[2].listunspent()
  214. for aUtx in listunspent:
  215. if aUtx['amount'] == 1.0:
  216. utx = aUtx
  217. if aUtx['amount'] == 5.0:
  218. utx2 = aUtx
  219. assert_equal(utx!=False, True)
  220. inputs = [ {'txid' : utx['txid'], 'vout' : utx['vout']},{'txid' : utx2['txid'], 'vout' : utx2['vout']} ]
  221. outputs = { self.nodes[0].getnewaddress() : 6.0, self.nodes[0].getnewaddress() : 1.0 }
  222. rawtx = self.nodes[2].createrawtransaction(inputs, outputs)
  223. dec_tx = self.nodes[2].decoderawtransaction(rawtx)
  224. assert_equal(utx['txid'], dec_tx['vin'][0]['txid'])
  225. rawtxfund = self.nodes[2].fundrawtransaction(rawtx)
  226. fee = rawtxfund['fee']
  227. dec_tx = self.nodes[2].decoderawtransaction(rawtxfund['hex'])
  228. totalOut = 0
  229. matchingOuts = 0
  230. for out in dec_tx['vout']:
  231. totalOut += out['value']
  232. if outputs.has_key(out['scriptPubKey']['addresses'][0]):
  233. matchingOuts+=1
  234. assert_equal(matchingOuts, 2)
  235. assert_equal(len(dec_tx['vout']), 3)
  236. ##############################################
  237. # test a fundrawtransaction with invalid vin #
  238. ##############################################
  239. listunspent = self.nodes[2].listunspent()
  240. inputs = [ {'txid' : "1c7f966dab21119bac53213a2bc7532bff1fa844c124fd750a7d0b1332440bd1", 'vout' : 0} ] #invalid vin!
  241. outputs = { self.nodes[0].getnewaddress() : 1.0}
  242. rawtx = self.nodes[2].createrawtransaction(inputs, outputs)
  243. dec_tx = self.nodes[2].decoderawtransaction(rawtx)
  244. errorString = ""
  245. try:
  246. rawtxfund = self.nodes[2].fundrawtransaction(rawtx)
  247. except JSONRPCException,e:
  248. errorString = e.error['message']
  249. assert_equal("Insufficient" in errorString, True);
  250. ############################################################
  251. #compare fee of a standard pubkeyhash transaction
  252. inputs = []
  253. outputs = {self.nodes[1].getnewaddress():1.1}
  254. rawTx = self.nodes[0].createrawtransaction(inputs, outputs)
  255. fundedTx = self.nodes[0].fundrawtransaction(rawTx)
  256. #create same transaction over sendtoaddress
  257. txId = self.nodes[0].sendtoaddress(self.nodes[1].getnewaddress(), 1.1);
  258. signedFee = self.nodes[0].getrawmempool(True)[txId]['fee']
  259. #compare fee
  260. feeDelta = Decimal(fundedTx['fee']) - Decimal(signedFee);
  261. assert(feeDelta >= 0 and feeDelta <= feeTolerance)
  262. ############################################################
  263. ############################################################
  264. #compare fee of a standard pubkeyhash transaction with multiple outputs
  265. inputs = []
  266. outputs = {self.nodes[1].getnewaddress():1.1,self.nodes[1].getnewaddress():1.2,self.nodes[1].getnewaddress():0.1,self.nodes[1].getnewaddress():1.3,self.nodes[1].getnewaddress():0.2,self.nodes[1].getnewaddress():0.3}
  267. rawTx = self.nodes[0].createrawtransaction(inputs, outputs)
  268. fundedTx = self.nodes[0].fundrawtransaction(rawTx)
  269. #create same transaction over sendtoaddress
  270. txId = self.nodes[0].sendmany("", outputs);
  271. signedFee = self.nodes[0].getrawmempool(True)[txId]['fee']
  272. #compare fee
  273. feeDelta = Decimal(fundedTx['fee']) - Decimal(signedFee);
  274. assert(feeDelta >= 0 and feeDelta <= feeTolerance)
  275. ############################################################
  276. ############################################################
  277. #compare fee of a 2of2 multisig p2sh transaction
  278. # create 2of2 addr
  279. addr1 = self.nodes[1].getnewaddress()
  280. addr2 = self.nodes[1].getnewaddress()
  281. addr1Obj = self.nodes[1].validateaddress(addr1)
  282. addr2Obj = self.nodes[1].validateaddress(addr2)
  283. mSigObj = self.nodes[1].addmultisigaddress(2, [addr1Obj['pubkey'], addr2Obj['pubkey']])
  284. inputs = []
  285. outputs = {mSigObj:1.1}
  286. rawTx = self.nodes[0].createrawtransaction(inputs, outputs)
  287. fundedTx = self.nodes[0].fundrawtransaction(rawTx)
  288. #create same transaction over sendtoaddress
  289. txId = self.nodes[0].sendtoaddress(mSigObj, 1.1);
  290. signedFee = self.nodes[0].getrawmempool(True)[txId]['fee']
  291. #compare fee
  292. feeDelta = Decimal(fundedTx['fee']) - Decimal(signedFee);
  293. assert(feeDelta >= 0 and feeDelta <= feeTolerance)
  294. ############################################################
  295. ############################################################
  296. #compare fee of a standard pubkeyhash transaction
  297. # create 4of5 addr
  298. addr1 = self.nodes[1].getnewaddress()
  299. addr2 = self.nodes[1].getnewaddress()
  300. addr3 = self.nodes[1].getnewaddress()
  301. addr4 = self.nodes[1].getnewaddress()
  302. addr5 = self.nodes[1].getnewaddress()
  303. addr1Obj = self.nodes[1].validateaddress(addr1)
  304. addr2Obj = self.nodes[1].validateaddress(addr2)
  305. addr3Obj = self.nodes[1].validateaddress(addr3)
  306. addr4Obj = self.nodes[1].validateaddress(addr4)
  307. addr5Obj = self.nodes[1].validateaddress(addr5)
  308. mSigObj = self.nodes[1].addmultisigaddress(4, [addr1Obj['pubkey'], addr2Obj['pubkey'], addr3Obj['pubkey'], addr4Obj['pubkey'], addr5Obj['pubkey']])
  309. inputs = []
  310. outputs = {mSigObj:1.1}
  311. rawTx = self.nodes[0].createrawtransaction(inputs, outputs)
  312. fundedTx = self.nodes[0].fundrawtransaction(rawTx)
  313. #create same transaction over sendtoaddress
  314. txId = self.nodes[0].sendtoaddress(mSigObj, 1.1);
  315. signedFee = self.nodes[0].getrawmempool(True)[txId]['fee']
  316. #compare fee
  317. feeDelta = Decimal(fundedTx['fee']) - Decimal(signedFee);
  318. assert(feeDelta >= 0 and feeDelta <= feeTolerance)
  319. ############################################################
  320. ############################################################
  321. # spend a 2of2 multisig transaction over fundraw
  322. # create 2of2 addr
  323. addr1 = self.nodes[2].getnewaddress()
  324. addr2 = self.nodes[2].getnewaddress()
  325. addr1Obj = self.nodes[2].validateaddress(addr1)
  326. addr2Obj = self.nodes[2].validateaddress(addr2)
  327. mSigObj = self.nodes[2].addmultisigaddress(2, [addr1Obj['pubkey'], addr2Obj['pubkey']])
  328. # send 1.2 BTC to msig addr
  329. txId = self.nodes[0].sendtoaddress(mSigObj, 1.2);
  330. self.sync_all()
  331. self.nodes[1].generate(1)
  332. self.sync_all()
  333. oldBalance = self.nodes[1].getbalance()
  334. inputs = []
  335. outputs = {self.nodes[1].getnewaddress():1.1}
  336. rawTx = self.nodes[2].createrawtransaction(inputs, outputs)
  337. fundedTx = self.nodes[2].fundrawtransaction(rawTx)
  338. signedTx = self.nodes[2].signrawtransaction(fundedTx['hex'])
  339. txId = self.nodes[2].sendrawtransaction(signedTx['hex'])
  340. self.sync_all()
  341. self.nodes[1].generate(1)
  342. self.sync_all()
  343. # make sure funds are received at node1
  344. assert_equal(oldBalance+Decimal('1.10000000'), self.nodes[1].getbalance())
  345. ############################################################
  346. # locked wallet test
  347. self.nodes[1].encryptwallet("test")
  348. self.nodes.pop(1)
  349. stop_nodes(self.nodes)
  350. wait_bitcoinds()
  351. self.nodes = start_nodes(4, self.options.tmpdir)
  352. connect_nodes_bi(self.nodes,0,1)
  353. connect_nodes_bi(self.nodes,1,2)
  354. connect_nodes_bi(self.nodes,0,2)
  355. connect_nodes_bi(self.nodes,0,3)
  356. self.is_network_split=False
  357. self.sync_all()
  358. error = False
  359. try:
  360. self.nodes[1].sendtoaddress(self.nodes[0].getnewaddress(), 1.2);
  361. except:
  362. error = True
  363. assert(error)
  364. oldBalance = self.nodes[0].getbalance()
  365. inputs = []
  366. outputs = {self.nodes[0].getnewaddress():1.1}
  367. rawTx = self.nodes[1].createrawtransaction(inputs, outputs)
  368. fundedTx = self.nodes[1].fundrawtransaction(rawTx)
  369. #now we need to unlock
  370. self.nodes[1].walletpassphrase("test", 100)
  371. signedTx = self.nodes[1].signrawtransaction(fundedTx['hex'])
  372. txId = self.nodes[1].sendrawtransaction(signedTx['hex'])
  373. self.sync_all()
  374. self.nodes[1].generate(1)
  375. self.sync_all()
  376. # make sure funds are received at node1
  377. assert_equal(oldBalance+Decimal('51.10000000'), self.nodes[0].getbalance())
  378. ###############################################
  379. # multiple (~19) inputs tx test | Compare fee #
  380. ###############################################
  381. #empty node1, send some small coins from node0 to node1
  382. self.nodes[1].sendtoaddress(self.nodes[0].getnewaddress(), self.nodes[1].getbalance(), "", "", True);
  383. self.sync_all()
  384. self.nodes[0].generate(1)
  385. self.sync_all()
  386. for i in range(0,20):
  387. self.nodes[0].sendtoaddress(self.nodes[1].getnewaddress(), 0.01);
  388. self.sync_all()
  389. self.nodes[0].generate(1)
  390. self.sync_all()
  391. #fund a tx with ~20 small inputs
  392. inputs = []
  393. outputs = {self.nodes[0].getnewaddress():0.15,self.nodes[0].getnewaddress():0.04}
  394. rawTx = self.nodes[1].createrawtransaction(inputs, outputs)
  395. fundedTx = self.nodes[1].fundrawtransaction(rawTx)
  396. #create same transaction over sendtoaddress
  397. txId = self.nodes[1].sendmany("", outputs);
  398. signedFee = self.nodes[1].getrawmempool(True)[txId]['fee']
  399. #compare fee
  400. feeDelta = Decimal(fundedTx['fee']) - Decimal(signedFee);
  401. assert(feeDelta >= 0 and feeDelta <= feeTolerance*19) #~19 inputs
  402. #############################################
  403. # multiple (~19) inputs tx test | sign/send #
  404. #############################################
  405. #again, empty node1, send some small coins from node0 to node1
  406. self.nodes[1].sendtoaddress(self.nodes[0].getnewaddress(), self.nodes[1].getbalance(), "", "", True);
  407. self.sync_all()
  408. self.nodes[0].generate(1)
  409. self.sync_all()
  410. for i in range(0,20):
  411. self.nodes[0].sendtoaddress(self.nodes[1].getnewaddress(), 0.01);
  412. self.sync_all()
  413. self.nodes[0].generate(1)
  414. self.sync_all()
  415. #fund a tx with ~20 small inputs
  416. oldBalance = self.nodes[0].getbalance()
  417. inputs = []
  418. outputs = {self.nodes[0].getnewaddress():0.15,self.nodes[0].getnewaddress():0.04}
  419. rawTx = self.nodes[1].createrawtransaction(inputs, outputs)
  420. fundedTx = self.nodes[1].fundrawtransaction(rawTx)
  421. fundedAndSignedTx = self.nodes[1].signrawtransaction(fundedTx['hex'])
  422. txId = self.nodes[1].sendrawtransaction(fundedAndSignedTx['hex'])
  423. self.sync_all()
  424. self.nodes[0].generate(1)
  425. self.sync_all()
  426. assert_equal(oldBalance+Decimal('50.19000000'), self.nodes[0].getbalance()) #0.19+block reward
  427. #####################################################
  428. # test fundrawtransaction with OP_RETURN and no vin #
  429. #####################################################
  430. rawtx = "0100000000010000000000000000066a047465737400000000"
  431. dec_tx = self.nodes[2].decoderawtransaction(rawtx)
  432. assert_equal(len(dec_tx['vin']), 0)
  433. assert_equal(len(dec_tx['vout']), 1)
  434. rawtxfund = self.nodes[2].fundrawtransaction(rawtx)
  435. dec_tx = self.nodes[2].decoderawtransaction(rawtxfund['hex'])
  436. assert_greater_than(len(dec_tx['vin']), 0) # at least one vin
  437. assert_equal(len(dec_tx['vout']), 2) # one change output added
  438. ##################################################
  439. # test a fundrawtransaction using only watchonly #
  440. ##################################################
  441. inputs = []
  442. outputs = {self.nodes[2].getnewaddress() : watchonly_amount / 2}
  443. rawtx = self.nodes[3].createrawtransaction(inputs, outputs)
  444. result = self.nodes[3].fundrawtransaction(rawtx, True)
  445. res_dec = self.nodes[0].decoderawtransaction(result["hex"])
  446. assert_equal(len(res_dec["vin"]), 1)
  447. assert_equal(res_dec["vin"][0]["txid"], watchonly_txid)
  448. assert_equal("fee" in result.keys(), True)
  449. assert_greater_than(result["changepos"], -1)
  450. ###############################################################
  451. # test fundrawtransaction using the entirety of watched funds #
  452. ###############################################################
  453. inputs = []
  454. outputs = {self.nodes[2].getnewaddress() : watchonly_amount}
  455. rawtx = self.nodes[3].createrawtransaction(inputs, outputs)
  456. result = self.nodes[3].fundrawtransaction(rawtx, True)
  457. res_dec = self.nodes[0].decoderawtransaction(result["hex"])
  458. assert_equal(len(res_dec["vin"]), 2)
  459. assert(res_dec["vin"][0]["txid"] == watchonly_txid or res_dec["vin"][1]["txid"] == watchonly_txid)
  460. assert_greater_than(result["fee"], 0)
  461. assert_greater_than(result["changepos"], -1)
  462. assert_equal(result["fee"] + res_dec["vout"][result["changepos"]]["value"], watchonly_amount / 10)
  463. signedtx = self.nodes[3].signrawtransaction(result["hex"])
  464. assert(not signedtx["complete"])
  465. signedtx = self.nodes[0].signrawtransaction(signedtx["hex"])
  466. assert(signedtx["complete"])
  467. self.nodes[0].sendrawtransaction(signedtx["hex"])
  468. if __name__ == '__main__':
  469. RawTransactionsTest().main()