In praise of APIs: Nxt Vanity Address finder

Tuesday 26 April 2016

Here’s how to make a simple Nxt Vanity Address finder using Python and Nxt's API.

Nxt’s APIs are really easy to use and powerful, so I decided to have a play around to see what I could do. This simple program is a Vanity address finder that brute-force finds a short string of characters in a Nxt address, though the process could easily be adapted for other address types.

Nxt addresses are numeric (a string of numbers) but typically presented in Reed-Solomon (RS) format, which means they look something like this: NXT-DJTQ-MMQE-SS4L-CMPFE. Within these groups of numbers and letters, there is obviously scope for finding names, business or personal, bits of l33t to show what a competent hax0r you are and, of course, rude words.

Plate

Vanity crypto addresses: the personalised plates of the bitcoin world

Passphrases (Nxt uses a brainwallet system) can be any string of characters, though the longer the better - up to a point - from a security perspective. So all we're going to do is generate a random list of 20 alphanumeric characters and see what the associated address looks like.

This is not the best way to do it. Aside from the inefficiencies of my algorithm, Python is high-level and easy to use but slow compared to other languages, but I’m not a l33t hax0r so I’m content to give a proof-of-concept that just works. Full code and comments are below. You can find details about the Nxt API at http://wiki.nxtcrypto.org/wiki/The_Nxt_API. That’s got pretty much everything you’ll need to API into the blockchain and do whatever you want. (Note: I hacked this together quickly as a PoC but if you want to use it for real you're best off using a better source of randomness.)

In this instance, the API call required is Get Account Id. You submit a passphrase and it returns various information including the RS-encoded address. The Python script then checks for a given target string within that address string.

Request:

  • requestType is getAccountId
  • secretPhrase is the secret passphrase of the account (optional)
  • publicKey is the public key of the account (optional if secretPhrase provided)

Response:

  • accountRS (S) is the Reed-Solomon address of the account
  • publicKey (S) is the public key of the account
  • requestProcessingTime (N) is the API request processing time (in millisec)
  • account (S) is the account number

So, we specify the search string, set it running and, quarter of a million guesses and somewhat over an hour later, here’s what it returns:

Searching for string BUTT
Success: Passphrase SpyrTnrgEoruCiddRcZ7g
NXT-SDNU-BUTT-DYJ5-8HQFH
253943 attempts required

Easy!


Full code:

import random # Bunch of libraries you'll need to import
import urllib
import urllib2
import json
import sys

BASE58 = '23456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz' # List of characters for passphrase
str = "BUTT" # Target string. Very childish.
address = ""
j = 0 # Counter for number of guesses
print "Searching for string", str

while str not in address: # Keep going until it finds the target string
    passphrase = ('%s%s' % ('S', ''.join([BASE58[ random.SystemRandom().randrange(0,len(BASE58)) ] for i in range(20)]))) # Line of code pinched from bitcoin mini private key generator, https://en.bitcoin.it/wiki/Mini_private_key_format

    nxtjson = {"requestType":"getAccountId", "secretPhrase":passphrase} # API calls are dead simple
    url = 'http://127.0.0.1:7876/nxt' # You'll need the Nxt client running
    data = urllib.urlencode(nxtjson) # Get the response from Nxt API
    req = urllib2.Request(url, data)
    response = urllib2.urlopen(req)
    output = json.loads(response.read()) # JSONify it
    address = output["accountRS"] # Pull out the address from the JSON returned
    print "%d\r" % j, # Useful counter thing to show how many guesses it's had
    sys.stdout.flush()
    j += 1

print "Success: Passphrase ", passphrase # Print results
print address
print j, "attempts required"

 


comments powered by Disqus