From e67f13ef4bcb0c9bede8f94cede70654098c5051 Mon Sep 17 00:00:00 2001 From: Jochen Hoenicke Date: Wed, 28 Dec 2016 19:16:50 +0100 Subject: [PATCH] Multi-byte address prefixes for segwit --- firmware/transaction.c | 31 ++++++++++++++++--------------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/firmware/transaction.c b/firmware/transaction.c index 9e63ce82d..3cbdd1c3a 100644 --- a/firmware/transaction.c +++ b/firmware/transaction.c @@ -63,7 +63,7 @@ int compile_output(const CoinType *coin, const HDNode *root, TxOutputType *in, T memset(out, 0, sizeof(TxOutputBinType)); out->amount = in->amount; uint8_t addr_raw[MAX_ADDR_RAW_SIZE]; - int addr_raw_len; + size_t addr_raw_len; if (in->has_address) { // address provided -> regular output addr_raw_len = base58_decode_check(in->address, addr_raw, MAX_ADDR_RAW_SIZE); @@ -76,36 +76,37 @@ int compile_output(const CoinType *coin, const HDNode *root, TxOutputType *in, T } } - if (addr_raw_len == 21 && - addr_raw[0] == coin->address_type) { // p2pkh + size_t prefix_len; + if (address_check_prefix(addr_raw, coin->address_type) // p2pkh + && addr_raw_len == 20 + (prefix_len = address_prefix_bytes_len(coin->address_type))) { 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); + memcpy(out->script_pubkey.bytes + 3, addr_raw + prefix_len, 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] == coin->address_type_p2sh) { // p2sh + } else if (address_check_prefix(addr_raw, coin->address_type_p2sh) // p2sh + && addr_raw_len == 20 + (prefix_len = address_prefix_bytes_len(coin->address_type_p2sh))) { 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); + 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 (addr_raw_len == 23 - && addr_raw[0] == coin->address_type_p2wpkh - && addr_raw[1] == 0 && addr_raw[2] == 0) { // p2wpkh v0 + } else if (address_check_prefix(addr_raw, coin->address_type_p2wpkh) + && addr_raw_len == 22 + (prefix_len = address_prefix_bytes_len(coin->address_type_p2wpkh)) + && addr_raw[prefix_len] == 0 && addr_raw[prefix_len + 1] == 0) { // p2wpkh v0 out->script_pubkey.bytes[0] = 0x00; // version 0 out->script_pubkey.bytes[1] = 0x14; // pushing 20 bytes - memcpy(out->script_pubkey.bytes + 2, addr_raw + 3, 20); + memcpy(out->script_pubkey.bytes + 2, addr_raw + prefix_len + 2, 20); out->script_pubkey.size = 22; - } else if (addr_raw_len == 35 - && addr_raw[0] == coin->address_type_p2wsh - && addr_raw[1] == 0 && addr_raw[2] == 0) { // p2wsh v0 + } else if (address_check_prefix(addr_raw, coin->address_type_p2wsh) + && addr_raw_len == 34 + (prefix_len = address_prefix_bytes_len(coin->address_type_p2wsh)) + && addr_raw[prefix_len] == 0 && addr_raw[prefix_len + 1] == 0) { // p2wsh v0 out->script_pubkey.bytes[0] = 0x00; // version 0 out->script_pubkey.bytes[1] = 0x20; // pushing 32 bytes - memcpy(out->script_pubkey.bytes + 2, addr_raw + 3, 32); + memcpy(out->script_pubkey.bytes + 2, addr_raw + prefix_len + 2, 32); out->script_pubkey.size = 34; } else { return 0;