@@ -245,6 +245,7 @@ def create_self_transfer_multi(
245
245
utxos_to_spend : Optional [List [dict ]] = None ,
246
246
num_outputs = 1 ,
247
247
amount_per_output = 0 ,
248
+ locktime = 0 ,
248
249
sequence = 0 ,
249
250
fee_per_output = 1000 ,
250
251
target_weight = 0
@@ -257,27 +258,29 @@ def create_self_transfer_multi(
257
258
utxos_to_spend = utxos_to_spend or [self .get_utxo ()]
258
259
sequence = [sequence ] * len (utxos_to_spend ) if type (sequence ) is int else sequence
259
260
assert_equal (len (utxos_to_spend ), len (sequence ))
260
- # create simple tx template (1 input, 1 output)
261
- tx = self .create_self_transfer (
262
- fee_rate = 0 ,
263
- utxo_to_spend = utxos_to_spend [0 ])["tx" ]
264
-
265
- # duplicate inputs, witnesses and outputs
266
- tx .vin = [deepcopy (tx .vin [0 ]) for _ in range (len (utxos_to_spend ))]
267
- for txin , seq in zip (tx .vin , sequence ):
268
- txin .nSequence = seq
269
- tx .wit .vtxinwit = [deepcopy (tx .wit .vtxinwit [0 ]) for _ in range (len (utxos_to_spend ))]
270
- tx .vout = [deepcopy (tx .vout [0 ]) for _ in range (num_outputs )]
271
-
272
- # adapt input prevouts
273
- for i , utxo in enumerate (utxos_to_spend ):
274
- tx .vin [i ] = CTxIn (COutPoint (int (utxo ['txid' ], 16 ), utxo ['vout' ]))
275
-
276
- # adapt output amounts (use fixed fee per output)
261
+
262
+ # calculate output amount
277
263
inputs_value_total = sum ([int (COIN * utxo ['value' ]) for utxo in utxos_to_spend ])
278
264
outputs_value_total = inputs_value_total - fee_per_output * num_outputs
279
- for o in tx .vout :
280
- o .nValue = amount_per_output or (outputs_value_total // num_outputs )
265
+ amount_per_output = amount_per_output or (outputs_value_total // num_outputs )
266
+
267
+ # create tx
268
+ tx = CTransaction ()
269
+ tx .vin = [CTxIn (COutPoint (int (utxo_to_spend ['txid' ], 16 ), utxo_to_spend ['vout' ]), nSequence = seq ) for utxo_to_spend ,seq in zip (utxos_to_spend , sequence )]
270
+ tx .vout = [CTxOut (amount_per_output , bytearray (self ._scriptPubKey )) for _ in range (num_outputs )]
271
+ tx .nLockTime = locktime
272
+
273
+ if self ._mode == MiniWalletMode .RAW_P2PK :
274
+ self .sign_tx (tx )
275
+ elif self ._mode == MiniWalletMode .RAW_OP_TRUE :
276
+ for i in range (len (utxos_to_spend )):
277
+ tx .vin [i ].scriptSig = CScript ([OP_NOP ] * 43 ) # pad to identical size
278
+ elif self ._mode == MiniWalletMode .ADDRESS_OP_TRUE :
279
+ tx .wit .vtxinwit = [CTxInWitness ()] * len (utxos_to_spend )
280
+ for i in range (len (utxos_to_spend )):
281
+ tx .wit .vtxinwit [i ].scriptWitness .stack = [CScript ([OP_TRUE ]), bytes ([LEAF_VERSION_TAPSCRIPT ]) + self ._internal_key ]
282
+ else :
283
+ assert False
281
284
282
285
if target_weight :
283
286
self ._bulk_tx (tx , target_weight )
@@ -300,6 +303,7 @@ def create_self_transfer(self, *, fee_rate=Decimal("0.003"), fee=Decimal("0"), u
300
303
utxo_to_spend = utxo_to_spend or self .get_utxo ()
301
304
assert fee_rate >= 0
302
305
assert fee >= 0
306
+ # calculate fee
303
307
if self ._mode in (MiniWalletMode .RAW_OP_TRUE , MiniWalletMode .ADDRESS_OP_TRUE ):
304
308
vsize = Decimal (104 ) # anyone-can-spend
305
309
elif self ._mode == MiniWalletMode .RAW_P2PK :
@@ -309,29 +313,12 @@ def create_self_transfer(self, *, fee_rate=Decimal("0.003"), fee=Decimal("0"), u
309
313
send_value = utxo_to_spend ["value" ] - (fee or (fee_rate * vsize / 1000 ))
310
314
assert send_value > 0
311
315
312
- tx = CTransaction ()
313
- tx .vin = [CTxIn (COutPoint (int (utxo_to_spend ['txid' ], 16 ), utxo_to_spend ['vout' ]), nSequence = sequence )]
314
- tx .vout = [CTxOut (int (COIN * send_value ), bytearray (self ._scriptPubKey ))]
315
- tx .nLockTime = locktime
316
- if self ._mode == MiniWalletMode .RAW_P2PK :
317
- self .sign_tx (tx )
318
- elif self ._mode == MiniWalletMode .RAW_OP_TRUE :
319
- tx .vin [0 ].scriptSig = CScript ([OP_NOP ] * 43 ) # pad to identical size
320
- elif self ._mode == MiniWalletMode .ADDRESS_OP_TRUE :
321
- tx .wit .vtxinwit = [CTxInWitness ()]
322
- tx .wit .vtxinwit [0 ].scriptWitness .stack = [CScript ([OP_TRUE ]), bytes ([LEAF_VERSION_TAPSCRIPT ]) + self ._internal_key ]
323
- else :
324
- assert False
325
-
326
- assert_equal (tx .get_vsize (), vsize )
327
-
328
- if target_weight :
329
- self ._bulk_tx (tx , target_weight )
330
-
331
- tx_hex = tx .serialize ().hex ()
332
- new_utxo = self ._create_utxo (txid = tx .rehash (), vout = 0 , value = send_value , height = 0 )
316
+ # create tx
317
+ tx = self .create_self_transfer_multi (utxos_to_spend = [utxo_to_spend ], locktime = locktime , sequence = sequence , amount_per_output = int (COIN * send_value ), target_weight = target_weight )
318
+ if not target_weight :
319
+ assert_equal (tx ["tx" ].get_vsize (), vsize )
333
320
334
- return {"txid" : new_utxo ["txid" ], "wtxid" : tx .getwtxid (), "hex" : tx_hex , "tx" : tx , "new_utxo" : new_utxo }
321
+ return {"txid" : tx ["txid" ], "wtxid" : tx [ "tx" ] .getwtxid (), "hex" : tx [ "hex" ] , "tx" : tx [ "tx" ] , "new_utxo" : tx [ "new_utxos" ][ 0 ] }
335
322
336
323
def sendrawtransaction (self , * , from_node , tx_hex , maxfeerate = 0 , ** kwargs ):
337
324
txid = from_node .sendrawtransaction (hexstring = tx_hex , maxfeerate = maxfeerate , ** kwargs )
0 commit comments