How to generate a Peercoin Address in code?

So, I’m trying to generate a Peercoin Address. The steps seem quite simple, since Peercoin uses basically the same recipe from Bitcoin (which can be found here).

However my problem starts on step 2, where one must generate a SHA-256 hash from a public ECDSA key in order to continue.

My issue is that the generated hash is always different from those seen in examples.

Pratical example:

You can open this website: http://gobittest.appspot.com/Address to check the steps of generating an address.

On step 2 - SHA-256 hash of 1, the hash generated doesn’t match the public key.

If you run a SHA-256 online hash tool on the public key provided in the website above, you will see the hash generated and the hash this website prints are different. How could that be?

The same issue is happening on my code. My SHA-256 hash from the public ECDSA key is somewhat not what bitcoin/peercoin “expects” and thus leads to a broken address in the end.

Is there something obvious I’m missing out? How can hashes from a public key get different since the step only asks me to run a simple sha256(pubKey)? Should I be adding any extra step to the recipe?

I can help you more later when I get back to my desk.

Make sure you’re performing the hash on binary data. ( the unhexlify step )

1 Like

Thanks! The hash was being performed on hexadecimal instead of binary data. That was the first issue.

However, it seems the problem persists. The “address” generated is invalid (38 chars) for some reason.

Here is the piece of code that does the trick:

let privateKey = KEY_PAIR.getPrivate('hex');

let key = BA.unhexlify(KEY_PAIR.getPublic('hex'));

let keyHash = '37' + new RIPEMD160().update(SHA256(key)).digest('hex');

let checksum = SHA256(SHA256(keyHash)).substr(0, 4);

// Should output the final address starting with 'P', etc..
// However it outputs 38-length "invalid" addresses
let address = BASE58CHECK.encode(keyHash + checksum);

For seeing the code running live: https://runkit.com/kazzkiq/5a569ec3bc4a6800120710b8

Try and test this out. Modified line 15.
We do something similar in Kutil for pypeerassets.

Just realized you also asked about the address starting with a P.

Since every npm package that works with bitcoin has remarkable complexity, and since most packages used by bitcoin libraries don’t behave well in Browser as they do in Node.js, I’m guessing this is no trivial task to generate addresses in browser from scratch.

So I decided to take a practical approach instead of reinventing the wheel: Rely on battle-tested libraries, and make them work with Peercoin.

bitcoinjs-lib its the most popular, and seems pretty easy to extend:

const bitcoinjs = require('bitcoinjs-lib');

const peercoinNetwork = {
  messagePrefix: '\x19Peercoin Signed Message:\n',
  bip32: {
    public: 0x0488b21e,
    private: 0x0488ade4
  },
  pubKeyHash: 0x37,
  scriptHash: 0x75,
  wif: 0xb7
}

const keyPair = bitcoinjs.ECPair.makeRandom({
    network: peercoinNetwork
});

// Peercoin Address/Priv. Key
console.log(keyPair.toWIF());
console.log(keyPair.getAddress());

Live Example

It also accepts random seed in order to generate a new wallet, which is exactly what I need. For now I will be using this solution.

2 Likes

https://jointhepartypooper.github.io/GraphicalPeercoinAddress/public/

1 Like