node-stratum-pool/coinbase.js
Matthew Little a13950e4fd updated
2014-01-06 15:25:56 -05:00

158 lines
4.2 KiB
JavaScript

/*
Ported from https://github.com/slush0/stratum-mining
*/
var binpack = require('/usr/lib/node_modules/binpack');
var buffertools = require('/usr/lib/node_modules/buffertools');
var util = require('./util.js');
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 extranonce_placeholder = new Buffer('f000000ff111111f', 'hex');
exports.extranonce_size = extranonce_placeholder.length;
function GenerationTransaction(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];
}
GenerationTransaction.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
]);
}
};
exports.GenerationTransaction = GenerationTransaction;