1
0
mirror of https://github.com/trezor/trezor-firmware.git synced 2024-12-23 06:48:16 +00:00

Multi-byte address prefixes for segwit

This commit is contained in:
Jochen Hoenicke 2016-12-28 19:16:50 +01:00
parent 52da2fc5e7
commit e67f13ef4b
No known key found for this signature in database
GPG Key ID: EB17C6B5E51193F5

View File

@ -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;