diff --git a/bitcoin/base58.c b/bitcoin/base58.c index 65281af024e0..fe1226867eac 100644 --- a/bitcoin/base58.c +++ b/bitcoin/base58.c @@ -67,40 +67,24 @@ static bool from_base58(u8 *version, return true; } -bool bitcoin_from_base58(bool *test_net, - struct bitcoin_address *addr, +bool bitcoin_from_base58(u8 *version, struct bitcoin_address *addr, const char *base58, size_t len) { - u8 version; - - if (!from_base58(&version, &addr->addr, base58, len)) - return false; - - if (version == 111) - *test_net = true; - else if (version == 0) - *test_net = false; - else - return false; - return true; + return from_base58(version, &addr->addr, base58, len); } -bool p2sh_from_base58(bool *test_net, - struct ripemd160 *p2sh, - const char *base58, size_t len) + +bool p2sh_from_base58(u8 *version, struct ripemd160 *p2sh, const char *base58, + size_t len) { - u8 version; - if (!from_base58(&version, p2sh, base58, len)) - return false; + return from_base58(version, p2sh, base58, len); +} - if (version == 196) - *test_net = true; - else if (version == 5) - *test_net = false; - else - return false; - return true; +bool ripemd160_from_base58(u8 *version, struct ripemd160 *rmd, + const char *base58, size_t base58_len) +{ + return from_base58(version, rmd, base58, base58_len); } bool key_from_base58(const char *base58, size_t base58_len, diff --git a/bitcoin/base58.h b/bitcoin/base58.h index cff8f85e944a..4154b6a3d4db 100644 --- a/bitcoin/base58.h +++ b/bitcoin/base58.h @@ -15,18 +15,20 @@ struct bitcoin_address; /* Bitcoin address encoded in base58, with version and checksum */ char *bitcoin_to_base58(const tal_t *ctx, bool test_net, const struct bitcoin_address *addr); -bool bitcoin_from_base58(bool *test_net, - struct bitcoin_address *addr, +bool bitcoin_from_base58(u8 *version, struct bitcoin_address *addr, const char *base58, size_t len); /* P2SH address encoded as base58, with version and checksum */ char *p2sh_to_base58(const tal_t *ctx, bool test_net, const struct ripemd160 *p2sh); -bool p2sh_from_base58(bool *test_net, - struct ripemd160 *p2sh, - const char *base58, size_t len); +bool p2sh_from_base58(u8 *version, struct ripemd160 *p2sh, const char *base58, + size_t len); bool key_from_base58(const char *base58, size_t base58_len, bool *test_net, struct privkey *priv, struct pubkey *key); +/* Decode a p2pkh or p2sh into the ripemd160 hash */ +bool ripemd160_from_base58(u8 *version, struct ripemd160 *rmd, + const char *base58, size_t base58_len); + #endif /* LIGHTNING_BITCOIN_BASE58_H */ diff --git a/bitcoin/chainparams.c b/bitcoin/chainparams.c index 871ea82059ee..7dd9db9dd531 100644 --- a/bitcoin/chainparams.c +++ b/bitcoin/chainparams.c @@ -28,6 +28,8 @@ const struct chainparams networks[] = { .max_payment = AMOUNT_MSAT_INIT(0xFFFFFFFFULL), /* "Lightning Charge Powers Developers & Blockstream Store" */ .when_lightning_became_cool = 504500, + .p2pkh_version = 0, + .p2sh_version = 5, .testnet = false, .bip32_key_version = {.bip32_pubkey_version = BIP32_VER_MAIN_PUBLIC, .bip32_privkey_version = BIP32_VER_MAIN_PRIVATE}}, {.network_name = "regtest", @@ -40,6 +42,8 @@ const struct chainparams networks[] = { .max_funding = AMOUNT_SAT_INIT((1 << 24) - 1), .max_payment = AMOUNT_MSAT_INIT(0xFFFFFFFFULL), .when_lightning_became_cool = 1, + .p2pkh_version = 111, + .p2sh_version = 196, .testnet = true, .bip32_key_version = {.bip32_pubkey_version = BIP32_VER_TEST_PUBLIC, .bip32_privkey_version = BIP32_VER_TEST_PRIVATE}}, {.network_name = "testnet", @@ -51,6 +55,8 @@ const struct chainparams networks[] = { .dust_limit = { 546 }, .max_funding = AMOUNT_SAT_INIT((1 << 24) - 1), .max_payment = AMOUNT_MSAT_INIT(0xFFFFFFFFULL), + .p2pkh_version = 111, + .p2sh_version = 196, .testnet = true, .bip32_key_version = {.bip32_pubkey_version = BIP32_VER_TEST_PUBLIC, .bip32_privkey_version = BIP32_VER_TEST_PRIVATE}}, {.network_name = "litecoin", @@ -63,6 +69,8 @@ const struct chainparams networks[] = { .max_funding = AMOUNT_SAT_INIT(60 * ((1 << 24) - 1)), .max_payment = AMOUNT_MSAT_INIT(60 * 0xFFFFFFFFULL), .when_lightning_became_cool = 1320000, + .p2pkh_version = 48, + .p2sh_version = 50, .testnet = false, .bip32_key_version = {.bip32_pubkey_version = BIP32_VER_MAIN_PUBLIC, .bip32_privkey_version = BIP32_VER_MAIN_PRIVATE}}, {.network_name = "litecoin-testnet", @@ -75,6 +83,8 @@ const struct chainparams networks[] = { .max_funding = AMOUNT_SAT_INIT(60 * ((1 << 24) - 1)), .max_payment = AMOUNT_MSAT_INIT(60 * 0xFFFFFFFFULL), .when_lightning_became_cool = 1, + .p2pkh_version = 111, + .p2sh_version = 58, .testnet = true, .bip32_key_version = {.bip32_pubkey_version = BIP32_VER_TEST_PUBLIC, .bip32_privkey_version = BIP32_VER_TEST_PRIVATE}} }; diff --git a/bitcoin/chainparams.h b/bitcoin/chainparams.h index 42e62d431324..493c6a9d5403 100644 --- a/bitcoin/chainparams.h +++ b/bitcoin/chainparams.h @@ -23,6 +23,8 @@ struct chainparams { const struct amount_sat max_funding; const struct amount_msat max_payment; const u32 when_lightning_became_cool; + const u8 p2pkh_version; + const u8 p2sh_version; /* Whether this is a test network or not */ const bool testnet; diff --git a/lightningd/jsonrpc.c b/lightningd/jsonrpc.c index 7e9af5c8d1b3..283fed0cab9e 100644 --- a/lightningd/jsonrpc.c +++ b/lightningd/jsonrpc.c @@ -957,8 +957,7 @@ json_tok_address_scriptpubkey(const tal_t *cxt, const char *buffer, const jsmntok_t *tok, const u8 **scriptpubkey) { - struct bitcoin_address p2pkh_destination; - struct ripemd160 p2sh_destination; + struct bitcoin_address destination; int witness_version; /* segwit_addr_net_decode requires a buffer of size 40, and will * not write to the buffer if the address is too long, so a buffer @@ -971,27 +970,24 @@ json_tok_address_scriptpubkey(const tal_t *cxt, bool parsed; bool right_network; - bool testnet; - - parsed = false; - if (bitcoin_from_base58(&testnet, &p2pkh_destination, - buffer + tok->start, tok->end - tok->start)) { - *scriptpubkey = scriptpubkey_p2pkh(cxt, &p2pkh_destination); - parsed = true; - right_network = (testnet == chainparams->testnet); - } else if (p2sh_from_base58(&testnet, &p2sh_destination, - buffer + tok->start, tok->end - tok->start)) { - *scriptpubkey = scriptpubkey_p2sh_hash(cxt, &p2sh_destination); - parsed = true; - right_network = (testnet == chainparams->testnet); - } - /* Insert other parsers that accept pointer+len here. */ + u8 addr_version; + + parsed = + ripemd160_from_base58(&addr_version, &destination.addr, + buffer + tok->start, tok->end - tok->start); if (parsed) { - if (right_network) + if (addr_version == chainparams->p2pkh_version) { + *scriptpubkey = scriptpubkey_p2pkh(cxt, &destination); return ADDRESS_PARSE_SUCCESS; - else + } else if (addr_version == chainparams->p2sh_version) { + *scriptpubkey = + scriptpubkey_p2sh_hash(cxt, &destination.addr); + return ADDRESS_PARSE_SUCCESS; + } else { return ADDRESS_PARSE_WRONG_NETWORK; + } + /* Insert other parsers that accept pointer+len here. */ } /* Generate null-terminated address. */