@@ -245,6 +245,7 @@ def create_self_transfer_multi(
245245 utxos_to_spend : Optional [List [dict ]] = None ,
246246 num_outputs = 1 ,
247247 amount_per_output = 0 ,
248+ locktime = 0 ,
248249 sequence = 0 ,
249250 fee_per_output = 1000 ,
250251 target_weight = 0
@@ -257,27 +258,29 @@ def create_self_transfer_multi(
257258 utxos_to_spend = utxos_to_spend or [self .get_utxo ()]
258259 sequence = [sequence ] * len (utxos_to_spend ) if type (sequence ) is int else sequence
259260 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
277263 inputs_value_total = sum ([int (COIN * utxo ['value' ]) for utxo in utxos_to_spend ])
278264 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
281284
282285 if target_weight :
283286 self ._bulk_tx (tx , target_weight )
@@ -300,6 +303,7 @@ def create_self_transfer(self, *, fee_rate=Decimal("0.003"), fee=Decimal("0"), u
300303 utxo_to_spend = utxo_to_spend or self .get_utxo ()
301304 assert fee_rate >= 0
302305 assert fee >= 0
306+ # calculate fee
303307 if self ._mode in (MiniWalletMode .RAW_OP_TRUE , MiniWalletMode .ADDRESS_OP_TRUE ):
304308 vsize = Decimal (104 ) # anyone-can-spend
305309 elif self ._mode == MiniWalletMode .RAW_P2PK :
@@ -309,29 +313,12 @@ def create_self_transfer(self, *, fee_rate=Decimal("0.003"), fee=Decimal("0"), u
309313 send_value = utxo_to_spend ["value" ] - (fee or (fee_rate * vsize / 1000 ))
310314 assert send_value > 0
311315
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 )
333320
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 ] }
335322
336323 def sendrawtransaction (self , * , from_node , tx_hex , maxfeerate = 0 , ** kwargs ):
337324 txid = from_node .sendrawtransaction (hexstring = tx_hex , maxfeerate = maxfeerate , ** kwargs )
0 commit comments