Skip to content

Instantly share code, notes, and snippets.

@qguv
Last active May 10, 2016 05:25
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save qguv/28dbf84e7138aee07b57b0a8986d2b4e to your computer and use it in GitHub Desktop.
Save qguv/28dbf84e7138aee07b57b0a8986d2b4e to your computer and use it in GitHub Desktop.
#!/usr/bin/env python3
'''Created to answer the question: How does bitcoin mining work? Key
differences between this method and bitcoin's:
- This method doesn't actually store transactions. :-)
- This primes the hash function with the previous nonce solution, so solving
for the nth iteration necessarily requires a solution for the (n-1)
iteration and all iterations before it. Bitcoin primes the hash function
with the entire previous block, (which includes its nonce). This method is
arguably more vulnerable to attacks on SHA-256.
- Difficulty is in bytes, not bits. It really ought to be in bits but I'm
lazy and I doubt anyone will ever see this.'''
from itertools import count # iterate infinitely
from hashlib import sha256 # the relevant hash function
from sys import exit # to exit cleanly with ^C
class Ramp(bytearray):
def increment(self):
# LSByte at index zero for efficiency
for i in range(len(self)):
if self[i] == 0xff:
self[i] = 0
else:
self[i] += 1
return
# if all bytes are zero, add another
self.append(0)
print(len(self), "B answers being considered", sep='', end='\r') #DEBUG
# hacky little-endian nonsense
def __str__(self):
return ':'.join([ "{:02x}".format(x) for x in reversed(self) ])
def hash_begins_with_n_zeros(solution: bytes, difficulty: int, primed_hash: sha256):
h = primed_hash.copy()
h.update(solution)
maybe_zeros = h.digest()[:difficulty]
return all([ x == 0 for x in maybe_zeros ])
def mine():
primed_hash = sha256()
for difficulty in count(1):
solution = Ramp()
while not hash_begins_with_n_zeros(solution, difficulty, primed_hash):
solution.increment()
yield solution
primed_hash = sha256(solution)
try:
m = mine()
last = Ramp()
d = 1
for s in m:
print("Difficulty", d, "solution found!")
print("When combined with the last result,", s, "SHA256-hashes to", sha256(last + s).hexdigest(), '', sep='\n')
last = s
d += 1
except KeyboardInterrupt:
print()
exit(0)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment