Skip to content
This repository has been archived by the owner on Dec 14, 2023. It is now read-only.

Commit

Permalink
Initialize with a private key (#20)
Browse files Browse the repository at this point in the history
* option to init with private key

* Add keypair generation script

* Pin block-chain variables

* Updated README to reflect generate_keypair
  • Loading branch information
kad-floriw authored Jun 3, 2021
1 parent 9ed5985 commit 6f2db6a
Show file tree
Hide file tree
Showing 7 changed files with 182 additions and 9 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ The node configuration depends on environment variables.
* PARAM_TARGET_BLOCK_SIZE: target-block-time|30
* PARAM_ANYONE_CAN_CONNECT: anyone-can-connect|true
* PARAM_ANYONE_CAN_MINE: anyone-can-mine|true
* PRIVATE_KEY: The private key to initialize the node with. The private key can be set when the node has not yet been initialized. An address / private key pair can be generated using scripts/generate_keypair.js.

#### Optional

Expand Down
4 changes: 4 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,9 @@ services:
PARAM_TARGET_BLOCK_SIZE: target-block-time|30
PARAM_ANYONE_CAN_CONNECT: anyone-can-connect|true
PARAM_ANYONE_CAN_MINE: anyone-can-mine|true
PARAM_PRIVATE_KEY_VERSION: private-key-version|80ea7b28
PARAM_ADDRESS_CHECKSUM_VALUE: address-checksum-value|344cbb15
PARAM_ADDRESS_PUBKEYHASH_VERSION: address-pubkeyhash-version|00f7391c

node:
build:
Expand All @@ -59,6 +62,7 @@ services:
RPC_ALLOW_IP: 0.0.0.0/0.0.0.0
MAIN_NODE_HOST: main-node
DELAY_INIT: 1
PRIVATE_KEY: VDFLMeU5BA8S8iRssuMvhUXh1WoTC7YcLGh4knCdP4oWVNw4RY8sQowG
links:
- main-node
depends_on:
Expand Down
20 changes: 11 additions & 9 deletions entrypoint.sh
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,8 @@ EOF
-daemon \
-txindex \
-shrinkdebugfilesize \
-datadir=/data
-datadir=/data \
-initprivkey=$PRIVATE_KEY

wait 10

Expand All @@ -67,14 +68,15 @@ start_node () {
echo "Start node with existing chain: $CHAINNAME from $IP:$NETWORK_PORT"

multichaind $CHAINNAME@$IP:$NETWORK_PORT \
-daemon \
-txindex \
-shrinkdebugfilesize \
-rpcuser=$RPC_USER \
-rpcpassword=$RPC_PASSWORD \
-rpcallowip=$RPC_ALLOW_IP \
-rpcport=$RPC_PORT \
-datadir=/data
-daemon \
-txindex \
-shrinkdebugfilesize \
-rpcuser=$RPC_USER \
-rpcpassword=$RPC_PASSWORD \
-rpcallowip=$RPC_ALLOW_IP \
-rpcport=$RPC_PORT \
-datadir=/data \
-initprivkey=$PRIVATE_KEY

wait 10
}
Expand Down
79 changes: 79 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@
"test": "echo \"Error: no test specified\" && exit 1"
},
"dependencies": {
"bs58": "^4.0.1",
"crypto": "^1.0.1",
"elliptic": "^6.5.4",
"multinodejs": "^2.0.0",
"patch-package": "^6.2.2",
"uuid": "^8.2.0"
Expand Down
66 changes: 66 additions & 0 deletions scripts/generate_keypair.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
let bs58 = require('bs58');
let crypto = require('crypto');
let elliptic = require('elliptic');


function hexToBytes(hex) {
const bytes = [];
for (let c = 0; c < hex.length; c += 2)
bytes.push(parseInt(hex.substr(c, 2), 16));

return bytes;
}

function getHash(bytes, method) {
return crypto.createHash(method).update(Buffer.from(bytes)).digest('hex');
}

function addHash(origin, hash, step) {
const interval = Math.floor(step / hash.length);
for (let i = 0; i < hash.length; i++) {
origin.splice(i * interval + i, 0, hash[i]);
}

return origin
}

const ADDRESS_PUBLIC_KEY_HASH_VERSION = '00f7391c';
const publicKeyHashVersionBytes = hexToBytes(ADDRESS_PUBLIC_KEY_HASH_VERSION);
console.log(`ADDRESS_PUBLIC_KEY_HASH_VERSION: ${ADDRESS_PUBLIC_KEY_HASH_VERSION}`);

const PRIVATE_KEY_VERSION = '80ea7b28';
let privateKeyVersionBytes = hexToBytes(PRIVATE_KEY_VERSION);
console.log(`PRIVATE_KEY_VERSION: ${PRIVATE_KEY_VERSION}`);

const ADDRESS_CHECKSUM_VALUE = '344cbb15';
const addressChecksumBytes = hexToBytes(ADDRESS_CHECKSUM_VALUE);
console.log(`ADDRESS_CHECKSUM_VALUE: ${ADDRESS_CHECKSUM_VALUE}`);

const keyPair = new elliptic.ec('secp256k1').genKeyPair();

const publicKey = keyPair.getPublic().encodeCompressed('hex');
let publicKeyBytes = hexToBytes(publicKey);

let publicKeyHash = getHash(publicKeyBytes, 'sha256');
publicKeyHash = getHash(hexToBytes(publicKeyHash), 'ripemd160');
publicKeyBytes = addHash(hexToBytes(publicKeyHash), publicKeyHashVersionBytes, 20);
publicKeyHash = getHash(publicKeyBytes, 'sha256');
publicKeyHash = getHash(hexToBytes(publicKeyHash), 'sha256');

publicKeyBytes.push(...hexToBytes(publicKeyHash).slice(0, 4).map((x, i) => x ^ addressChecksumBytes[i]));

const privateKey = keyPair.getPrivate('hex');
let privateKeyBytes = hexToBytes(privateKey);
privateKeyBytes.push(1);

privateKeyBytes = addHash(privateKeyBytes, privateKeyVersionBytes, 33);

let privateKeyBytesHash = getHash(privateKeyBytes, 'sha256');
privateKeyBytesHash = getHash(hexToBytes(privateKeyBytesHash), 'sha256');
privateKeyBytes.push(...hexToBytes(privateKeyBytesHash).slice(0, 4).map((x, i) => x ^ addressChecksumBytes[i]));

const address = bs58.encode(publicKeyBytes);
console.log(`Address: ${address}`);

const privateKeyEncoded = bs58.encode(privateKeyBytes);
console.log(`Private Key: ${privateKeyEncoded}`);
18 changes: 18 additions & 0 deletions testing/get_private_key.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
const multichain = require('multinodejs');

const connection = multichain({
port: 8572,
host: '127.0.0.1',
user: 'multichainrpc',
pass: 'password',
});

async function asyncDumpPrivateKey() {
const addresses = await connection.getAddresses();
for (const address of addresses) {
const privateKey = await connection.dumpPrivKey({ address });
console.log(`${address}: ${privateKey}`);
}
}

asyncDumpPrivateKey().then();

0 comments on commit 6f2db6a

Please sign in to comment.