On-chain Outsourcing of Vanity Address Generation on Bitcoin

Mihael Šinkec
3 min readJan 31, 2022

--

With the help of Nikamoto I’ve developed a solution to outsource the generation of Bitcoin vanity addresses in a completely trustless manner using smart contracts deployed on the Bitcoin SV blockchain. I’ve used the sCrypt programming language to write the contract itself, along with its Python SDK, py-scryptlib, to write code for transaction deployment and parsing. The project is avaliable on GitHub.

sCrypt’s article was the inspiration for developing this solution and the contract code contained in the article was used as the base of mine. The notable difference between the two is that the articles contract code doesn’t support optimizations exploiting endomorphic and symmetric properties of secp256k1, that tools like VanitySearch use to speed up the searching process considerably.

Usage

Let’s say we’d like to own a Bitcoin vanity address, prefixed with the string 1miha but we don’t have beefy enough computer to search for it in a reasonable amount of time. We’ll deploy a contract with some coin tied to it to the chain.

First, we’ll need to generate a random private keyk. We can use the bitcoinX module in Python.

>>> import bitcoinx
>>> k = bitcoinx.PrivateKey.from_random()
>>> k.to_WIF()
‘L2Z1U6HRZijJDomnZfh9PEo3RDN3mKJGAy7VLJBZSVexkmSPjqZh’

We’ll need this key to assemble the final key of our desired address, so we need to store it somewhere safe and don’t share it with anyone!

Now we can deploy the contract the chain. Let’s say we’ll pay 100000 satoshis for a valid solution. We run the following command.

./vanity.py deploy L2Z1U6HRZijJDomnZfh9PEo3RDN3mKJGAy7VLJBZSVexkmSPjqZh 1miha 100000

The script will ask you to send the needed amount of coin needed for the contract to a temporary address.

If the deploy succeeded, the script will return its transaction ID like a63041f13720160fa29ec52129103f54339c07f595141537e1b2a253fd0d18fa .

Now, once our contract is published a potential seller can extract the needed information out of our deployed contract (0 is the index of the output containing the contract locking script):

./vanity.py info a63041f13720160fa29ec52129103f54339c07f595141537e1b2a253fd0d18fa 0

P: 0226447bcc9167db9973ff6759d39ddd3359e9332983cc9404132278e440832b76
Prefix pattern: 1miha
Rewards (sats): 100000

Once he has our public key and desired address prefix, he can start search for a partial key, that will produce the address we want. One of the tools he can use is VanitySearch, which supports split key search. Once he found the key, he can claim his reward with the following command:

./vanity.py claim a63041f13720160fa29ec52129103f54339c07f595141537e1b2a253fd0d18fa 0 KwtvWH85BrsLv7LbDRjY9299wUZNUWiHGqS5bZiM9YVTve2o9Z5x KwtvWH85BrsLv7LbDRjY9299wUZNUWiHGqS5bZiM9YVTve2o9Z5x 1BGHDr1bAcZ8zgjJ2p4aY85fwovzZwV2as

The script will return the ID of the redeeming transaction, e.g. 545ddf370e04bc5deef3fd561300feca908b1d60216e29fa15cc64204bff1e45.

Now we can assemble our final private key, the public keys address of which will start with our desired prefix:

./vanity.py assemble 545ddf370e04bc5deef3fd561300feca908b1d60216e29fa15cc64204bff1e45 0 L2Z1U6HRZijJDomnZfh9PEo3RDN3mKJGAy7VLJBZSVexkmSPjqZh

Final private key (WIF): L5SKe4HEyvjwDCVEjYpcaNkWdZBANRdrwMsAvNwn6rNiKykNEz8Z
Final private key (HEX): f52fd8bde78b05727829e510075f60c5313ae0f141e700f04cc6068d3e5af85c
Final public key: 033e8adb090003f69e3695e73f6095f346d2b2145cee2c35dce3e6e31228dc40ff
Address: 1mihaGoBUMtu24zqZXVE2sp8hhXXHoBwU

We can be sure, that only we know the final private key, because only we know the value of key k , which is needed to assemble it.

The next step

The code of this solution can be further extended with a marketplace that has a web interface , which will enable easier contract management and will list all the deployed contracts.

For now you can also use Nikamotos interactive script via Replit, which doesn’t require you to download any software whatsoever.

--

--