Skip to content

Instantly share code, notes, and snippets.

@railsstudent
Last active March 12, 2019 10:06
Show Gist options
  • Save railsstudent/292ac30d23bb337f84477f46a6de9b34 to your computer and use it in GitHub Desktop.
Save railsstudent/292ac30d23bb337f84477f46a6de9b34 to your computer and use it in GitHub Desktop.
crypto = require('crypto');
function buildMerkleRoot(targetHash, proof) {
const bigEndianMerkleRoot = proof.reduce((merkleHash, p) => {
if ('append' in p) {
return Buffer.concat([merkleHash, Buffer.from(p.append, 'hex')]);
} else if ('prepend' in p) {
return Buffer.concat([Buffer.from(p.prepend, 'hex'), merkleHash]);
} else if ('sha256' in p) {
return crypto.createHash('sha256').update(merkleHash).digest();
}
return merkleHash;
}, Buffer.from(targetHash, 'hex')).toString('hex');
return swapAndReverse(bigEndianMerkleRoot);
}
function swapAndReverse(s) {
let str = '';
for (let i = 0; i < s.length; i+= 2) {
str += s[i+1] + s[i];
}
return str.split('').reverse().join('');
}
const testInputs = [{
merkleRoot: '86088dd7c2150b1aa4f9a41bf4fbd1ec151858f46724c529eb54f46fa8d83f7e',
targetHash: 'de655cbf45657984d57276ee56260369bb5b04bd807a7688d5045d6edbbbe70e',
proof: [
{ 'append': 'd65c90fb6073c08bede523a60802f3ae' },
{ 'sha256' : '' },
{ 'append' : '6ece9977c82b31873f44903cfe443418' },
{ 'sha256' : '' },
{ 'prepend' : '5c85f378' },
{ 'append' : 'a831ff6383c5a595' },
{ 'sha256' : '' },
{ 'prepend' : '0100000001f95eb06f6f6e8a4d6eda1fc880562e0b46c9c7d50708cfe80948371742abf017000000004847304402203e6af830ec361d4743bebb56004e357c2caf03954bd093965f73770431308ce60220376fe713db277a66b7a2c72ccb8dc1c5ecb5e8710edb0ada7958988146517f3001fdffffff0290f0052a0100000017a914920b6b12ad46b1c1e0cd781e36e8e6019a443371870000000000000000226a20' },
{ 'append' : '334b0000' },
{ 'sha256' : '' },
{ 'sha256' : '' },
{ 'prepend' : 'a3249d80be7656b1bbc647702ab5d6c5b3422f15be768e30b318b950b6d4cfe9' },
{ 'sha256' : '' },
{ 'sha256' : '' }
]
},
{
merkleRoot: 'a74b7a0023746ff945758851c2d0ca2ebf006f330cca1131e9c20de1c8030916',
targetHash: '404eb6e1b539fe0ef8e21e91aa71d14a7f12c86c6964860baf99d334e8180da6',
proof: [
{ 'append': '70684d852a322bd087284ba36861843f' },
{ 'sha256' : '' },
{ 'append' : '64727c5ec5b9d26be2ff8058885bf8b5' },
{ 'sha256' : '' },
{ 'prepend' : '5c85f3a7' },
{ 'append' : '46676f61f873da27' },
{ 'sha256' : '' },
{ 'append' : 'ece8c0ab887fc7cfbb74c2be0fc47a5c79ec046979218b40f3980432536caedf' },
{ 'sha256' : '' },
{ 'append' : '317728a3d4aebfb96194a95bead628e61ae66a81d9e17578fed9f997e83a2f4e' },
{ 'sha256' : '' },
{ 'prepend' : '9f9f8b2458a66a1d3d42f84269d586de01ee36dc44b7b2259e4ed2fc1f163bcf' },
{ 'sha256' : '' },
{ 'prepend' : '0100000001f874220fab00b570dd2a31815276e92be011b8cdfed2b895521e9d2e719ceecc0000000047463043021f291f21efb1f1c316bd1287a57b0e22d56e03843f58e114eedd047b2def3d5802203a6b397ad09fdebb3ac9647553a0928e43fe6202d92c43c7f36df3de3a081ff701fdffffff0290f0052a0100000017a9141b02b46717a0f5a2cc182ddaefe8a255905bbf09870000000000000000226a20' },
{ 'append' : '814d0000' },
{ 'sha256' : '' },
{ 'sha256' : '' },
{ 'prepend' : '268dde1222e1d9211a4c5b83ce4ecf1565715a240ffc3a2ea93017f89deb6fcd' },
{ 'sha256' : '' },
{ 'sha256' : '' }
]
}, {
merkleRoot: '73104642f6de0271af397ce9f13df80cf5d9bede64bf218262bddfe556974729',
targetHash: '35be92d1935b634c470e23c8d95a753a40ddcfb180e36ae499f7f1f605e158da',
proof: [
{ 'append': '2a5db6bddad9f765a31afae029f18d32' },
{ 'sha256' : '' },
{ 'append' : '00701e75a7df874809cc0776943fb803' },
{ 'sha256' : '' },
{ 'prepend' : '5c871fce' },
{ 'append' : 'a8a3c9af2de5c02c' },
{ 'sha256' : '' },
{ 'append' : '2d42b6ec777e4a319e21496b30208e6ddd94815499da61c2ceda4957acb48c9e' },
{ 'sha256' : '' },
{ 'append' : '9b51eb415aa2426cb6d8deba5166981490c89ac7dcd3ba311ab2c41e6c394528' },
{ 'sha256' : '' },
{ 'prepend' : '0100000001f195f6f940465c34c3427bb8aa1d9f3df257b8b5330ae3654a690adfda10a895000000004847304402207d188364b870ab5b5e1c991cf25f2182445e5e045fec089294b175258ef55f990220264f7400c09c96a914f62d2e6aabf16b238c6289973d4682426fce9faf51098a01fdffffff02caef052a0100000017a914509c159b3fbe99bd620fc5904408970fc0beea51870000000000000000226a20' },
{ 'append' : '735c0000' },
{ 'sha256' : '' },
{ 'sha256' : '' },
{ 'prepend' : 'c3178fa191f0ef1679011778d6d2bffc8a257460014bf7fcfa4c0e0a091d894a' },
{ 'sha256' : '' },
{ 'sha256' : '' }
]
}];
testInputs.forEach(input => {
const computedMerkleRoot = buildMerkleRoot(input.targetHash, input.proof);
console.log(computedMerkleRoot, input.merkleRoot, computedMerkleRoot === input.merkleRoot);
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment