Last active
August 9, 2017 17:20
-
-
Save nmarley/506a3d3036d55c878696 to your computer and use it in GitHub Desktop.
Convert Dash BIP32 extended public key version prefix from 'xpub' to 'drkv'
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#! /usr/bin/env ruby | |
# Utility converting BIP32 extended key version bytes | |
require './dashutil' | |
xkey = ARGV.shift | |
pref = ARGV.shift | |
# xpub661MyMwAqRbcFnEEbFf8idiyo8QGKiqhTujUmaJsDhAEZ82cEQPMq69Y4V27vGc5rJnxsd26kyHpBJDW72YMjntsmASbdBy1awfGMsUvLCa | |
puts DashUtil.swap_prefix(xkey, pref) | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#! /usr/bin/env ruby | |
# Example of converting Dash BIP32 extended public key (incorrectly) beginning | |
# with 'xpub' to correct prefix 'drkv'. | |
# | |
require 'bitcoin' | |
# test extended pub key | |
xpub = 'xpub661MyMwAqRbcF3jZGiw3QBt7nD13a7k8jVt9me27BL1vSeSpviDj6udJ5cnFyr2q2ofw7kMKGUepVhVsbLVsckxGzDmvnpGPr88CJAz1Ab5' | |
# Dash extended public key prefix | |
drkv_prefix = '02fe52f8' | |
# decode base58 pubkey | |
bin = Bitcoin.decode_base58(xpub) | |
# replace 4-byte version prefix | |
bin[0..7] = drkv_prefix | |
version = bin[0..7] # 0488b21e | |
depth = bin[8..9] # 00 | |
parent_fingerprint = bin[10..17] # 00000000 | |
child = bin[18..25] # 00000000 | |
chain_code = bin[26..89] # 32bdad605aae059ae99303a1b74c8492630a0bf9f3b45680dfe82b03f8174365 | |
key_data = bin[90..155] # 03906d7e79f8b55ce4d7720bbd478dff3f11f832459d2890e2c8fb2b3316e18455 | |
# checksum... | |
# b43167ec | |
puts "version: #{version}" | |
puts "depth: #{depth}" | |
puts "parent_fingerprint: #{parent_fingerprint}" | |
puts "child: #{child}" | |
puts "chain_code: #{chain_code}" | |
puts "key_data: #{key_data}" | |
# add the checksum to the 78-byte xkey | |
drkbin = bin[0..155] + Bitcoin.checksum(bin[0..155]) | |
# base58 encode again | |
drk = Bitcoin.encode_base58(drkbin) | |
# result has proper 'drkv' prefix and generates same addresses | |
puts drk | |
# => drkvjJe5sJgqomjLnD39LKGdme64zzL4d38fDEhkveYsjvqDZzEZSoq6VEE5znetSRvSB6pYAxhTViXJdZ5QygKogD4nsa31hQ8aVuW6psczteC | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Dash BIP32 utilities | |
require 'bitcoin' | |
require 'byebug' | |
require 'pp' | |
class DashUtil | |
VERSION_BYTES = { | |
'drkv' => '02fe52f8', | |
'drkp' => '02fe52cc', | |
'DRKV' => '3a8061a0', | |
'DRKP' => '3a805837', | |
'xpub' => '0488b21e', | |
'xprv' => '0488ade4', | |
'tpub' => '043587cf', | |
'tprv' => '04358394', | |
} | |
def self.swap_version_bytes(xkey, version_bytes) | |
hex = Bitcoin.decode_base58(xkey) | |
hex[0..7] = version_bytes | |
hex = hex[0..155] + Bitcoin.checksum(hex[0..155]) | |
new_xkey = Bitcoin.encode_base58(hex) | |
return new_xkey | |
end | |
def self.swap_prefix(xkey, prefix) | |
swap_version_bytes(xkey, VERSION_BYTES[prefix]) | |
rescue StandardError => ex | |
throw ex | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#! /usr/bin/env ruby | |
# Utility converting BIP32 extended key version bytes | |
require 'dashruby' | |
require 'dashruby/extensions' | |
require './dashutil' | |
def gen_electrum_public_keys(xkey, type = :receive, num = 10) | |
path_prefix = (:change == type) ? "1" : "0" | |
# TODO: validation, also parsing pub/priv, etc. | |
if !xkey.match(/^drk[pv]/) | |
# TODO: determine prefix based on pub/priv key data (not version bytes) | |
# this assumes public key, which is a bad assumption. | |
xkey = DashUtil.swap_prefix(xkey, 'drkv') | |
end | |
public_keys = [] | |
kc = Dash::Keychain.new(extended_key: xkey) | |
(0..(num-1)).each do |n| | |
path = "#{path_prefix}/#{n}" | |
pubkey = kc.derived_key(path).public_key.to_hex | |
public_keys.push( pubkey ) | |
end | |
return public_keys | |
end | |
xkey = ARGV.shift | |
type = ARGV.shift || 'receive' | |
num = ARGV.shift || '5' | |
type = type.to_sym | |
num = num.to_i || 5 | |
print "\n\n" | |
gen_electrum_public_keys(xkey, type, num).each do |pubkey| | |
puts pubkey | |
end | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# original incorrect 'xpub' key: | |
xpub661MyMwAqRbcF3jZGiw3QBt7nD13a7k8jVt9me27BL1vSeSpviDj6udJ5cnFyr2q2ofw7kMKGUepVhVsbLVsckxGzDmvnpGPr88CJAz1Ab5 | |
# First two receiving addresses generated by Electrum: | |
XfodG6PGyXksxznJXzKFPgU1q9QdPBNYB2 | |
Xb4AKDUJBkjUSYVzuMXxLAxkUJaWomozGT | |
# ---------------------------------------------------------------------- | |
# correctly convert 'drkv' key: | |
drkvjJe5sJgqomjLnD39LKGdme64zzL4d38fDEhkveYsjvqDZzEZSoq6VEE5znetSRvSB6pYAxhTViXJdZ5QygKogD4nsa31hQ8aVuW6psczteC | |
# First two receiving addresses generated by Electrum: | |
XfodG6PGyXksxznJXzKFPgU1q9QdPBNYB2 | |
Xb4AKDUJBkjUSYVzuMXxLAxkUJaWomozGT | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#! /usr/bin/env ruby | |
require 'dashruby' | |
require 'dashruby/extensions' | |
# test extended pub key | |
xkey = 'drkvjJe5sJgqomjLnwXpeqzj65vw1ujHNeEDweZ5vaqdnHyXgTpLkVzjDQkKyetkNrVgzbwZvqNEzDAJK9o3VNNHoF1PeWhgXmqCEj3AtcMrX1c' | |
path = '0/0' | |
kc = Dash::Keychain.new(extended_key: xkey) | |
derived = kc.derived_key(path) | |
pubkey = derived.public_key.to_hex | |
addr = derived.address.to_s | |
puts " Path: m/#{path}" | |
puts "Public Key: #{pubkey}" | |
puts " Address: #{addr}" | |
print "\n" | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment