Created
December 27, 2017 04:01
-
-
Save JCThePants/c3c96ca97cd673dace69fe389588af66 to your computer and use it in GitHub Desktop.
Modified for use with znodes
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var util = require('./util.js'); | |
exports.CreateGeneration = function (args) { | |
var rpcData = args.rpcData; | |
var publicKey = args.publicKey; | |
var extraNoncePlaceholder = args.extraNoncePlaceholder; | |
var rewardType = args.rewardType; | |
var txMessages = args.txMessages; | |
var fixedRewards = args.fixedRewards; | |
var auxMerkleTree = args.auxMerkleTree; | |
var txInputsCount = 1; | |
var txOutputsCount = 1; | |
var txVersion = txMessages === true ? 2 : 1; | |
var txLockTime = 0; | |
var txInPrevOutHash = 0; | |
var txInPrevOutIndex = Math.pow(2, 32) - 1; | |
var txInSequence = 0; | |
//Only required for POS coins | |
var txTimestamp = rewardType === 'POS' ? | |
util.packUInt32LE(rpcData.curtime) : new Buffer([]); | |
//For coins that support/require transaction comments | |
var txComment = txMessages === true ? | |
util.serializeString('https://github.com/UNOMP/node-merged-pool') : | |
new Buffer([]); | |
var scriptSigPart1 = Buffer.concat([ | |
util.serializeNumber(rpcData.height), | |
new Buffer(rpcData.coinbaseaux.flags, 'hex'), | |
util.serializeNumber(Date.now() / 1000 | 0), | |
new Buffer([extraNoncePlaceholder.length]), | |
new Buffer('fabe6d6d', 'hex'), | |
util.reverseBuffer(auxMerkleTree.root), | |
util.packUInt32LE(auxMerkleTree.data.length), | |
util.packUInt32LE(0) | |
]); | |
var scriptSigPart2 = util.serializeString('/nodeStratum/'); | |
var p1 = Buffer.concat([ | |
util.packUInt32LE(txVersion), | |
txTimestamp, | |
//transaction input | |
util.varIntBuffer(txInputsCount), | |
util.uint256BufferFromHash(txInPrevOutHash), | |
util.packUInt32LE(txInPrevOutIndex), | |
util.varIntBuffer(scriptSigPart1.length + extraNoncePlaceholder.length + scriptSigPart2.length), | |
scriptSigPart1 | |
]); | |
/* | |
The generation transaction must be split at the extranonce (which located in the transaction input | |
scriptSig). Miners send us unique extranonces that we use to join the two parts in attempt to create | |
a valid share and/or block. | |
*/ | |
var outputTransactions = generateOutputTransactions(publicKey, fixedRewards, rpcData); | |
var p2 = Buffer.concat([ | |
scriptSigPart2, | |
util.packUInt32LE(txInSequence), | |
//end transaction input | |
//transaction output | |
outputTransactions, | |
//end transaction ouput | |
util.packUInt32LE(txLockTime), | |
txComment | |
]); | |
return [p1, p2]; | |
}; | |
/* | |
This function creates the generation transaction that accepts the reward for | |
successfully mining a new block. | |
For some (probably outdated and incorrect) documentation about whats kinda going on here, | |
see: https://en.bitcoin.it/wiki/Protocol_specification#tx | |
*/ | |
function generateOutputTransactions(poolRecipient, fixedRewards, blockTemplate) { | |
var rewardAmount = blockTemplate.coinbasevalue; | |
var rewardToPool = rewardAmount; | |
var txOutputBuffers = []; | |
/* Dash 12.1 */ | |
var masternode = blockTemplate.masternode; | |
var superblock = blockTemplate.superblock; | |
if (masternode && superblock) { | |
if (masternode.payee) { | |
var payeeReward = masternode.amount; | |
rewardAmount -= payeeReward; | |
rewardToPool -= payeeReward; | |
var payeeScript = util.addressToScript(masternode.payee); | |
txOutputBuffers.push(Buffer.concat([ | |
util.packInt64LE(payeeReward), | |
util.varIntBuffer(payeeScript.length), | |
payeeScript | |
])); | |
} | |
else if (superblock.length > 0) { | |
for (var i in superblock) { | |
var payeeReward = 0; | |
payeeReward = superblock[i].amount; | |
rewardAmount -= payeeReward; | |
rewardToPool -= payeeReward; | |
var payeeScript = util.addressToScript(superblock[i].payee); | |
txOutputBuffers.push(Buffer.concat([ | |
util.packInt64LE(payeeReward), | |
util.varIntBuffer(payeeScript.length), | |
payeeScript | |
])); | |
} | |
} | |
} | |
// Zcoin znodes | |
if (blockTemplate.znode) { | |
var znode = blockTemplate.znode; | |
if (znode.payee) { | |
var payeeReward = znode.amount; | |
var payeeScript = util.addressToScript(znode.payee); | |
txOutputBuffers.push(Buffer.concat([ | |
util.packInt64LE(payeeReward), | |
util.varIntBuffer(payeeScript.length), | |
payeeScript | |
])); | |
} | |
} | |
// Payee | |
if (blockTemplate.payee) { | |
var payeeReward = 0; | |
if (blockTemplate.payee_amount) { | |
payeeReward = blockTemplate.payee_amount; | |
} | |
else { | |
payeeReward = Math.ceil(rewardAmount / 5); | |
} | |
rewardAmount -= payeeReward; | |
rewardToPool -= payeeReward; | |
var payeeScript = util.addressToScript(blockTemplate.payee); | |
txOutputBuffers.push(Buffer.concat([ | |
util.packInt64LE(payeeReward), | |
util.varIntBuffer(payeeScript.length), | |
payeeScript | |
])); | |
} | |
// Fixed rewards | |
fixedRewards.forEachReward(rewardAmount, function(recipientReward, recipientInfo) { | |
// subtract from pool reward | |
if (recipientInfo.subtractFromPool) | |
rewardToPool -= recipientReward; | |
txOutputBuffers.push(Buffer.concat([ | |
util.packInt64LE(recipientReward), | |
util.varIntBuffer(recipientInfo.script.length), | |
recipientInfo.script | |
])); | |
}); | |
// Payment to pool | |
txOutputBuffers.unshift(Buffer.concat([ | |
util.packInt64LE(rewardToPool), | |
util.varIntBuffer(poolRecipient.length), | |
poolRecipient | |
])); | |
if (blockTemplate.default_witness_commitment !== undefined) { | |
var witness_commitment = new Buffer(blockTemplate.default_witness_commitment, 'hex'); | |
txOutputBuffers.unshift(Buffer.concat([ | |
util.packInt64LE(0), | |
util.varIntBuffer(witness_commitment.length), | |
witness_commitment | |
])); | |
} | |
return Buffer.concat([ | |
util.varIntBuffer(txOutputBuffers.length), | |
Buffer.concat(txOutputBuffers) | |
]); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment