Last active
May 10, 2016 05:25
-
-
Save qguv/28dbf84e7138aee07b57b0a8986d2b4e to your computer and use it in GitHub Desktop.
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
#!/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