def sign_transaction(self, keystore, tx: PartialTransaction, prev_tx): self.prev_tx = prev_tx client = self.get_client(keystore) inputs = self.tx_inputs(tx, for_sig=True, keystore=keystore) outputs = self.tx_outputs(tx, keystore=keystore) signatures = client.sign_tx(self.get_coin_name(), inputs, outputs, lock_time=tx.locktime, version=tx.version)[0] signatures = [(bh2u(x) + '01') for x in signatures] tx.update_signatures(signatures)
def sign_transaction(self, keystore, tx: PartialTransaction, prev_tx): prev_tx = {bfh(txhash): self.electrum_tx_to_txtype(tx) for txhash, tx in prev_tx.items()} client = self.get_client(keystore) inputs = self.tx_inputs(tx, for_sig=True, keystore=keystore) outputs = self.tx_outputs(tx, keystore=keystore) details = SignTx(lock_time=tx.locktime, version=tx.version) signatures, _ = client.sign_tx(self.get_coin_name(), inputs, outputs, details=details, prev_txes=prev_tx) signatures = [(bh2u(x) + '01') for x in signatures] tx.update_signatures(signatures)
def sign_transaction(self, keystore, tx: PartialTransaction, prev_tx): prev_tx = {bfh(txhash): self.electrum_tx_to_txtype(tx) for txhash, tx in prev_tx.items()} if not self.client: raise Exception("client is None") xpub = keystore.xpub derivation = keystore.get_derivation_prefix() if not self.force_pair_with_xpub(self.client, xpub, derivation): raise Exception("Can't Pair With You Device When Sign tx") inputs = self.tx_inputs(tx, for_sig=True, keystore=keystore) outputs = self.tx_outputs(tx, keystore=keystore) details = SignTx(lock_time=tx.locktime, version=tx.version) signatures, _ = self.client.sign_tx(self.get_coin_name(), inputs, outputs, details=details, prev_txes=prev_tx) signatures = [(bh2u(x) + '01') for x in signatures] tx.update_signatures(signatures) raise Exception("sign success")
def sign_transaction( self, keystore: Hardware_KeyStore, tx: PartialTransaction, wallet: Deterministic_Wallet, ): if tx.is_complete(): return if self.bitbox02_device is None: raise Exception( "Need to setup communication first before attempting any BitBox02 calls" ) coin = bitbox02.btc.BTC if constants.net.TESTNET: coin = bitbox02.btc.TBTC tx_script_type = None # Build BTCInputType list inputs = [] for txin in tx.inputs(): my_pubkey, full_path = keystore.find_my_pubkey_in_txinout(txin) if full_path is None: raise Exception( "A wallet owned pubkey was not found in the transaction input to be signed" ) prev_tx = txin.utxo if prev_tx is None: raise UserFacingException(_('Missing previous tx.')) prev_inputs: List[bitbox02.BTCPrevTxInputType] = [] prev_outputs: List[bitbox02.BTCPrevTxOutputType] = [] for prev_txin in prev_tx.inputs(): prev_inputs.append( { "prev_out_hash": prev_txin.prevout.txid[::-1], "prev_out_index": prev_txin.prevout.out_idx, "signature_script": prev_txin.script_sig, "sequence": prev_txin.nsequence, } ) for prev_txout in prev_tx.outputs(): prev_outputs.append( { "value": prev_txout.value, "pubkey_script": prev_txout.scriptpubkey, } ) inputs.append( { "prev_out_hash": txin.prevout.txid[::-1], "prev_out_index": txin.prevout.out_idx, "prev_out_value": txin.value_sats(), "sequence": txin.nsequence, "keypath": full_path, "script_config_index": 0, "prev_tx": { "version": prev_tx.version, "locktime": prev_tx.locktime, "inputs": prev_inputs, "outputs": prev_outputs, }, } ) if tx_script_type == None: tx_script_type = txin.script_type elif tx_script_type != txin.script_type: raise Exception("Cannot mix different input script types") if tx_script_type == "p2wpkh": tx_script_type = bitbox02.btc.BTCScriptConfig( simple_type=bitbox02.btc.BTCScriptConfig.P2WPKH ) elif tx_script_type == "p2wpkh-p2sh": tx_script_type = bitbox02.btc.BTCScriptConfig( simple_type=bitbox02.btc.BTCScriptConfig.P2WPKH_P2SH ) elif tx_script_type == "p2wsh": if type(wallet) is Multisig_Wallet: tx_script_type = self.btc_multisig_config(coin, full_path, wallet) else: raise Exception("Can only use p2wsh with multisig wallets") else: raise UserFacingException( "invalid input script type: {} is not supported by the BitBox02".format( tx_script_type ) ) # Build BTCOutputType list outputs = [] for txout in tx.outputs(): assert txout.address # check for change if txout.is_change: my_pubkey, change_pubkey_path = keystore.find_my_pubkey_in_txinout(txout) outputs.append( bitbox02.BTCOutputInternal( keypath=change_pubkey_path, value=txout.value, script_config_index=0, ) ) else: addrtype, pubkey_hash = bitcoin.address_to_hash(txout.address) if addrtype == OnchainOutputType.P2PKH: output_type = bitbox02.btc.P2PKH elif addrtype == OnchainOutputType.P2SH: output_type = bitbox02.btc.P2SH elif addrtype == OnchainOutputType.WITVER0_P2WPKH: output_type = bitbox02.btc.P2WPKH elif addrtype == OnchainOutputType.WITVER0_P2WSH: output_type = bitbox02.btc.P2WSH else: raise UserFacingException( "Received unsupported output type during transaction signing: {} is not supported by the BitBox02".format( addrtype ) ) outputs.append( bitbox02.BTCOutputExternal( output_type=output_type, output_hash=pubkey_hash, value=txout.value, ) ) if type(wallet) is Standard_Wallet: keypath_account = full_path[:3] elif type(wallet) is Multisig_Wallet: keypath_account = full_path[:4] else: raise Exception( "BitBox02 does not support this wallet type: {}".format(type(wallet)) ) sigs = self.bitbox02_device.btc_sign( coin, [bitbox02.btc.BTCScriptConfigWithKeypath( script_config=tx_script_type, keypath=keypath_account, )], inputs=inputs, outputs=outputs, locktime=tx.locktime, version=tx.version, ) # Fill signatures if len(sigs) != len(tx.inputs()): raise Exception("Incorrect number of inputs signed.") # Should never occur signatures = [bh2u(ecc.der_sig_from_sig_string(x[1])) + "01" for x in sigs] tx.update_signatures(signatures)