Do you agree that a not-uncommon Bitcoin discussion goes along the lines:
"Remember that one private key controls two public addresses, the uncompressed and the compressed." Next, someone smart-ass says, "You're forgetting nested and native segwit - it's four addresses, guys."What about newer stuff like Taproot? What about crazy things like 1-of-1-multisig? What about older formats like P2K and P2MS that no one has used in years but would still be accepted by the network?
I decided to give it a shot.
The overall goal here is to show how many unique public addresses are actually derived from one single seed, using no "HD Wallet wizardry" with optional additional keyphrases and derivation paths. I decided no input other than the "bad_seed" string is allowed; absolutely no mnemonic phrases or derivations paths from BIPs.By the way, I call the only input "seed" rather than password/passphrase, and I define a seed to be a 64-character hexadecimal number, such as
0000000000000000000000000000000000000000000000000000000000000001
because it can then be interpreted as 32 bytes
or as a script. (This example wouldn't run as a script, but that's a separate story).
For this project, I've experimented with Python and cross-verified outputs with online services as needed, but I thought my actual code was of limited interest. If you, against all odds, wanna take a look at my scripts, say when.
Back to the title subject. From the seed, I can begin with deriving:
[[[OUTPUTS]]]
Master root XPRV:
xprv9s21ZrQH143K24Mfq5zL5MhWK9hUhhGbd45hLXo2Pq2oqzMMo63oStZzF93Y5wvzdUayhgkkFoicQZcP3y52uPPxFnfoLZB21TeqtDeZVxb
Uncompressed public key: 0479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8
Compressed public key: 0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798
Uncompressed RIPEMD160 a.k.a. HASH160: 91b24bf9f5288532960ac687abb035127b1d28a5
Compressed RIPEMD160 a.k.a. HASH160: 751e76e8199196d454941c45d1b3a323f1433bd6
Private keys
~~~~~~~~~~~~
Uncompressed (WIF): 5HpHagT65TZzG1PH3CSu63k8DbpvD8s5ip4nEB3kEsreAnchuDf
Compressed (WIF): KwDiBf89QgGbjEhKnhXJuH7LrciVrZi3qYjgd9M7rFU73sVHnoWn
Nothing special so far, except maybe my
XPRV experiment.
But how about this? I've never found anything online that is this extensive (and way too many examples on Github that do bits and pieces of it).
Public addresses
~~~~~~~~~~~
Public script - rare but valid (P2S)** 0000000000000000000000000000000000000000000000000000000000000001
Old 1-of-1 multisig uncompressed - rare but valid (P2MS): 51410479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b851ae
Old 1-of-1 multisig compressed - rare but valid (P2MS): 51210279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f8179851ae
Uncompressed public key - rare but valid (P2PK): 0479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8
Compressed public key - rare but valid (P2PK): 0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798
Uncompressed legacy public key (P2PKH): 1EHNa6Q4Jz2uvNExL497mE43ikXhwF6kZm
Compressed legacy public key (P2PKH): 1BgGZ9tcN4rm9KBzDn7KprQz87SZ26SAMH
Nested SegWit public address (P2WPKH-P2SH): 3JvL6Ymt8MVWiCNHC7oWU6nLeHNJKLZGLN
Nested SegWit script public address (P2SH)**: 3D24NWLpGxY9x8WZYpvowwyNPyZyN7aRNB
New 1-of-1 multisig uncompressed - weird (P2SH): 33RjLdp9usumz3BNqa5PB9umJZjiw7kmjK
New 1-of-1 multisig compressed - weird (P2SH): 3DicS6C8JZm59RsrgXr56iVHzYdQngiehV
Native SegWit public address (P2WPKH): bc1qw508d6qejxtdg4y5r3zarvary0c5xw7kv8f3t4
Native Segwit public address (P2WSH)**: bc1qa3y3dhfgl3xpp4uw9p72tkwv28hp4eeuhl0q334nwvjvh74v30zs5faqjp
Taproot public address (P2TR): bc1pmfr3p9j00pfxjh0zmgp99y8zftmd3s5pmedqhyptwy6lm87hf5sspknck9
[Those marked with ** require the underlying script to be executbale, or the address is unspendable.]
My comments:
I thought I'd take it from the beginning and in chronological order of appearance from 2009 until today.
Pay-to-script (P2S) has, to the best of my knowledge, always been allowed, but there are few examples from the past decade. Paying to the script used in this example but be advised against; it is probably not spendable.
The same goes for early-day multi-signature addresses, for which you had to write the public key(s) in clear text (P2MS). As far as I understand, they are still legal but very scarce. The special case of 1-of-1 was probably never an intended feature - it makes little sense - but they weren't disallowed back then, and they are still accepted today. We can write one each for the uncompressed and the compressed public keys, respectively.
Then, we have the two legacy addresses that reigned for many years (especially the compressed ones).
First among the "3-addresses" is one with many names. I like "nested Segwit" best, but if you prefer P2WPKH-P2SH, I'm cool.
Next in line is "Nested SegWit script public address (P2SH)**" - and I would like you to suggest a better name. The code I use to construct them is:
base58.b58encode_check(bytes.fromhex('05'+ hashlib.new('ripemd160', hashlib.sha256(bytes.fromhex(bad_seed)).digest()).hexdigest())).decode()
They are, I think, only good if the corresponding script is good (and I strongly suspect "bad_seed" will not pass as a valid Bitcoin Script).
Then we have these weird 1-of-1 multi-sig transactions again. Take a look at this
link collection about "Crazy1to1" and good luck getting any wiser! In any case, we can easily create two 1-of-1 multi-sig addresses, one for the uncompressed public key and one for the compressed ditto, and wrap them up in P2SH containers.
Native Segwit, or shall we call them "bc1"-addresses shouldn't surprise anyone. At least not the first. The second one, which I call "(P2WSH)**", is just me using the seed as a script again; hence, 32 instead of 20 bytes and a longer address. In honor of full transparency, I think the address format is correct, but since "bad_seed" isn't a real script, I doubt the address is spendable.
The last one is "just" a regular Taproot. It is also the format that I know the least about. I am struggling with theory in combination with super-enthusiastic Youtubers, but it is still to little avail - I am not sure I get "it" when it comes to Taproot/bc1p and how it changes the world for the better. Is it possible to make Taproot variations without introducing arbitrary extra code? I take pride in that all the above are derived from one single seed and that anyone who reproduces parts or all of them should get the same public addresses.
I am super excited about your feedback! Did I leave anything obvious out? Did I make any mistakes, big or small? In other words, what should I correct? Have others derived more than 14 public addresses from one hardcoded seed in a deterministic and reproducible manner? Should I make public my Python script?For good measure, iteration 2 yields:
[[[INPUT]]]] [[[We treat this single input a private key OR a script (HEX)]]]
Bad seed: 0000000000000000000000000000000000000000000000000000000000000002
[[[OUTPUTS]]]
Master root XPRV:
xprv9s21ZrQH143K24Mfq5zL5MhWK9hUhhGbd45hLXo2Pq2oqzMMo63oStZzF93Y5wvzdUayhgkkFoicQZcP3y52uPPxFnfoLZB21TeqtEE6Pxo
Uncompressed public key: 04c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee51ae168fea63dc339a3c58419466ceaeef7f632653266d0e1236431a950cfe52a
Compressed public key: 02c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee5
Uncompressed RIPEMD160 a.k.a. HASH160: d6c8e828c1eca1bba065e1b83e1dc2a36e387a42
Compressed RIPEMD160 a.k.a. HASH160: 06afd46bcdfd22ef94ac122aa11f241244a37ecc
Private keys
~~~~~~~~~~~~
Uncompressed (WIF): 5HpHagT65TZzG1PH3CSu63k8DbpvD8s5ip4nEB3kEsreAvUcVfH
Compressed (WIF): KwDiBf89QgGbjEhKnhXJuH7LrciVrZi3qYjgd9M7rFU74NMTptX4
Public addresses
~~~~~~~~~~~
Public script - rare but valid (P2S)** 0000000000000000000000000000000000000000000000000000000000000002
Old 1-of-1 multisig uncompressed - rare but valid (P2MS): 514104c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee51ae168fea63dc339a3c58419466ceaeef7f632653266d0e1236431a950cfe52a51ae
Old 1-of-1 multisig compressed - rare but valid (P2MS): 512102c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee551ae
Uncompressed public key - rare but valid (P2PK): 0479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8
Compressed public key - rare but valid (P2PK): 0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798
Uncompressed legacy public key (P2PKH): 1LagHJk2FyCV2VzrNHVqg3gYG4TSYwDV4m
Compressed legacy public key (P2PKH): 1cMh228HTCiwS8ZsaakH8A8wze1JR5ZsP
Nested SegWit public address (P2WPKH-P2SH): 3FWHHE3RVgyv5vYmMrcoRdA25uugWvQbso
Nested SegWit script public address (P2SH)**: 3CNVyupnE7C8FMCv9vPWSpriuVQZVt6Fzh
New 1-of-1 multisig uncompressed - weird (P2SH): 3G1kW5oNxKs2whEgi6cwVy5KEoAqkwuGHr
New 1-of-1 multisig compressed - weird (P2SH): 32KTvowh8quz8eFfxgX98QJUdUGgryn28R
Native SegWit public address (P2WPKH): bc1qq6hag67dl53wl99vzg42z8eyzfz2xlkvxechjp
Native Segwit public address (P2WSH)**: bc1qjfna8kldsq55zjplrtaz567x3hjlv5cj3t9fhu2xr3ws5wkndmfqhhl956
Taproot public address (P2TR): bc1pet7ep3czdu9k4wvdlz2fp5p8x2yp7t6ttyqg2c6cmh0lgeuu9lasmp9hsg
[Those marked with ** require the underlying script to be executable, or the address is unspendable.]