1
0

bitcoin.py/transaction.py: API changes: rm most hex usage

Instead of some functions operating with hex strings,
and others using bytes, this consolidates most things to use bytes.

This mainly focuses on bitcoin.py and transaction.py,
and then adapts the API usages in other files.

Notably,
- scripts,
- pubkeys,
- signatures
should be bytes in almost all places now.
This commit is contained in:
SomberNight
2024-04-26 20:09:00 +00:00
parent 5e08d6e486
commit 2f1095510c
33 changed files with 429 additions and 465 deletions

View File

@@ -536,8 +536,8 @@ class BitBox02Client(HardwareClientBase):
# Fill signatures
if len(sigs) != len(tx.inputs()):
raise Exception("Incorrect number of inputs signed.") # Should never occur
sighash = Sighash.to_sigbytes(Sighash.ALL).hex()
signatures = [ecc.ecdsa_der_sig_from_ecdsa_sig64(x[1]).hex() + sighash for x in sigs]
sighash = Sighash.to_sigbytes(Sighash.ALL)
signatures = [ecc.ecdsa_der_sig_from_ecdsa_sig64(x[1]) + sighash for x in sigs]
tx.update_signatures(signatures)
def sign_message(self, keypath: str, message: bytes, script_type: str) -> bytes:

View File

@@ -600,7 +600,7 @@ class ColdcardPlugin(HW_PluginBase):
xfp_int = xfp_int_from_xfp_bytes(fp_bytes)
xfp_paths.append([xfp_int] + list(der_full))
script = bfh(wallet.pubkeys_to_scriptcode(pubkey_hexes))
script = wallet.pubkeys_to_scriptcode(pubkey_hexes)
keystore.show_p2sh_address(wallet.m, script, xfp_paths, txin_type)

View File

@@ -547,7 +547,7 @@ class DigitalBitbox_KeyStore(Hardware_KeyStore):
if not inputPath:
self.give_error("No matching pubkey for sign_transaction") # should never happen
inputPath = convert_bip32_intpath_to_strpath(inputPath)
inputHash = sha256d(bfh(tx.serialize_preimage(i)))
inputHash = sha256d(tx.serialize_preimage(i))
hasharray_i = {'hash': to_hexstr(inputHash), 'keypath': inputPath}
hasharray.append(hasharray_i)
inputhasharray.append(inputHash)
@@ -659,8 +659,8 @@ class DigitalBitbox_KeyStore(Hardware_KeyStore):
sig_r = int(signed['sig'][:64], 16)
sig_s = int(signed['sig'][64:], 16)
sig = ecc.ecdsa_der_sig_from_r_and_s(sig_r, sig_s)
sig = to_hexstr(sig) + Sighash.to_sigbytes(Sighash.ALL).hex()
tx.add_signature_to_txin(txin_idx=i, signing_pubkey=pubkey_bytes.hex(), sig=sig)
sig = sig + Sighash.to_sigbytes(Sighash.ALL)
tx.add_signature_to_txin(txin_idx=i, signing_pubkey=pubkey_bytes, sig=sig)
except UserCancelled:
raise
except BaseException as e:

View File

@@ -268,7 +268,6 @@ class Jade_KeyStore(Hardware_KeyStore):
pubkey, path = self.find_my_pubkey_in_txinout(txin)
witness_input = txin.is_segwit()
redeem_script = Transaction.get_preimage_script(txin)
redeem_script = bytes.fromhex(redeem_script) if redeem_script is not None else None
input_tx = txin.utxo
input_tx = bytes.fromhex(input_tx.serialize()) if input_tx is not None else None
@@ -314,9 +313,11 @@ class Jade_KeyStore(Hardware_KeyStore):
for index, (txin, signature) in enumerate(zip(tx.inputs(), signatures)):
pubkey, path = self.find_my_pubkey_in_txinout(txin)
if pubkey is not None and signature is not None:
tx.add_signature_to_txin(txin_idx=index,
signing_pubkey=pubkey.hex(),
sig=signature.hex())
tx.add_signature_to_txin(
txin_idx=index,
signing_pubkey=pubkey,
sig=signature,
)
finally:
self.handler.finished()

View File

@@ -266,8 +266,8 @@ class KeepKeyPlugin(HW_PluginBase):
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]
sighash = Sighash.to_sigbytes(Sighash.ALL).hex()
signatures = [(x.hex() + sighash) for x in signatures]
sighash = Sighash.to_sigbytes(Sighash.ALL)
signatures = [(sig + sighash) for sig in signatures]
tx.update_signatures(signatures)
@runs_in_hwd_thread

View File

@@ -9,7 +9,7 @@ from typing import Dict, List, Optional, Sequence, Tuple, TYPE_CHECKING
from electrum import bip32, constants, ecc
from electrum import descriptor
from electrum.bip32 import BIP32Node, convert_bip32_intpath_to_strpath, normalize_bip32_derivation
from electrum.bitcoin import EncodeBase58Check, int_to_hex, is_b58_address, is_segwit_script_type, var_int
from electrum.bitcoin import EncodeBase58Check, is_b58_address, is_segwit_script_type, var_int
from electrum.crypto import hash_160
from electrum.i18n import _
from electrum.keystore import Hardware_KeyStore
@@ -584,7 +584,7 @@ class Ledger_Client_Legacy(Ledger_Client):
self.give_error("No matching pubkey for sign_transaction") # should never happen
full_path = convert_bip32_intpath_to_strpath(full_path)[2:]
redeemScript = Transaction.get_preimage_script(txin)
redeemScript = Transaction.get_preimage_script(txin).hex()
txin_prev_tx = txin.utxo
if txin_prev_tx is None and not txin.is_segwit():
raise UserFacingException(_('Missing previous tx for legacy input.'))
@@ -604,13 +604,14 @@ class Ledger_Client_Legacy(Ledger_Client):
if not is_txin_legacy_multisig(txin):
self.give_error("P2SH / regular input mixed in same transaction not supported") # should never happen
txOutput = var_int(len(tx.outputs()))
txOutput = bytearray()
txOutput += var_int(len(tx.outputs()))
for o in tx.outputs():
txOutput += int_to_hex(o.value, 8)
script = o.scriptpubkey.hex()
txOutput += var_int(len(script) // 2)
txOutput += int.to_bytes(o.value, length=8, byteorder="little", signed=False)
script = o.scriptpubkey
txOutput += var_int(len(script))
txOutput += script
txOutput = bfh(txOutput)
txOutput = bytes(txOutput)
if not self.supports_multi_output():
if len(tx.outputs()) > 2:
@@ -649,11 +650,11 @@ class Ledger_Client_Legacy(Ledger_Client):
# Get trusted inputs from the original transactions
for input_idx, utxo in enumerate(inputs):
self.handler.show_message(_("Preparing transaction inputs...") + f" (phase1, {input_idx}/{len(inputs)})")
sequence = int_to_hex(utxo[5], 4)
sequence = int.to_bytes(utxo[5], length=4, byteorder="little", signed=False)
if segwitTransaction and not self.supports_segwit_trustedInputs():
tmp = bfh(utxo[3])[::-1]
tmp += bfh(int_to_hex(utxo[1], 4))
tmp += bfh(int_to_hex(utxo[6], 8)) # txin['value']
tmp += int.to_bytes(utxo[1], length=4, byteorder="little", signed=False)
tmp += int.to_bytes(utxo[6], length=8, byteorder="little", signed=False) # txin['value']
chipInputs.append({'value': tmp, 'witness': True, 'sequence': sequence})
redeemScripts.append(bfh(utxo[2]))
elif (not p2shTransaction) or self.supports_multi_output():
@@ -669,7 +670,7 @@ class Ledger_Client_Legacy(Ledger_Client):
redeemScripts.append(txtmp.outputs[utxo[1]].script)
else:
tmp = bfh(utxo[3])[::-1]
tmp += bfh(int_to_hex(utxo[1], 4))
tmp += int.to_bytes(utxo[1], length=4, byteorder="little", signed=False)
chipInputs.append({'value': tmp, 'sequence': sequence})
redeemScripts.append(bfh(utxo[2]))
@@ -703,8 +704,8 @@ class Ledger_Client_Legacy(Ledger_Client):
inputSignature[0] = 0x30 # force for 1.4.9+
my_pubkey = inputs[inputIndex][4]
tx.add_signature_to_txin(txin_idx=inputIndex,
signing_pubkey=my_pubkey.hex(),
sig=inputSignature.hex())
signing_pubkey=my_pubkey,
sig=inputSignature)
inputIndex = inputIndex + 1
else:
while inputIndex < len(inputs):
@@ -728,8 +729,8 @@ class Ledger_Client_Legacy(Ledger_Client):
inputSignature[0] = 0x30 # force for 1.4.9+
my_pubkey = inputs[inputIndex][4]
tx.add_signature_to_txin(txin_idx=inputIndex,
signing_pubkey=my_pubkey.hex(),
sig=inputSignature.hex())
signing_pubkey=my_pubkey,
sig=inputSignature)
inputIndex = inputIndex + 1
firstTransaction = False
except UserWarning:
@@ -1247,7 +1248,7 @@ class Ledger_Client_New(Ledger_Client):
input_sigs = self.client.sign_psbt(psbt, wallet, wallet_hmac)
for idx, part_sig in input_sigs:
tx.add_signature_to_txin(
txin_idx=idx, signing_pubkey=part_sig.pubkey.hex(), sig=part_sig.signature.hex())
txin_idx=idx, signing_pubkey=part_sig.pubkey, sig=part_sig.signature)
except DenyError:
pass # cancelled by user
except BaseException as e:

View File

@@ -236,8 +236,8 @@ class SafeTPlugin(HW_PluginBase):
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]
sighash = Sighash.to_sigbytes(Sighash.ALL).hex()
signatures = [(x.hex() + sighash) for x in signatures]
sighash = Sighash.to_sigbytes(Sighash.ALL)
signatures = [(sig + sighash) for sig in signatures]
tx.update_signatures(signatures)
@runs_in_hwd_thread

View File

@@ -346,8 +346,8 @@ class TrezorPlugin(HW_PluginBase):
amount_unit=self.get_trezor_amount_unit(),
serialize=False,
prev_txes=prev_tx)
sighash = Sighash.to_sigbytes(Sighash.ALL).hex()
signatures = [((x.hex() + sighash) if x else None) for x in signatures]
sighash = Sighash.to_sigbytes(Sighash.ALL)
signatures = [((sig + sighash) if sig else None) for sig in signatures]
tx.update_signatures(signatures)
@runs_in_hwd_thread