From eec9fc9d67f2a810409e3efca39b94f14995c304 Mon Sep 17 00:00:00 2001 From: Michael Polzer Date: Sun, 27 May 2018 05:37:31 +0300 Subject: [PATCH] Add support for p2sh, BIP32 and bech32 decoding (#147) * Add Support for CHC Algo * decode p2sh, BIP32 and native SegWit (bech32) keys for use in coinbase transactions --- lib/blockTemplate.js | 5 ++-- lib/jobManager.js | 6 +++-- lib/pool.js | 10 ++++--- lib/transactions.js | 62 ++++++++++++++++++++++---------------------- lib/util.js | 21 +++++---------- package.json | 1 + 6 files changed, 51 insertions(+), 54 deletions(-) diff --git a/lib/blockTemplate.js b/lib/blockTemplate.js index 723e0cf..8e6e557 100644 --- a/lib/blockTemplate.js +++ b/lib/blockTemplate.js @@ -9,7 +9,7 @@ var util = require('./util.js'); * The BlockTemplate class holds a single job. * and provides several methods to validate and submit it to the daemon coin **/ -var BlockTemplate = module.exports = function BlockTemplate(jobId, rpcData, poolAddressScript, extraNoncePlaceholder, reward, txMessages, recipients){ +var BlockTemplate = module.exports = function BlockTemplate(jobId, rpcData, poolAddressScript, extraNoncePlaceholder, reward, txMessages, recipients, network){ //private members @@ -71,7 +71,8 @@ var BlockTemplate = module.exports = function BlockTemplate(jobId, rpcData, pool extraNoncePlaceholder, reward, txMessages, - recipients + recipients, + network ); this.serializeCoinbase = function(extraNonce1, extraNonce2){ diff --git a/lib/jobManager.js b/lib/jobManager.js index cbcfc48..b8951a3 100644 --- a/lib/jobManager.js +++ b/lib/jobManager.js @@ -123,7 +123,8 @@ var JobManager = module.exports = function JobManager(options){ _this.extraNoncePlaceholder, options.coin.reward, options.coin.txMessages, - options.recipients + options.recipients, + options.network ); _this.currentJob = tmpBlockTemplate; @@ -158,7 +159,8 @@ var JobManager = module.exports = function JobManager(options){ _this.extraNoncePlaceholder, options.coin.reward, options.coin.txMessages, - options.recipients + options.recipients, + options.network ); this.currentJob = tmpBlockTemplate; diff --git a/lib/pool.js b/lib/pool.js index 72c057b..11363d0 100644 --- a/lib/pool.js +++ b/lib/pool.js @@ -273,7 +273,7 @@ var pool = module.exports = function pool(options, authorizeFn){ if (r.length === 40) rObj.script = util.miningKeyToScript(r); else - rObj.script = util.addressToScript(r); + rObj.script = util.addressToScript(options.network, r); recipients.push(rObj); options.feePercent += percent; } @@ -414,17 +414,19 @@ var pool = module.exports = function pool(options, authorizeFn){ return; } + options.testnet = (rpcResults.getblockchaininfo.chain === 'test') ? true : false; + + options.network = (options.testnet ? options.coin.testnet : options.coin.mainnet); + options.poolAddressScript = (function(){ switch(options.coin.reward){ case 'POS': return util.pubkeyToScript(rpcResults.validateaddress.pubkey); case 'POW': - return util.addressToScript(rpcResults.validateaddress.address); + return util.addressToScript(options.network, rpcResults.validateaddress.address); } })(); - options.testnet = (rpcResults.getblockchaininfo.chain === 'test') ? true : false; - options.protocolVersion = rpcResults.getnetworkinfo.protocolversion; options.initStats = { diff --git a/lib/transactions.js b/lib/transactions.js index dd952ae..61929a9 100644 --- a/lib/transactions.js +++ b/lib/transactions.js @@ -123,7 +123,7 @@ For some (probably outdated and incorrect) documentation about whats kinda going see: https://en.bitcoin.it/wiki/Protocol_specification#tx */ -var generateOutputTransactions = function(poolRecipient, recipients, rpcData){ +var generateOutputTransactions = function(poolRecipient, recipients, rpcData, network){ var reward = rpcData.coinbasevalue; var rewardToPool = reward; @@ -132,52 +132,52 @@ var generateOutputTransactions = function(poolRecipient, recipients, rpcData){ -/* Dash 12.1 */ -if (rpcData.masternode && rpcData.superblock) { - if (rpcData.masternode.payee) { - var payeeReward = 0; - - payeeReward = rpcData.masternode.amount; - reward -= payeeReward; - rewardToPool -= payeeReward; - - var payeeScript = util.addressToScript(rpcData.masternode.payee); - txOutputBuffers.push(Buffer.concat([ - util.packInt64LE(payeeReward), - util.varIntBuffer(payeeScript.length), - payeeScript - ])); - } else if (rpcData.superblock.length > 0) { - for(var i in rpcData.superblock){ + /* Dash 12.1 */ + if (rpcData.masternode && rpcData.superblock) { + if (rpcData.masternode.payee) { var payeeReward = 0; - payeeReward = rpcData.superblock[i].amount; + payeeReward = rpcData.masternode.amount; reward -= payeeReward; rewardToPool -= payeeReward; - var payeeScript = util.addressToScript(rpcData.superblock[i].payee); + var payeeScript = util.addressToScript(network, rpcData.masternode.payee); txOutputBuffers.push(Buffer.concat([ util.packInt64LE(payeeReward), util.varIntBuffer(payeeScript.length), payeeScript ])); + } else if (rpcData.superblock.length > 0) { + for(var i in rpcData.superblock){ + var payeeReward = 0; + + payeeReward = rpcData.superblock[i].amount; + reward -= payeeReward; + rewardToPool -= payeeReward; + + var payeeScript = util.addressToScript(network, rpcData.superblock[i].payee); + txOutputBuffers.push(Buffer.concat([ + util.packInt64LE(payeeReward), + util.varIntBuffer(payeeScript.length), + payeeScript + ])); + } } } -} -if (rpcData.payee) { - var payeeReward = 0; + if (rpcData.payee) { + var payeeReward = 0; - if (rpcData.payee_amount) { - payeeReward = rpcData.payee_amount; - } else { - payeeReward = Math.ceil(reward / 5); - } + if (rpcData.payee_amount) { + payeeReward = rpcData.payee_amount; + } else { + payeeReward = Math.ceil(reward / 5); + } reward -= payeeReward; rewardToPool -= payeeReward; - var payeeScript = util.addressToScript(rpcData.payee); + var payeeScript = util.addressToScript(network, rpcData.payee); txOutputBuffers.push(Buffer.concat([ util.packInt64LE(payeeReward), util.varIntBuffer(payeeScript.length), @@ -222,7 +222,7 @@ if (rpcData.payee) { }; -exports.CreateGeneration = function(rpcData, publicKey, extraNoncePlaceholder, reward, txMessages, recipients){ +exports.CreateGeneration = function(rpcData, publicKey, extraNoncePlaceholder, reward, txMessages, recipients, network){ var txInputsCount = 1; var txOutputsCount = 1; @@ -272,7 +272,7 @@ exports.CreateGeneration = function(rpcData, publicKey, extraNoncePlaceholder, r */ - var outputTransactions = generateOutputTransactions(publicKey, recipients, rpcData); + var outputTransactions = generateOutputTransactions(publicKey, recipients, rpcData, network); var p2 = Buffer.concat([ scriptSigPart2, diff --git a/lib/util.js b/lib/util.js index 394d059..03dfce3 100644 --- a/lib/util.js +++ b/lib/util.js @@ -2,6 +2,7 @@ var crypto = require('crypto'); var base58 = require('base58-native'); var bignum = require('bignum'); +var bitcoin = require('bitcoinjs-lib'); exports.addressFromEx = function(exAddress, ripdm160Key){ @@ -261,26 +262,16 @@ exports.miningKeyToScript = function(key){ /* For POW coins - used to format wallet address for use in generation transaction's output */ -exports.addressToScript = function(addr){ +exports.addressToScript = function(network, addr){ - var decoded = base58.decode(addr); - - if (decoded.length != 25){ - console.error('invalid address length for ' + addr); - throw new Error(); + if (typeof network !== 'undefined' && network !== null){ + return bitcoin.address.toOutputScript(addr, network); + } else { + return Buffer.concat([new Buffer([0x76, 0xa9, 0x14]), bitcoin.address.fromBase58Check(addr).hash, new Buffer([0x88, 0xac])]); } - if (!decoded){ - console.error('base58 decode failed for ' + addr); - throw new Error(); - } - - var pubkey = decoded.slice(1,-4); - - return Buffer.concat([new Buffer([0x76, 0xa9, 0x14]), pubkey, new Buffer([0x88, 0xac])]); }; - exports.getReadableHashRateString = function(hashrate){ var i = -1; var byteUnits = [ ' KH', ' MH', ' GH', ' TH', ' PH' ]; diff --git a/package.json b/package.json index 4bc8904..d1d560c 100644 --- a/package.json +++ b/package.json @@ -29,6 +29,7 @@ }, "dependencies": { "multi-hashing": "git://github.com/zone117x/node-multi-hashing.git", + "bitcoinjs-lib": "*", "bignum": "*", "base58-native": "*", "async": "*"