Generate Bitcoin Address JS Step-By-Step "Invalid Address" Error

0

I am following the process for bitcoin address creation as outlined in Mastering Bitcoin, however, when I try to reference this address in my bitcoin-cli, which is set to regtest, it responds with an invalid address error. I am attempting to write some JS to interact with my bitcoin node via the bitcoin-core package, but instead of just using all the built in commands, write some of the code myself to solidify my understanding.

I am using the following npm packages:

const EC = require('elliptic').ec;
const ec = new EC('secp256k1');
const bs58 = require('bs58')
const SHA256 = require("crypto-js/sha256");
const RIPEMD160 = require("crypto-js/ripemd160");

Here is my address creation function.

function createNewAddress() {
  // Get the private key
  const privateKey = ec.genKeyPair()
  // Get the public point from the private key
  const publicPoint = privateKey.getPublic();
  // Uncompressed public key
  const uncompressedPK = publicPoint.encode('hex');
  // SHA256 then RIPEMD160, aka HASH160
  const hashedPK = RIPEMD160(SHA256(uncompressedPK).toString()).toString();
  // Prepend the version, here we use 6F got the testnet (we are using regtest)
  const prependedPK = "6F"+hashedPK;
  // Calculate the checksum and take the first 4 btyes
  const checksum = SHA256(SHA256(prependedPK).toString()).toString().substring(0,9);
  // Append the checksum to the end
  const unencodedPK = prependedPK + checksum;
  // Base58Encode the unencodedPK
  const bytes = Buffer.from(unencodedPK, 'hex');
  const bitcoinAddress = bs58.encode(bytes);
  return (bitcoinAddress);
}

Here is a simple output: mtURXDaisk6ustpeo7LuiZYje9yV31JhBN

crypto_rob

Posted 2017-11-05T03:04:40.303

Reputation: 65

That's a testnet versioned P2PKH address.Anonymous 2017-11-05T03:30:30.130

I was looking for a regtest prefix here: https://en.bitcoin.it/wiki/List_of_address_prefixes could not find one

crypto_rob 2017-11-05T04:02:02.020

regtest and testnet use the same version byte.Andrew Chow 2017-11-05T04:08:18.080

That is what I figuredcrypto_rob 2017-11-05T04:26:10.780

Answers

0

You are hashing everything as hex strings. However that is not the proper way to hash stuff. They should all be hashed as bytes (i.e. the raw data), not strings of hexadecimal.

Andrew Chow

Posted 2017-11-05T03:04:40.303

Reputation: 40 910

Unless I am mistaken the package I am using, crypto-js, takes in a string. Does this alter the data in a way that will result in incorrect hashes?crypto_rob 2017-11-05T04:31:11.423

Yes, that will result in incorrect hashes. It takes in a string, and hashes that string. It does not seem to convert that string to the bytes that the string represents so that will result in a different hash.Andrew Chow 2017-11-05T04:35:31.757

Ok, so to confirm, I should take the uncompressed public key, then convert it to bytes if it isn't already bytes, hash that (SHA256). Then, take the bytes from that hash and hash it again (RIPEMD160). So basically convert to bytes each time before hashing?crypto_rob 2017-11-05T04:38:13.253

Yes, everything should be bytes, not a hex string representing the bytes.Andrew Chow 2017-11-05T04:50:05.713