mirror of
https://github.com/trezor/trezor-firmware.git
synced 2024-11-22 15:38:11 +00:00
Added support for cashaddr.
This commit is contained in:
parent
e1ad1512d0
commit
cb6022ce04
@ -58,6 +58,7 @@ OBJS += ../vendor/trezor-crypto/pbkdf2.o
|
||||
OBJS += ../vendor/trezor-crypto/base32.o
|
||||
OBJS += ../vendor/trezor-crypto/base58.o
|
||||
OBJS += ../vendor/trezor-crypto/segwit_addr.o
|
||||
OBJS += ../vendor/trezor-crypto/cash_addr.o
|
||||
|
||||
OBJS += ../vendor/trezor-crypto/ripemd160.o
|
||||
OBJS += ../vendor/trezor-crypto/sha2.o
|
||||
|
@ -91,6 +91,7 @@ def coin_to_struct(coin):
|
||||
("xprv_magic", format_hex(coin["xprv_magic"])),
|
||||
("forkid", format_number(coin["forkid"])),
|
||||
("bech32_prefix", format_string(coin["bech32_prefix"])),
|
||||
("cashaddr_prefix", format_string(coin["cashaddr_prefix"])),
|
||||
("coin_type", "({} | 0x80000000)".format(format_number(coin["bip44"]))), # noqa: E501
|
||||
("curve_name", "{}_NAME".format(coin["curve_name"].upper())), # noqa: E501
|
||||
("curve", "&{}_info".format(coin["curve_name"])),
|
||||
|
@ -44,6 +44,7 @@ typedef struct _CoinInfo {
|
||||
uint32_t xprv_magic;
|
||||
uint32_t forkid;
|
||||
const char *bech32_prefix;
|
||||
const char *cashaddr_prefix;
|
||||
uint32_t coin_type;
|
||||
const char *curve_name;
|
||||
const curve_info *curve;
|
||||
|
@ -32,9 +32,14 @@
|
||||
#include "messages.pb.h"
|
||||
#include "types.pb.h"
|
||||
#include "segwit_addr.h"
|
||||
#include "cash_addr.h"
|
||||
|
||||
#define SEGWIT_VERSION_0 0
|
||||
|
||||
#define CASHADDR_P2KH (0)
|
||||
#define CASHADDR_P2SH (8)
|
||||
#define CASHADDR_160 (0)
|
||||
|
||||
/* transaction input size (without script): 32 prevhash, 4 idx, 4 sequence */
|
||||
#define TXSIZE_INPUT 40
|
||||
/* transaction output size (without script): 8 amount */
|
||||
@ -138,6 +143,12 @@ bool compute_address(const CoinInfo *coin,
|
||||
if (!base58_encode_check(raw, prelen + 20, coin->curve->hasher_base58, address, MAX_ADDR_SIZE)) {
|
||||
return 0;
|
||||
}
|
||||
} else if (coin->cashaddr_prefix) {
|
||||
raw[0] = CASHADDR_P2SH | CASHADDR_160;
|
||||
ripemd160(digest, 32, raw + 1);
|
||||
if (!cash_addr_encode(address, coin->cashaddr_prefix, raw, 21)) {
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
// non-segwit p2sh multisig
|
||||
prelen = address_prefix_bytes_len(coin->address_type_p2sh);
|
||||
@ -165,6 +176,11 @@ bool compute_address(const CoinInfo *coin,
|
||||
return 0;
|
||||
}
|
||||
ecdsa_get_address_segwit_p2sh(node->public_key, coin->address_type_p2sh, coin->curve->hasher_pubkey, coin->curve->hasher_base58, address, MAX_ADDR_SIZE);
|
||||
} else if (coin->cashaddr_prefix) {
|
||||
ecdsa_get_address_raw(node->public_key, CASHADDR_P2KH | CASHADDR_160, coin->curve->hasher_type, raw);
|
||||
if (!cash_addr_encode(address, coin->cashaddr_prefix, raw, 21)) {
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
ecdsa_get_address(node->public_key, coin->address_type, coin->curve->hasher_pubkey, coin->curve->hasher_base58, address, MAX_ADDR_SIZE);
|
||||
}
|
||||
@ -252,6 +268,28 @@ int compile_output(const CoinInfo *coin, const HDNode *root, TxOutputType *in, T
|
||||
memcpy(out->script_pubkey.bytes + 2, addr_raw + prefix_len, 20);
|
||||
out->script_pubkey.bytes[22] = 0x87; // OP_EQUAL
|
||||
out->script_pubkey.size = 23;
|
||||
} else if (coin->cashaddr_prefix
|
||||
&& cash_addr_decode(addr_raw, &addr_raw_len, coin->cashaddr_prefix, in->address)) {
|
||||
if (addr_raw_len == 21
|
||||
&& addr_raw[0] == (CASHADDR_P2KH | CASHADDR_160)) {
|
||||
out->script_pubkey.bytes[0] = 0x76; // OP_DUP
|
||||
out->script_pubkey.bytes[1] = 0xA9; // OP_HASH_160
|
||||
out->script_pubkey.bytes[2] = 0x14; // pushing 20 bytes
|
||||
memcpy(out->script_pubkey.bytes + 3, addr_raw + 1, 20);
|
||||
out->script_pubkey.bytes[23] = 0x88; // OP_EQUALVERIFY
|
||||
out->script_pubkey.bytes[24] = 0xAC; // OP_CHECKSIG
|
||||
out->script_pubkey.size = 25;
|
||||
|
||||
} else if (addr_raw_len == 21
|
||||
&& addr_raw[0] == (CASHADDR_P2SH | CASHADDR_160)) {
|
||||
out->script_pubkey.bytes[0] = 0xA9; // OP_HASH_160
|
||||
out->script_pubkey.bytes[1] = 0x14; // pushing 20 bytes
|
||||
memcpy(out->script_pubkey.bytes + 2, addr_raw + 1, 20);
|
||||
out->script_pubkey.bytes[22] = 0x87; // OP_EQUAL
|
||||
out->script_pubkey.size = 23;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
} else if (coin->bech32_prefix) {
|
||||
int witver;
|
||||
if (!segwit_addr_decode(&witver, addr_raw, &addr_raw_len, coin->bech32_prefix, in->address)) {
|
||||
@ -736,7 +774,16 @@ uint32_t tx_output_weight(const CoinInfo *coin, const TxOutputType *txoutput) {
|
||||
uint8_t addr_raw[MAX_ADDR_RAW_SIZE];
|
||||
int witver;
|
||||
size_t addr_raw_len;
|
||||
if (coin->bech32_prefix
|
||||
if (coin->cashaddr_prefix
|
||||
&& cash_addr_decode(addr_raw, &addr_raw_len, coin->cashaddr_prefix, txoutput->address)) {
|
||||
if (addr_raw_len == 21
|
||||
&& addr_raw[0] == (CASHADDR_P2KH | CASHADDR_160)) {
|
||||
output_script_size = TXSIZE_P2PKHASH;
|
||||
} else if (addr_raw_len == 21
|
||||
&& addr_raw[0] == (CASHADDR_P2SH | CASHADDR_160)) {
|
||||
output_script_size = TXSIZE_P2SCRIPT;
|
||||
}
|
||||
} else if (coin->bech32_prefix
|
||||
&& segwit_addr_decode(&witver, addr_raw, &addr_raw_len, coin->bech32_prefix, txoutput->address)) {
|
||||
output_script_size = 2 + addr_raw_len;
|
||||
} else {
|
||||
|
Loading…
Reference in New Issue
Block a user