Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- -- In-game KristMiner
- -- By Anavrins
- -- Disclaimer: This is a proof of concept ONLY
- -- This is the fastest in-game krist miner out there, and will lag your ComputerCraft instance
- -- Do not run on online servers!
- local args = {...}
- local address = args[1]
- if not address then print("Usage: kmine <address>") return end
- local nodeurl = "https://krist.ceriat.net"
- local work
- local block
- local balance
- local solved = 0
- local nonce = 0
- local rate = 0
- local clock = os.clock
- local tonum = tonumber
- -- JSON (Compacted) By ElvishJerricco
- local json = loadstring([[local a={["\n"]="\\n",["\r"]="\\r",["\t"]="\\t",["\b"]="\\b",["\f"]="\\f",["\""]="\\\"",["\\"]="\\\\"}local function b(t)local c=0;for d,e in pairs(t)do if type(d)~="number"then return false elseif d>c then c=d end end;return c==#t end;local f={['\n']=true,['\r']=true,['\t']=true,[' ']=true,[',']=true,[':']=true}function removeWhite(g)while f[g:sub(1,1)]do g=g:sub(2)end;return g end;local h={}for d,e in pairs(a)do h[e]=d end;function parseBoolean(g)if g:sub(1,4)=="true"then return true,removeWhite(g:sub(5))else return false,removeWhite(g:sub(6))end end;function parseNull(g)return nil,removeWhite(g:sub(5))end;local i={['e']=true,['E']=true,['+']=true,['-']=true,['.']=true}function parseNumber(g)local j=1;while i[g:sub(j,j)]or tonumber(g:sub(j,j))do j=j+1 end;local k=tonumber(g:sub(1,j-1))g=removeWhite(g:sub(j))return k,g end;function parseString(g)g=g:sub(2)local l=""while g:sub(1,1)~="\""do local m=g:sub(1,1)g=g:sub(2)assert(m~="\n","Unclosed string")if m=="\\"then local n=g:sub(1,1)g=g:sub(2)m=assert(h[m..n],"Invalid escape character")end;l=l..m end;return l,removeWhite(g:sub(2))end;function parseArray(g)g=removeWhite(g:sub(2))local k={}local j=1;while g:sub(1,1)~="]"do local e=nil;e,g=parseValue(g)k[j]=e;j=j+1;g=removeWhite(g)end;g=removeWhite(g:sub(2))return k,g end;function parseObject(g)g=removeWhite(g:sub(2))local k={}while g:sub(1,1)~="}"do local d,e=nil,nil;d,e,g=parseMember(g)k[d]=e;g=removeWhite(g)end;g=removeWhite(g:sub(2))return k,g end;function parseMember(g)local d=nil;d,g=parseValue(g)local k=nil;k,g=parseValue(g)return d,k,g end;function parseValue(g)local o=g:sub(1,1)if o=="{"then return parseObject(g)elseif o=="["then return parseArray(g)elseif tonumber(o)~=nil or i[o]then return parseNumber(g)elseif g:sub(1,4)=="true"or g:sub(1,5)=="false"then return parseBoolean(g)elseif o=="\""then return parseString(g)elseif g:sub(1,4)=="null"then return parseNull(g)end;return nil end;return{decode=function(g)g=removeWhite(g)t=parseValue(g)return t end}]])()
- -- SHA256 (Compacted) By Anavrins
- local sha256 = loadstring([[local a=2^32;local b=bit32 and bit32.band or bit.band;local c=bit32 and bit32.bnot or bit.bnot;local d=bit32 and bit32.bxor or bit.bxor;local e=bit32 and bit32.lshift or bit.blshift;local f=unpack;local function g(h,i)local j=h/2^i;local k=j%1;return j-k+k*a end;local function l(m,n)local j=m/2^n;return j-j%1 end;local o={0x6a09e667,0xbb67ae85,0x3c6ef372,0xa54ff53a,0x510e527f,0x9b05688c,0x1f83d9ab,0x5be0cd19}local p={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}local function q(r)local s,t=0,0;if 0xFFFFFFFF-s<r then t=t+1;s=r-(0xFFFFFFFF-s)-1 else s=s+r end;return t,s end;local function u(v,w)return e(v[w]or 0,24)+e(v[w+1]or 0,16)+e(v[w+2]or 0,8)+(v[w+3]or 0)end;local function x(y)local z=#y;local A={}y[#y+1]=0x80;while#y%64~=56 do y[#y+1]=0 end;local B=math.ceil(#y/64)for w=1,B do A[w]={}for C=1,16 do A[w][C]=u(y,1+(w-1)*64+(C-1)*4)end end;A[B][15],A[B][16]=q(z*8)return A end;local function D(E,F)for C=17,64 do local G=E[C-15]local H=d(d(g(E[C-15],7),g(E[C-15],18)),l(E[C-15],3))local I=d(d(g(E[C-2],17),g(E[C-2],19)),l(E[C-2],10))E[C]=(E[C-16]+H+E[C-7]+I)%a end;local J,i,K,L,M,k,N,O=f(F)for C=1,64 do local P=d(d(g(M,6),g(M,11)),g(M,25))local Q=d(b(M,k),b(c(M),N))local R=(O+P+Q+p[C]+E[C])%a;local S=d(d(g(J,2),g(J,13)),g(J,22))local T=d(d(b(J,i),b(J,K)),b(i,K))local U=(S+T)%a;O,N,k,M,L,K,i,J=N,k,M,(L+R)%a,K,i,J,(R+U)%a end;F[1]=(F[1]+J)%a;F[2]=(F[2]+i)%a;F[3]=(F[3]+K)%a;F[4]=(F[4]+L)%a;F[5]=(F[5]+M)%a;F[6]=(F[6]+k)%a;F[7]=(F[7]+N)%a;F[8]=(F[8]+O)%a;return F end;return{digest=function(y)y=x({y:byte(1,-1)})local F={f(o)}for w=1,#y do F=D(y[w],F)end;return("%08x"):rep(8):format(unpack(F))end}]])()
- local function toBase(num, base)
- local char = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz.-:+=^!/*?&<>()[]{}@%$#"
- local ret = ""
- base = base or 36
- while num ~= 0 do
- local i = num % base
- ret = char:sub(i+1,i+1) .. ret
- num = math.floor(num/base)
- end
- return ret
- end
- local function getJSONPage(url, options, post)
- local res
- if type(post) == "table" then
- local postdata = ""
- for k, v in pairs(post) do
- postdata = postdata..k.."="..textutils.urlEncode(v).."&"
- end
- res = http.post(url..options, postdata:sub(1, -2))
- else
- res = http.get(url..options)
- end
- if not res then error("Error: Node Offline", 0) end
- local ret = json.decode(res.readAll())
- return ret
- end
- local function getWork()
- local res = getJSONPage(nodeurl, "/work")
- return res.ok and res.work or nil
- -- return 0x0007FFFFFFFF -- For testing purpose, you will only get invalid blocks though
- end
- local function getLastBlock()
- local res = getJSONPage(nodeurl, "/blocks/last")
- return res.ok and res.block.short_hash, res.block.address or nil
- end
- local function getBalance()
- local res = getJSONPage(nodeurl, "/addresses/"..address)
- if res.error then error(res.error, 0) end
- return res.ok and res.address.balance or nil
- end
- local function submitBlock(nonce)
- local postdata = {
- address = address,
- nonce = nonce,
- }
- local res = getJSONPage(nodeurl, "/submit", postdata)
- if res.ok then
- return res.success
- end
- end
- local function printHeader(str, ny)
- local w, h = term.getSize()
- local x, y = term.getCursorPos()
- term.setCursorPos(math.ceil(w/2) - math.floor(#str/2), ny or 1)
- term.clearLine()
- term.write(str)
- term.setCursorPos(x, y)
- end
- local function log(text, color)
- term.setTextColor(color or colors.white)
- print(text)
- term.setTextColor(colors.yellow)
- printHeader(("Work: %s | Block: %s"):format(work, block), 1)
- printHeader(("Balance: %s"):format(balance), 2)
- end
- term.clear()
- term.setCursorPos(1,1)
- print("Connecting to node...")
- balance = getBalance()
- block = getLastBlock()
- work = getWork()
- local timer = clock()
- local timer2 = clock()
- term.setCursorPos(1, 3)
- local function miner()
- while true do
- local nonceStr = toBase(nonce, 85)
- local hash = sha256.digest(address..block..nonceStr)
- local subhash = hash:sub(1, 12)
- if tonum(subhash, 16) < work then
- log(subhash.." found! nonce: "..nonceStr, colors.cyan)
- solved = solved + 1
- local ok = submitBlock(nonceStr)
- log(ok and "Accepted" or "Invalid", ok and colors.lime or colors.red)
- end
- if clock() > timer + 1 then
- log(("%s H/s Solved: %s"):format(nonce-rate, solved))
- timer = clock()
- rate = nonce
- os.queueEvent("")
- os.pullEvent("")
- end
- nonce = nonce+1
- end
- end
- local function updatework()
- while true do
- sleep(5)
- timer2 = clock()
- local newblock, lastaddr = getLastBlock()
- local newwork = getWork()
- balance = getBalance()
- if newwork ~= work then
- work = newwork
- log("Block mined by "..lastaddr, colors.orange)
- log("New work: "..work, colors.orange)
- end
- if newblock ~= block then
- block = newblock
- log("New block: "..block, colors.orange)
- end
- end
- end
- parallel.waitForAny(miner, updatework)
Advertisement
Add Comment
Please, Sign In to add comment