mirror of
https://github.com/trezor/trezor-firmware.git
synced 2025-02-01 18:30:56 +00:00
signing/multisig: get_address for change outputs, address_n check
This commit is contained in:
parent
8715e20b79
commit
6a73a7922b
@ -19,7 +19,7 @@ class AddressError(Exception):
|
||||
pass
|
||||
|
||||
|
||||
def get_address(script_type: InputScriptType, coin: CoinType, node) -> str:
|
||||
def get_address(script_type: InputScriptType, coin: CoinType, node, multisig=None) -> str:
|
||||
|
||||
if script_type == InputScriptType.SPENDADDRESS: # p2pkh
|
||||
return node.address(coin.address_type)
|
||||
@ -36,6 +36,21 @@ def get_address(script_type: InputScriptType, coin: CoinType, node) -> str:
|
||||
'Segwit not enabled on this coin')
|
||||
return address_p2wpkh_in_p2sh(node.public_key(), coin.address_type_p2sh)
|
||||
|
||||
elif script_type == InputScriptType.SPENDMULTISIG: # multisig
|
||||
if multisig is None:
|
||||
raise AddressError(FailureType.ProcessError,
|
||||
'Multisig details required')
|
||||
pubkey = node.public_key()
|
||||
index = multisig_pubkey_index(multisig, pubkey)
|
||||
if index is None:
|
||||
raise AddressError(FailureType.ProcessError,
|
||||
'Public key not found')
|
||||
if coin.address_type_p2sh is None:
|
||||
raise AddressError(FailureType.ProcessError,
|
||||
'Multisig not enabled on this coin')
|
||||
|
||||
return address_multisig_p2sh(multisig_get_pubkeys(multisig), multisig.m, coin.address_type_p2sh)
|
||||
|
||||
else:
|
||||
raise AddressError(FailureType.ProcessError,
|
||||
'Invalid script type')
|
||||
|
@ -29,3 +29,10 @@ def multisig_get_pubkey(hd: HDNodePathType) -> bytes:
|
||||
|
||||
def multisig_get_pubkeys(multisig: MultisigRedeemScriptType):
|
||||
return [multisig_get_pubkey(hd) for hd in multisig.pubkeys]
|
||||
|
||||
|
||||
def check_address_n_against_pubkeys(multisig: MultisigRedeemScriptType, address_n) -> bool:
|
||||
for p in multisig.pubkeys:
|
||||
if p.address_n == address_n:
|
||||
return True
|
||||
return False
|
||||
|
@ -122,14 +122,14 @@ def input_script_multisig(current_signature, other_signatures, pubkeys, m: int):
|
||||
|
||||
|
||||
# returns a ripedm(sha256()) hash of a multisig script used in P2SH
|
||||
def output_script_multisig_p2sh(pubkeys, m) -> HashWriter:
|
||||
def output_script_multisig_p2sh(pubkeys, m) -> bytes:
|
||||
script = script_multisig(pubkeys, m)
|
||||
h = sha256(script).digest()
|
||||
return ripemd160(h).digest()
|
||||
|
||||
|
||||
# returns a sha256() hash of a multisig script used in native P2WSH
|
||||
def output_script_multisig_p2wsh(pubkeys, m) -> HashWriter:
|
||||
def output_script_multisig_p2wsh(pubkeys, m) -> bytes:
|
||||
for pubkey in pubkeys:
|
||||
if len(pubkey) != 33:
|
||||
raise Exception # only compressed public keys are allowed for P2WSH
|
||||
@ -137,7 +137,7 @@ def output_script_multisig_p2wsh(pubkeys, m) -> HashWriter:
|
||||
return sha256(script).digest()
|
||||
|
||||
|
||||
def script_multisig(pubkeys, m) -> bytes:
|
||||
def script_multisig(pubkeys, m) -> bytearray:
|
||||
n = len(pubkeys)
|
||||
if n < 1 or n > 15:
|
||||
raise Exception
|
||||
|
@ -438,6 +438,10 @@ def output_derive_script(o: TxOutputType, coin: CoinType, root) -> bytes:
|
||||
if o.address_n: # change output
|
||||
if o.address:
|
||||
raise SigningError(FailureType.DataError, 'Address in change output')
|
||||
if o.multisig:
|
||||
if not check_address_n_against_pubkeys(o.multisig, o.address_n):
|
||||
raise AddressError(FailureType.ProcessError,
|
||||
'address_n must match one of the address_n in the MultisigRedeemScriptType pubkeys')
|
||||
o.address = get_address_for_change(o, coin, root)
|
||||
else:
|
||||
if not o.address:
|
||||
@ -471,7 +475,7 @@ def get_address_for_change(o: TxOutputType, coin: CoinType, root):
|
||||
input_script_type = InputScriptType.SPENDP2SHWITNESS
|
||||
else:
|
||||
raise SigningError(FailureType.DataError, 'Invalid script type')
|
||||
return get_address(input_script_type, coin, node_derive(root, o.address_n))
|
||||
return get_address(input_script_type, coin, node_derive(root, o.address_n), o.multisig)
|
||||
|
||||
|
||||
def output_is_change(o: TxOutputType, wallet_path: list, segwit_in: int) -> bool:
|
||||
|
Loading…
Reference in New Issue
Block a user