src/apps/wallet/sign_tx: implement cashaddr

pull/25/head
Pavol Rusnak 6 years ago
parent f2f3d39cf1
commit 0cd3e411f4
No known key found for this signature in database
GPG Key ID: 91F3B339B9A02A3D

@ -1,7 +1,7 @@
from micropython import const from micropython import const
from trezor.crypto.hashlib import sha256, ripemd160 from trezor.crypto.hashlib import sha256, ripemd160
from trezor.crypto import base58, bech32 from trezor.crypto import base58, bech32, cashaddr
from trezor.utils import ensure from trezor.utils import ensure
from trezor.messages import FailureType from trezor.messages import FailureType
@ -34,13 +34,19 @@ def get_address(script_type: InputScriptType, coin: CoinInfo, node, multisig=Non
'Multisig not enabled on this coin') 'Multisig not enabled on this coin')
pubkeys = multisig_get_pubkeys(multisig) pubkeys = multisig_get_pubkeys(multisig)
return address_multisig_p2sh(pubkeys, multisig.m, coin.address_type_p2sh) address = address_multisig_p2sh(pubkeys, multisig.m, coin.address_type_p2sh)
if coin.cashaddr_prefix is not None:
address = address_to_cashaddr(address, coin)
return address
if script_type == InputScriptType.SPENDMULTISIG: if script_type == InputScriptType.SPENDMULTISIG:
raise AddressError(FailureType.ProcessError, raise AddressError(FailureType.ProcessError,
'Multisig details required') 'Multisig details required')
# p2pkh # p2pkh
return node.address(coin.address_type) address = node.address(coin.address_type)
if coin.cashaddr_prefix is not None:
address = address_to_cashaddr(address, coin)
return address
elif script_type == InputScriptType.SPENDWITNESS: # native p2wpkh or native p2wsh elif script_type == InputScriptType.SPENDWITNESS: # native p2wpkh or native p2wsh
if not coin.segwit or not coin.bech32_prefix: if not coin.segwit or not coin.bech32_prefix:
@ -146,6 +152,18 @@ def decode_bech32_address(prefix: str, address: str) -> bytes:
return bytes(raw) return bytes(raw)
def address_to_cashaddr(address: str, coin: CoinInfo) -> str:
raw = base58.decode_check(address)
version, data = raw[0], raw[1:]
if version == coin.address_type:
version = cashaddr.ADDRESS_TYPE_P2KH
elif version == coin.address_type_p2sh:
version = cashaddr.ADDRESS_TYPE_P2SH
else:
raise ValueError('Unknown cashaddr address type')
return cashaddr.encode(coin.cashaddr_prefix, version, data)
def ecdsa_hash_pubkey(pubkey: bytes) -> bytes: def ecdsa_hash_pubkey(pubkey: bytes) -> bytes:
if pubkey[0] == 0x04: if pubkey[0] == 0x04:
ensure(len(pubkey) == 65) # uncompressed format ensure(len(pubkey) == 65) # uncompressed format

@ -1,6 +1,6 @@
from micropython import const from micropython import const
from trezor.crypto import base58, bip32, der from trezor.crypto import base58, bip32, der, cashaddr
from trezor.crypto.curve import secp256k1 from trezor.crypto.curve import secp256k1
from trezor.crypto.hashlib import sha256 from trezor.crypto.hashlib import sha256
from trezor.utils import HashWriter from trezor.utils import HashWriter
@ -465,7 +465,18 @@ def output_derive_script(o: TxOutputType, coin: CoinInfo, root: bip32.HDNode) ->
witprog = decode_bech32_address(coin.bech32_prefix, o.address) witprog = decode_bech32_address(coin.bech32_prefix, o.address)
return output_script_native_p2wpkh_or_p2wsh(witprog) return output_script_native_p2wpkh_or_p2wsh(witprog)
raw_address = base58.decode_check(o.address) if coin.cashaddr_prefix is not None and o.address.startswith(coin.cashaddr_prefix + ':'):
prefix, addr = o.address.split(':')
version, data = cashaddr.decode(prefix, addr)
if version == cashaddr.ADDRESS_TYPE_P2KH:
version = coin.address_type
elif version == cashaddr.ADDRESS_TYPE_P2SH:
version = coin.address_type_p2sh
else:
raise ValueError('Unknown cashaddr address type')
raw_address = bytes([version]) + data
else:
raw_address = base58.decode_check(o.address)
if address_type.check(coin.address_type, raw_address): if address_type.check(coin.address_type, raw_address):
# p2pkh # p2pkh

@ -21,6 +21,8 @@
# THE SOFTWARE. # THE SOFTWARE.
CHARSET = 'qpzry9x8gf2tvdw0s3jn54khce6mua7l' CHARSET = 'qpzry9x8gf2tvdw0s3jn54khce6mua7l'
ADDRESS_TYPE_P2KH = 0
ADDRESS_TYPE_P2SH = 8
def cashaddr_polymod(values): def cashaddr_polymod(values):

Loading…
Cancel
Save