diff --git a/blockTemplate.js b/blockTemplate.js index 48c5713..ba2392b 100644 --- a/blockTemplate.js +++ b/blockTemplate.js @@ -14,7 +14,7 @@ var BlockTemplate = module.exports = function BlockTemplate(jobId, rpcData, publ function getMerkleHashes(steps){ return steps.map(function(step){ - return util.reverseBuffer(step).toString('hex'); + return step.toString('hex'); }); } @@ -31,7 +31,7 @@ var BlockTemplate = module.exports = function BlockTemplate(jobId, rpcData, publ this.rpcData = rpcData; this.jobId = jobId; this.target = util.bignumFromBits(rpcData.bits); - this.previousHashBuffer = util.reverseHex(rpcData.previousblockhash); + this.prevHashReversed = util.reverseByteOrder(new Buffer(rpcData.previousblockhash, 'hex')).toString('hex'); this.transactionData = Buffer.concat(rpcData.transactions.map(function(tx){ return new Buffer(tx.data, 'hex'); })); @@ -65,19 +65,7 @@ var BlockTemplate = module.exports = function BlockTemplate(jobId, rpcData, publ header.writeUInt32BE(rpcData.version, position + 32); var header = util.reverseBuffer(header); - var test = header.toString('hex'); - - return header; - - /*return Buffer.concat([ - binpack.packInt32(rpcData.version, 'big'), - this.previousHashBuffer, - merkleRootBuffer, - nTimeBuffer, - new Buffer(this.rpcData.bits, 'hex'), - nonceBuffer - ]);*/ }; this.serializeBlock = function(header, coinbase){ @@ -102,7 +90,7 @@ var BlockTemplate = module.exports = function BlockTemplate(jobId, rpcData, publ if (!this.jobParams){ this.jobParams = [ this.jobId, - this.previousHashBuffer, + this.prevHashReversed, this.generationTransaction.coinbase[0].toString('hex'), this.generationTransaction.coinbase[1].toString('hex'), this.merkleBranch, @@ -114,4 +102,8 @@ var BlockTemplate = module.exports = function BlockTemplate(jobId, rpcData, publ } return this.jobParams; } + + //this.jobParams = this.getJobParams(); + //console.log(JSON.stringify(this.jobParams, null, ' ').replace(/\n/g ,'')); + } \ No newline at end of file diff --git a/jobManager.js b/jobManager.js index f33c84d..266e304 100644 --- a/jobManager.js +++ b/jobManager.js @@ -61,19 +61,38 @@ var JobManager = module.exports = function JobManager(options){ _this.emit('newBlock', blockTemplate); } - var diffDividend = bignum.fromBuffer(new Buffer((function(){ + var diffDividend = (function(){ switch(options.algorithm){ case 'sha256': - return '00000000ffff0000000000000000000000000000000000000000000000000000'; + return 0x00000000ffff0000000000000000000000000000000000000000000000000000; case 'scrypt': case 'scrypt-jane': - return '0000ffff00000000000000000000000000000000000000000000000000000000'; + return 0x0000ffff00000000000000000000000000000000000000000000000000000000; case 'quark': - return '000000ffff000000000000000000000000000000000000000000000000000000' + return 0x000000ffff000000000000000000000000000000000000000000000000000000; } - })(), 'hex')); - + })(); + var hashDigest = (function(){ + switch(options.algorithm){ + case 'sha256': + return function(){ + return util.doublesha.apply(this, arguments); + } + case 'scrypt': + return function(){ + return scrypt.digest.apply(this, arguments); + } + case 'scrypt-jane': + return function(){ + return scryptJane.digest.apply(this, arguments); + } + case 'quark': + return function(){ + return quark.digest.apply(this, arguments); + } + } + })(); //public members @@ -94,25 +113,20 @@ var JobManager = module.exports = function JobManager(options){ if (extraNonce2.length / 2 !== _this.extraNonce2Size) return {error: [20, 'incorrect size of extranonce2', null]}; - var job = jobs[jobId]; if (!job) return {error: [21, 'job not found', null]}; - if (nTime.length !== 8) return {error: [20, 'incorrect size of ntime']}; - var nTimeInt = parseInt(nTime, 16); if (nTimeInt < job.rpcData.curtime || nTime > submitTime + 7200) return {error: [20, 'ntime out of range', null]}; - if (nonce.length !== 8) return {error: [20, 'incorrect size of nonce']}; - if (!job.registerSubmit(extraNonce1, extraNonce2, nTime, nonce)) return {error: [22, 'duplicate share', null]}; @@ -124,25 +138,10 @@ var JobManager = module.exports = function JobManager(options){ var coinbaseHash = util.doublesha(coinbaseBuffer); var merkleRoot = job.merkleTree.withFirst(coinbaseHash); - for (var i = 0; i < 8; i++) merkleRoot.writeUInt32LE(merkleRoot.readUInt32BE(i * 4), i * 4); merkleRoot = util.reverseBuffer(merkleRoot).toString('hex'); var headerBuffer = job.serializeHeader(merkleRoot, nTime, nonce); - for (var i = 0; i < 20; i++) headerBuffer.writeUInt32LE(headerBuffer.readUInt32BE(i * 4), i * 4); - var headerHash = (function(){ - switch(options.algorithm){ - case 'sha256': - return util.doublesha(headerBuffer); - case 'scrypt': - return scrypt.digest(headerBuffer); - case 'scrypt-jane': - return scryptJane.digest(headerBuffer, nTimeInt); - case 'quark': - return quark.digest(headerBuffer); - } - })(); - - + var headerHash = hashDigest(headerBuffer, nTimeInt); var headerBigNum = bignum.fromBuffer(headerHash, {endian: 'little', size: 32}); if (job.target.ge(headerBigNum)){ @@ -150,10 +149,8 @@ var JobManager = module.exports = function JobManager(options){ _this.emit('blockFound', blockHex); } - var targetUser = diffDividend.div(difficulty); + var targetUser = bignum(diffDividend / difficulty); if (headerBigNum.gt(targetUser)){ - console.log('target:' + targetUser.toString()); - console.log('share:' + headerBigNum.toString()); return {error: [23, 'low difficulty share', null]}; } diff --git a/main.js b/main.js index d5ee1cf..80700cf 100644 --- a/main.js +++ b/main.js @@ -16,8 +16,8 @@ var coins = [ symbol: 'doge', algorithm: 'scrypt', //or sha256, scrypt-jane, quark reward: 'POW', //or POS - address: 'D5uXR7F6bTCJKRZBqj1D4gyHF9MHAd5oNs', - stratumPort: 3333, + address: 'DDt79i6P3Wro3SD3HSnkRLpMgUGUGdiNhS', + stratumPort: 3334, difficulty: 8, daemon: { bin: 'dogecoind', diff --git a/pool.js b/pool.js index dd0731e..fe956b2 100644 --- a/pool.js +++ b/pool.js @@ -1,5 +1,6 @@ var net = require('net'); var events = require('events'); +var fs = require('fs'); var async = require('async'); @@ -51,8 +52,10 @@ var pool = module.exports = function pool(coin){ console.log('getblocktemplate rpc error for ' + coin.options.name); callback(error); } - else + else{ + //result = JSON.parse(fs.readFileSync('example.json')); callback(null, result); + } } ); }, @@ -95,9 +98,6 @@ var pool = module.exports = function pool(coin){ _this.jobManager.newTemplate(results.rpcTemplate, publicKeyBuffer); - //console.log(results.rpcTemplate); - //console.log(_this.jobManager.currentJob.getJobParams()); - }); }).on('startFailed', function(){ diff --git a/test.js b/test.js index bdacab6..3dd736a 100644 --- a/test.js +++ b/test.js @@ -9,6 +9,7 @@ var reverseBuffer = function(buff){ return reversed; }; +/* var hash = new Buffer("38f3e68be0b74813af175b8da506dfa3c3017ff06fed7ae85e3efee655c9f7fd", 'hex'); var goal = "8be6f3381348b7e08d5b17afa3df06a5f07f01c3e87aed6fe6fe3e5efdf7c955"; @@ -25,6 +26,7 @@ console.log('maybe: ' + nHash.toString('hex')); var wow = bignum.fromBuffer(hash, {endian: 'little', size: 32}).toBuffer({endian: 'big', size: 32}).toString('hex'); console.log(wow); console.log(wow == goal ? 'good' : 'fuck'); +*/ /* @@ -88,7 +90,6 @@ version = 1; merkleroot = reverseBuffer(new Buffer(merkleroot, 'hex')).toString('hex'); var serializeHeader = function(){ - var header = new Buffer(80); var position = 0; header.write(nonce, position, 4, 'hex'); @@ -98,9 +99,23 @@ var serializeHeader = function(){ header.write(pbh, position += 32, 32, 'hex'); header.writeUInt32BE(version, position + 32); var header = reverseBuffer(header); - - var test = header.toString('hex'); - return header; - }; + +var headerBuff = serializeHeader(); +var headerHashed = scrypt.digest(headerBuff); +var hashInt = bignum.fromBuffer(headerHashed, {endian: 'little', size: 32}); + + +//var diffDividend = bignum.fromBuffer(new Buffer('0000ffff00000000000000000000000000000000000000000000000000000000'), 'hex'); +//var target = diffDividend.div(16) + +var dividend = 0x0000ffff00000000000000000000000000000000000000000000000000000000; +var target = dividend / 16; + +var big = bignum(target); + +console.log('dividend ' + big.toString()); + +console.log('hash ' + hashInt.toString()) +console.log('target ' + target.toString()); \ No newline at end of file diff --git a/transactions.js b/transactions.js index fbbb5d0..e67cf88 100644 --- a/transactions.js +++ b/transactions.js @@ -5,26 +5,12 @@ var util = require('./util.js'); function Transaction(params){ - var version; - var inputs; - var outputs; - var lockTime; - (function init(){ - if (typeof(params) === "object"){ - version = params.version || 1; - inputs = params.inputs || []; - outputs = params.outputs || []; - lockTime = params.lockTime || 0; - } - else if (typeof(params) === "string"){ - fromRaw(params); - } - })(); + var version = params.version || 1, + inputs = params.inputs || [], + outputs = params.outputs || [], + lockTime = params.lockTime || 0; - function fromRaw(raw){ - - } this.toBuffer = function(){ return Buffer.concat([ @@ -43,28 +29,15 @@ function Transaction(params){ } function TransactionInput(params){ - var prevOutHash; - var prevOutIndex; - var sigScriptBuffer; - var sequence; - (function init(){ - if (typeof(params) === "object"){ - prevOutHash = params.prevOutHash || 0; - prevOutIndex = params.prevOutIndex; - sigScriptBuffer = params.sigScriptBuffer; - sequence = params.sequence || 0; - } - else if (typeof(params) === "string"){ - fromRaw(params); - } - })(); + var prevOutHash = params.prevOutHash || 0, + prevOutIndex = params.prevOutIndex, + sigScript = params.sigScript, + sequence = params.sequence || 0; - function fromRaw(raw){ - - } this.toBuffer = function(){ + sigScriptBuffer = sigScript.toBuffer(); return Buffer.concat([ util.uint256BufferFromHash(prevOutHash), binpack.packUInt32(prevOutIndex, 'little'), @@ -77,22 +50,8 @@ function TransactionInput(params){ function TransactionOutput(params){ - var value; - var pkScriptBuffer; - - (function init(){ - if (typeof(params) === "object"){ - value = params.value; - pkScriptBuffer = params.pkScriptBuffer; - } - else if (typeof(params) === "string"){ - fromRaw(params); - } - })(); - - function fromRaw(raw){ - - } + var value = params.value, + pkScriptBuffer = params.pkScriptBuffer; this.toBuffer = function(){ return Buffer.concat([ @@ -103,25 +62,36 @@ function TransactionOutput(params){ }; } -var buildScriptSig = function(height, flags, extraNoncePlaceholder){ - return Buffer.concat([ - util.serializeNumber(height), - new Buffer(flags, 'hex'), - util.serializeNumber(Date.now() / 1000 | 0), - new Buffer([extraNoncePlaceholder.length]), - extraNoncePlaceholder, - util.serializeString('/nodeStratum/') - ]); +function ScriptSig(params){ + + var height = params.height, + flags = params.flags, + extraNoncePlaceholder = params.extraNoncePlaceholder; + + this.toBuffer = function(){ + + return Buffer.concat([ + util.serializeNumber(height), + new Buffer(flags, 'hex'), + util.serializeNumber(Date.now() / 1000 | 0), + new Buffer([extraNoncePlaceholder.length]), + extraNoncePlaceholder, + util.serializeString('/nodeStratum/') + ]); + } + }; var Generation = exports.Generation = function Generation(rpcData, publicKey, extraNoncePlaceholder){ - var scriptSig = buildScriptSig(rpcData.height, rpcData.coinbaseaux.flags, extraNoncePlaceholder); - var tx = new Transaction({ inputs: [new TransactionInput({ prevOutIndex: Math.pow(2, 32) - 1, - sigScriptBuffer: scriptSig + sigScript: new ScriptSig({ + height: rpcData.height, + flags: rpcData.coinbaseaux.flags, + extraNoncePlaceholder: extraNoncePlaceholder + }) })], outputs: [new TransactionOutput({ value: rpcData.coinbasevalue, @@ -137,150 +107,4 @@ var Generation = exports.Generation = function Generation(rpcData, publicKey, ex this.transaction = tx; this.coinbase = [p1, p2]; -}; - - - - -/* - -function COutPoint(){ - this.hash = 0; - this.n = 0; -} -COutPoint.prototype = { - deserialize: function(f){ - this.hash = util.hexFromReversedBuffer(f.read(32)); - this.n = f.read(4).readUInt32LE(0); - }, - serialize: function(){ - return Buffer.concat([ - util.uint256BufferFromHash(this.hash), - binpack.packUInt32(this.n, 'little') - ]); - } -}; - - -function CTxIn(){ - this.prevout = new COutPoint(); - this.scriptSig = ""; - this.nSequence = 0; -} -CTxIn.prototype = { - deserialize: function(f){ - this.prevout = new COutPoint(); - this.prevout.deserialize(f); - this.scriptSig = util.deser_string(f); - this.nSequence = f.read(4).readUInt32LE(0); - }, - serialize: function(){ - return Buffer.concat([ - this.prevout.serialize(), - util.ser_string(this.scriptSig), - binpack.packUInt32(this.nSequence, 'little') - ]); - } -}; - - -function CTxOut(){ - this.nValue = 0; - this.scriptPubKey = ''; -} -CTxOut.prototype = { - deserialize: function(f){ - this.nValue = f.read(8).readInt64LE(0); - this.scriptPubKey = util.deser_string(f); - }, - serialize: function(){ - return Buffer.concat([ - binpack.packInt64(this.nValue, 'little'), - util.ser_string(this.scriptPubKey) - ]); - } -}; - - -function CTransaction(){ - this.nVersion = 1; - this.vin = []; - this.vout = []; - this.nLockTime = 0; - this.sha256 = null; -}; -CTransaction.prototype = { - deserialize: function(f){ - util.makeBufferReadable(f); - this.nVersion = f.read(4).readInt32LE(0); - this.vin = util.deser_vector(f, CTxIn); - this.vout = util.deser_vector(f, CTxOut); - this.nLockTime = r.read(4).readUInt32LE(0); - this.sha256 = null; - }, - serialize: function(){ - return Buffer.concat([ - binpack.packInt32(this.nVersion, 'little'), - util.ser_vector(this.vin), - util.ser_vector(this.vout), - binpack.packUInt32(this.nLockTime, 'little') - ]); - } -}; -exports.CTransaction = CTransaction; - - -var Generation = exports.Generation = function Generation(coinbaseValue, coinbaseAuxFlags, height, address){ - var CTrans = new CTransaction(); - - var tx_in = new CTxIn(); - tx_in.prevout.hash = 0; - tx_in.prevout.n = Math.pow(2, 32) - 1; - tx_in._scriptSig_template = [ - Buffer.concat([ - util.serializeNumber(height), - new Buffer(coinbaseAuxFlags, 'hex'), - util.serializeNumber(Date.now() / 1000 | 0), - new Buffer([exports.extranonce_size]) - ]), - util.ser_string('/stratum/') - ]; - - tx_in.scriptSig = Buffer.concat([ - tx_in._scriptSig_template[0], - extranonce_placeholder, - tx_in._scriptSig_template[1] - ]); - - var tx_out = new CTxOut(); - tx_out.nValue = coinbaseValue; - tx_out.scriptPubKey = util.script_to_address(address); - - CTrans.vin.push(tx_in); - CTrans.vout.push(tx_out); - - var cTransBin = CTrans.serialize(); - var epIndex = buffertools.indexOf(cTransBin, extranonce_placeholder); - var p1 = cTransBin.slice(0, epIndex); - var p2 = cTransBin.slice(epIndex + extranonce_placeholder.length); - - this.tx = CTrans; - this.serialized = [p1, p2]; -} -Generation.prototype = { - setExtraNonce: function(extraNonce){ - if (extraNonce.length != exports.extranonce_size){ - throw "Incorrect extranonce size"; - } - - var part1 = this.tx.vin[0]._scriptSig_template[0]; - var part2 = this.tx.vin[0]._scriptSig_template[1]; - this.tx.vin[0].scriptSig = Buffer.concat([ - part1, - extraNonce, - part2 - ]); - - } -}; -*/ \ No newline at end of file +}; \ No newline at end of file diff --git a/util.js b/util.js index 2463167..cf346b3 100644 --- a/util.js +++ b/util.js @@ -46,6 +46,11 @@ exports.reverseHex = function(hex){ return exports.reverseBuffer(new Buffer(hex, 'hex')).toString('hex'); }; +exports.reverseByteOrder = function(buff){ + for (var i = 0; i < 8; i++) buff.writeUInt32LE(buff.readUInt32BE(i * 4), i * 4); + return exports.reverseBuffer(buff); +}; + exports.uint256BufferFromHash = function(hex){ var fromHex = new Buffer(hex, 'hex'); @@ -64,6 +69,29 @@ exports.hexFromReversedBuffer = function(buffer){ return exports.reverseBuffer(buffer).toString('hex'); }; +exports.varIntBuffer = function(n){ + if (n < 0xfd) + return new Buffer([n]); + else if (n < 0xffff){ + var buff = new Buffer(3); + buff[0] = 0xfd; + buff.writeUInt16LE(n, 1); + return buff; + } + else if (n < 0xffffffff){ + var buff = new Buffer(5); + buff[0] = 0xfe; + buff.writeUInt32LE(n, 1); + return buff; + } + else{ + var buff = new Buffer(9); + buff[0] = 0xff; + binpack.packUInt64(n, 'little').copy(buff, 1); + return buff; + } +}; + exports.serializeNumber = function(n){ if (n < 0xfd){ var buff = new Buffer(2); @@ -74,13 +102,13 @@ exports.serializeNumber = function(n){ else if (n <= 0xffff){ var buff = new Buffer(4); buff[0] = 0x3; - buff.writeUInt16BE(n, 1); + buff.writeUInt16LE(n, 1); return buff; } else if (n <= 0xffffffff){ - var buff = new Buffer(6); - buff[0] = 0x5; - buff.writeUInt32BE(n, 1); + var buff = new Buffer(5); + buff[0] = 0x4; + buff.writeUInt32LE(n, 1); return buff; } else{ @@ -115,29 +143,6 @@ exports.serializeString = function(s){ ]); }; -exports.varIntBuffer = function(n){ - if (n < 0xfd) - return new Buffer([n]); - else if (n < 0xffff){ - var buff = new Buffer(3); - buff[0] = 0xfd; - buff.writeUInt16LE(n, 1); - return buff; - } - else if (n < 0xffffffff){ - var buff = new Buffer(5); - buff[0] = 0xfe; - buff.writeUInt32LE(n, 1); - return buff; - } - else{ - var buff = new Buffer(9); - buff[0] = 0xff; - binpack.packUInt64(n, 'little').copy(buff, 1); - return buff; - } -}; - exports.range = function(start, stop, step){ if (typeof stop === 'undefined'){ stop = start;