Created
May 12, 2013 08:41
-
-
Save brandon-lockaby/5562870 to your computer and use it in GitHub Desktop.
educational node bitcoin getwork pool cpu mining
This file contains hidden or 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
// educational node bitcoin getwork pool cpu mining | |
var request = require('request'); | |
var crypto = require('crypto'); | |
var json_rpc_id = 1; | |
function sha256(buf) { | |
var sha = crypto.createHash('sha256'); | |
sha.update(buf); | |
return sha.digest(); | |
} | |
function reverse_hex(str) { | |
var out = ""; | |
for(var i = 0; i < str.length; i += 2) { | |
out = str.substr(i, 2) + out; | |
} | |
return out; | |
} | |
function swap32(buf) { | |
if(buf.length % 4) throw "what"; | |
for(var i = 0; i < buf.length; i += 4) { | |
buf.writeUInt32BE(buf.readUInt32LE(i), i); | |
} | |
return buf; | |
} | |
var BlockHeader = function() {}; | |
BlockHeader.deserialize = function(buf) { | |
var blockheader = new BlockHeader(); | |
blockheader.ver = buf.readUInt32LE(0); | |
blockheader.prev_block = reverse_hex(buf.slice(4, 4+32).toString('hex')); | |
blockheader.mrkl_root = reverse_hex(buf.slice(36, 36+32).toString('hex')); | |
blockheader.time = buf.readUInt32LE(68); | |
blockheader.bits = buf.readUInt32LE(72); | |
blockheader.nonce = buf.readUInt32LE(76); | |
return blockheader; | |
} | |
BlockHeader.prototype.serialize = function() { | |
var buf = new Buffer(80); | |
buf.writeUInt32LE(this.ver, 0); | |
buf.write(reverse_hex(this.prev_block), 4, 32, 'hex'); | |
buf.write(reverse_hex(this.mrkl_root), 36, 32, 'hex'); | |
buf.writeUInt32LE(this.time, 68); | |
buf.writeUInt32LE(this.bits, 72); | |
buf.writeUInt32LE(this.nonce, 76); | |
return buf; | |
}; | |
BlockHeader.prototype.hash = function() { | |
return reverse_hex(sha256(sha256(this.serialize())).toString('hex')); | |
}; | |
var Work = function() {}; | |
Work.get = function(url, cb) { | |
var work = new Work(); | |
work.url = url; | |
request({ | |
url: url, | |
method: 'POST', | |
body: JSON.stringify({ | |
"method": "getwork", | |
"params": [], | |
"id": (json_rpc_id++) | |
}) | |
}, function(e, r, body) { | |
console.log("RESPONSE1:", body); | |
var result = JSON.parse(body); | |
work.data = result.result.data; | |
work.target = result.result.target; | |
work.current_nonce = work.getBlockHeader().nonce; // usually 0 | |
setImmediate(cb.bind(this, work)); | |
}); | |
}; | |
Work.prototype.getBlockHeader = function() { | |
var buf = new Buffer(this.data, 'hex'); | |
buf = swap32(buf); | |
return BlockHeader.deserialize(buf); | |
}; | |
Work.prototype.submit = function(blockheader) { | |
var url = this.url; | |
var data = swap32(blockheader.serialize()).toString('hex'); | |
data += this.data.substr(160); | |
var body = JSON.stringify({ | |
"method": "getwork", | |
"params": [data], | |
"id": (json_rpc_id++) | |
}); | |
console.log("SUBMIT:", body); | |
request({ | |
url: url, | |
method: 'POST', | |
body: body | |
}, function(e, r, body) { | |
console.log("RESPONSE2:", body); | |
}); | |
}; | |
Work.prototype.do = function(hashes, cb) { | |
var blockheader = this.getBlockHeader(); | |
for(var i = 0; i < hashes; i++) { | |
blockheader.nonce = ++this.current_nonce; | |
var hash = blockheader.hash(); | |
if(hash.indexOf("00000000") == 0) { | |
// todo: real target comparison | |
this.submit(blockheader); | |
} | |
} | |
}; | |
var url = 'http://user.worker:[email protected]:8332'; | |
var get_new_work = false; | |
var do_work = function(work) { | |
work.do(10000); | |
setImmediate(function() { | |
if(get_new_work) { | |
get_new_work = false; | |
Work.get(url, do_work); | |
} else { | |
do_work(work); | |
} | |
}); | |
}; | |
Work.get(url, do_work); | |
setInterval(function() { | |
get_new_work = true; | |
}, 1000 * 60 * 5); // 5 minutes... |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment