@@ -215,6 +215,7 @@ def create_self_transfer_multi(
215215 utxos_to_spend : Optional [List [dict ]] = None ,
216216 num_outputs = 1 ,
217217 amount_per_output = 0 ,
218+ locktime = 0 ,
218219 sequence = 0 ,
219220 fee_per_output = 1000 ,
220221 ):
@@ -226,26 +227,29 @@ def create_self_transfer_multi(
226227 utxos_to_spend = utxos_to_spend or [self .get_utxo ()]
227228 sequence = [sequence ] * len (utxos_to_spend ) if type (sequence ) is int else sequence
228229 assert_equal (len (utxos_to_spend ), len (sequence ))
229- # create simple tx template (1 input, 1 output)
230- tx = self .create_self_transfer (
231- fee_rate = 0 ,
232- utxo_to_spend = utxos_to_spend [0 ])["tx" ]
233-
234- # duplicate inputs, witnesses and outputs
235- tx .vin = [deepcopy (tx .vin [0 ]) for _ in range (len (utxos_to_spend ))]
236- for txin , seq in zip (tx .vin , sequence ):
237- txin .nSequence = seq
238- tx .vout = [deepcopy (tx .vout [0 ]) for _ in range (num_outputs )]
239-
240- # adapt input prevouts
241- for i , utxo in enumerate (utxos_to_spend ):
242- tx .vin [i ] = CTxIn (COutPoint (int (utxo ['txid' ], 16 ), utxo ['vout' ]))
243-
244- # adapt output amounts (use fixed fee per output)
230+
231+ # calculate output amount
245232 inputs_value_total = sum ([int (COIN * utxo ['value' ]) for utxo in utxos_to_spend ])
246233 outputs_value_total = inputs_value_total - fee_per_output * num_outputs
247- for o in tx .vout :
248- o .nValue = amount_per_output or (outputs_value_total // num_outputs )
234+ amount_per_output = amount_per_output or (outputs_value_total // num_outputs )
235+
236+ # create tx
237+ tx = CTransaction ()
238+ 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 )]
239+ tx .vout = [CTxOut (amount_per_output , bytearray (self ._scriptPubKey )) for _ in range (num_outputs )]
240+ tx .nLockTime = locktime
241+
242+ if self ._mode == MiniWalletMode .RAW_P2PK :
243+ self .sign_tx (tx )
244+ elif self ._mode == MiniWalletMode .RAW_OP_TRUE :
245+ for i in range (len (utxos_to_spend )):
246+ tx .vin [i ].scriptSig = CScript ([OP_NOP ] * 24 ) # pad to identical size
247+ elif self ._mode == MiniWalletMode .ADDRESS_OP_TRUE :
248+ for i in range (len (utxos_to_spend )):
249+ tx .vin [i ].scriptSig = CScript ([CScript ([OP_TRUE ])])
250+ else :
251+ assert False
252+
249253 txid = tx .rehash ()
250254 return {
251255 "new_utxos" : [self ._create_utxo (
@@ -264,6 +268,7 @@ def create_self_transfer(self, *, fee_rate=Decimal("0.003"), fee=Decimal("0"), u
264268 utxo_to_spend = utxo_to_spend or self .get_utxo ()
265269 assert fee_rate >= 0
266270 assert fee >= 0
271+ # calculate fee
267272 if self ._mode in (MiniWalletMode .RAW_OP_TRUE , MiniWalletMode .ADDRESS_OP_TRUE ):
268273 vsize = Decimal (85 ) # anyone-can-spend
269274 elif self ._mode == MiniWalletMode .RAW_P2PK :
@@ -273,24 +278,11 @@ def create_self_transfer(self, *, fee_rate=Decimal("0.003"), fee=Decimal("0"), u
273278 send_value = utxo_to_spend ["value" ] - (fee or (fee_rate * vsize / 1000 ))
274279 assert send_value > 0
275280
276- tx = CTransaction ()
277- tx .vin = [CTxIn (COutPoint (int (utxo_to_spend ['txid' ], 16 ), utxo_to_spend ['vout' ]), nSequence = sequence )]
278- tx .vout = [CTxOut (int (COIN * send_value ), bytearray (self ._scriptPubKey ))]
279- tx .nLockTime = locktime
280- if self ._mode == MiniWalletMode .RAW_P2PK :
281- self .sign_tx (tx )
282- elif self ._mode == MiniWalletMode .RAW_OP_TRUE :
283- tx .vin [0 ].scriptSig = CScript ([OP_NOP ] * 24 ) # pad to identical size
284- elif self ._mode == MiniWalletMode .ADDRESS_OP_TRUE :
285- tx .vin [0 ].scriptSig = CScript ([CScript ([OP_TRUE ])])
286- else :
287- assert False
288- tx_hex = tx .serialize ().hex ()
289-
290- assert_equal (tx .get_vsize (), vsize )
291- new_utxo = self ._create_utxo (txid = tx .rehash (), vout = 0 , value = send_value , height = 0 )
281+ # create tx
282+ tx = self .create_self_transfer_multi (utxos_to_spend = [utxo_to_spend ], locktime = locktime , sequence = sequence , amount_per_output = int (COIN * send_value ))
283+ assert_equal (tx ["tx" ].get_vsize (), vsize )
292284
293- return {"txid" : new_utxo ["txid" ], "hex" : tx_hex , "tx" : tx , "new_utxo" : new_utxo }
285+ return {"txid" : tx ["txid" ], "hex" : tx [ "hex" ] , "tx" : tx [ "tx" ] , "new_utxo" : tx [ "new_utxos" ][ 0 ] }
294286
295287 def sendrawtransaction (self , * , from_node , tx_hex , maxfeerate = 0 , ** kwargs ):
296288 txid = from_node .sendrawtransaction (hexstring = tx_hex , maxfeerate = maxfeerate , ** kwargs )
0 commit comments