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
This commit is contained in:
Michael Polzer 2018-05-27 05:37:31 +03:00 committed by Matthew Little
parent 60c88a7c5f
commit eec9fc9d67
6 changed files with 51 additions and 54 deletions

View File

@ -9,7 +9,7 @@ var util = require('./util.js');
* The BlockTemplate class holds a single job. * The BlockTemplate class holds a single job.
* and provides several methods to validate and submit it to the daemon coin * 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 //private members
@ -71,7 +71,8 @@ var BlockTemplate = module.exports = function BlockTemplate(jobId, rpcData, pool
extraNoncePlaceholder, extraNoncePlaceholder,
reward, reward,
txMessages, txMessages,
recipients recipients,
network
); );
this.serializeCoinbase = function(extraNonce1, extraNonce2){ this.serializeCoinbase = function(extraNonce1, extraNonce2){

View File

@ -123,7 +123,8 @@ var JobManager = module.exports = function JobManager(options){
_this.extraNoncePlaceholder, _this.extraNoncePlaceholder,
options.coin.reward, options.coin.reward,
options.coin.txMessages, options.coin.txMessages,
options.recipients options.recipients,
options.network
); );
_this.currentJob = tmpBlockTemplate; _this.currentJob = tmpBlockTemplate;
@ -158,7 +159,8 @@ var JobManager = module.exports = function JobManager(options){
_this.extraNoncePlaceholder, _this.extraNoncePlaceholder,
options.coin.reward, options.coin.reward,
options.coin.txMessages, options.coin.txMessages,
options.recipients options.recipients,
options.network
); );
this.currentJob = tmpBlockTemplate; this.currentJob = tmpBlockTemplate;

View File

@ -273,7 +273,7 @@ var pool = module.exports = function pool(options, authorizeFn){
if (r.length === 40) if (r.length === 40)
rObj.script = util.miningKeyToScript(r); rObj.script = util.miningKeyToScript(r);
else else
rObj.script = util.addressToScript(r); rObj.script = util.addressToScript(options.network, r);
recipients.push(rObj); recipients.push(rObj);
options.feePercent += percent; options.feePercent += percent;
} }
@ -414,17 +414,19 @@ var pool = module.exports = function pool(options, authorizeFn){
return; return;
} }
options.testnet = (rpcResults.getblockchaininfo.chain === 'test') ? true : false;
options.network = (options.testnet ? options.coin.testnet : options.coin.mainnet);
options.poolAddressScript = (function(){ options.poolAddressScript = (function(){
switch(options.coin.reward){ switch(options.coin.reward){
case 'POS': case 'POS':
return util.pubkeyToScript(rpcResults.validateaddress.pubkey); return util.pubkeyToScript(rpcResults.validateaddress.pubkey);
case 'POW': 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.protocolVersion = rpcResults.getnetworkinfo.protocolversion;
options.initStats = { options.initStats = {

View File

@ -123,7 +123,7 @@ For some (probably outdated and incorrect) documentation about whats kinda going
see: https://en.bitcoin.it/wiki/Protocol_specification#tx 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 reward = rpcData.coinbasevalue;
var rewardToPool = reward; var rewardToPool = reward;
@ -132,52 +132,52 @@ var generateOutputTransactions = function(poolRecipient, recipients, rpcData){
/* Dash 12.1 */ /* Dash 12.1 */
if (rpcData.masternode && rpcData.superblock) { if (rpcData.masternode && rpcData.superblock) {
if (rpcData.masternode.payee) { 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){
var payeeReward = 0; var payeeReward = 0;
payeeReward = rpcData.superblock[i].amount; payeeReward = rpcData.masternode.amount;
reward -= payeeReward; reward -= payeeReward;
rewardToPool -= payeeReward; rewardToPool -= payeeReward;
var payeeScript = util.addressToScript(rpcData.superblock[i].payee); var payeeScript = util.addressToScript(network, rpcData.masternode.payee);
txOutputBuffers.push(Buffer.concat([ txOutputBuffers.push(Buffer.concat([
util.packInt64LE(payeeReward), util.packInt64LE(payeeReward),
util.varIntBuffer(payeeScript.length), util.varIntBuffer(payeeScript.length),
payeeScript 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) { if (rpcData.payee) {
var payeeReward = 0; var payeeReward = 0;
if (rpcData.payee_amount) { if (rpcData.payee_amount) {
payeeReward = rpcData.payee_amount; payeeReward = rpcData.payee_amount;
} else { } else {
payeeReward = Math.ceil(reward / 5); payeeReward = Math.ceil(reward / 5);
} }
reward -= payeeReward; reward -= payeeReward;
rewardToPool -= payeeReward; rewardToPool -= payeeReward;
var payeeScript = util.addressToScript(rpcData.payee); var payeeScript = util.addressToScript(network, rpcData.payee);
txOutputBuffers.push(Buffer.concat([ txOutputBuffers.push(Buffer.concat([
util.packInt64LE(payeeReward), util.packInt64LE(payeeReward),
util.varIntBuffer(payeeScript.length), 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 txInputsCount = 1;
var txOutputsCount = 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([ var p2 = Buffer.concat([
scriptSigPart2, scriptSigPart2,

View File

@ -2,6 +2,7 @@ var crypto = require('crypto');
var base58 = require('base58-native'); var base58 = require('base58-native');
var bignum = require('bignum'); var bignum = require('bignum');
var bitcoin = require('bitcoinjs-lib');
exports.addressFromEx = function(exAddress, ripdm160Key){ 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 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 (typeof network !== 'undefined' && network !== null){
return bitcoin.address.toOutputScript(addr, network);
if (decoded.length != 25){ } else {
console.error('invalid address length for ' + addr); return Buffer.concat([new Buffer([0x76, 0xa9, 0x14]), bitcoin.address.fromBase58Check(addr).hash, new Buffer([0x88, 0xac])]);
throw new Error();
} }
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){ exports.getReadableHashRateString = function(hashrate){
var i = -1; var i = -1;
var byteUnits = [ ' KH', ' MH', ' GH', ' TH', ' PH' ]; var byteUnits = [ ' KH', ' MH', ' GH', ' TH', ' PH' ];

View File

@ -29,6 +29,7 @@
}, },
"dependencies": { "dependencies": {
"multi-hashing": "git://github.com/zone117x/node-multi-hashing.git", "multi-hashing": "git://github.com/zone117x/node-multi-hashing.git",
"bitcoinjs-lib": "*",
"bignum": "*", "bignum": "*",
"base58-native": "*", "base58-native": "*",
"async": "*" "async": "*"