Sunday, September 21, 2014

Writing your first bitcoin-ruby program

Imagine you wrote down a WIF private bitcoin key, but because your handwriting was unclear or you wrote it in a hurry, it turns out one character was copied down wrong.

Here is the incorrect WIF: 5KL6HJfzZ4Uj4CJRFYT11z2W1t5kbULaDqHd7rn6ktLwT6sgyrY

You want to go through each character in the WIF string, replacing each single character in turn with one of the 58 valid characters for the WIF format, and check if it's a valid WIF key.

#!/usr/bin/env ruby
# First the required includes for bitcoin and openssl
require 'bitcoin'
require 'openssl'

# This function performs the correct checksum on a proposed WIF key
# to determine if it is a genuine WIF key
# See http://gobittest.appspot.com/PrivateKey (TP's Go Bitcoin Tests) for an explanation
def wif_valid?(hex)
hex = Bitcoin::base58_to_hex(hex)
hex1 = hex[0..-9]
hex1 = Bitcoin::checksum(hex1)
hex2 = hex.reverse[0..7].reverse
if hex1 == hex2
return true
end
return false
end

# This is our one character wrong WIF
badwif = "5KL6HJfzZ4Uj4CJRFYT11z2W1t5kbULaDqHd7rn6ktLwT6sgyrY"

# And this function takes a WIF, and loops through each character,
# changing it by one, and checking if it is now valid.
# It prints out any valid WIF it finds (there should only be one)
def one_alter(awif)
code_string = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"
newwif = ""
for i in 1..awif.length-1
for j in 0..code_string.length-1
newwif = awif
   # Next line is a  hack to ensure that newwif is a new string 
   # and not a pointer to the same string as awif
newwif = newwif + ""
newwif[i] = code_string[j]
if wif_valid?(newwif) == true
    # print out the newwif if it is a correct key
puts newwif
end
end
end
end

one_alter badwif

So lets see what happens when we run it:

bitcoin-ruby$ ruby programs/address.rb 

5KL6HJfzZ4Uj4CJRFYT11z2W1t5kbULaDqHd7rn6ktLwT5sgyrY

There you go - the one valid WIF address within one character of the bad one is retrieved. And it's corresponding public address is 1MUDdayQ7Af39bT9mA6zRYd7ehEeuqFzLZ . Note: no balance, and unlike to have one for long from now on, given that I've committed the cardinal sin of bitcoin, and published the private key.

No comments:

Post a Comment