Wie berechnet man Ethash in Python?

Ich versuche zu ethash(hash(blockHeader),nonce) < TARGETbeweisen, dass der Block mit mindestens einer minimalen Schwierigkeit abgebaut wurde.

Ist obige Formel richtig?

Wenn ich versuche, ehtereum.pow.ethash von pyethereum zu verwenden:

from ethereum.pow import ethash
difficulty = 3963642329
block_number = 4156209
nonce = int('0xf245822d3412da7f', 16)
block_hash = 0x47b8f62c1400dae65105d2f8e03824bfc58481c0b32f45788ad3378fbc05e9f6
cache = ethash.mkcache(block_number)
ethash = hashimoto_light(block_number, cache, block_hash, nonce)
print(ethash)

Ich bekomme diesen Fehler:

Traceback (most recent call last):
  File "test.py", line 10, in <module>
    cache = ethash.mkcache(block_number)
  File "(environment_path)/lib/python3.6/site-packages/ethereum/pow/ethash.py", line 15, in mkcache
    while len(cache_seeds) <= block_number // EPOCH_LENGTH:
NameError: name 'EPOCH_LENGTH' is not defined

Mache ich es falsch? Oder gibt es einen Fehler in ethereum.pow.ethash?

Antworten (1)

Das ethereumModul wird nicht gepflegt. Auschecken pyethashfür den gleichen Zweck.

Sie können wie folgt importieren:

from pyethash import (
    EPOCH_LENGTH,
    hashimoto_light,
    mkcache_bytes,
)

py-evmverwendet es, um den Arbeitsnachweis wie folgt zu überprüfen:

def check_pow(block_number: int,
              mining_hash: Hash32,
              mix_hash: Hash32,
              nonce: bytes,
              difficulty: int) -> None:
    validate_length(mix_hash, 32, title="Mix Hash")
    validate_length(mining_hash, 32, title="Mining Hash")
    validate_length(nonce, 8, title="POW Nonce")
    cache = get_cache(block_number)
    mining_output = hashimoto_light(
        block_number, cache, mining_hash, big_endian_to_int(nonce))
    if mining_output[b'mix digest'] != mix_hash:
        raise ValidationError("mix hash mismatch; {0} != {1}".format(
            encode_hex(mining_output[b'mix digest']), encode_hex(mix_hash)))
    result = big_endian_to_int(mining_output[b'result'])
    validate_lte(result, 2**256 // difficulty, title="POW Difficulty")

Wo der Cache generiert und gespeichert wird mit:

# Type annotation here is to ensure we don't accidentally use strings instead of bytes.
cache_seeds = [b'\x00' * 32]  # type: List[bytes]
cache_by_seed = OrderedDict()  # type: OrderedDict[bytes, bytearray]
CACHE_MAX_ITEMS = 10


def get_cache(block_number: int) -> bytes:
    while len(cache_seeds) <= block_number // EPOCH_LENGTH:
        cache_seeds.append(keccak(cache_seeds[-1]))
    seed = cache_seeds[block_number // EPOCH_LENGTH]
    if seed in cache_by_seed:
        c = cache_by_seed.pop(seed)  # pop and append at end
        cache_by_seed[seed] = c
        return c
    c = mkcache_bytes(block_number)
    cache_by_seed[seed] = c
    if len(cache_by_seed) > CACHE_MAX_ITEMS:
        cache_by_seed.popitem(last=False)  # remove last recently accessed
    return c
Danke schön. Ich habe das versucht, aber es sagt, dass mix_hash != result. Was mache ich falsch? block_number = 4156209 difficulty = 3963642329 nonce = unhexlify('0xf245822d3412da7f'[2:]) block_hash = unhexlify( '0x47b8f62c1400dae65105d2f8e03824bfc58481c0b32f45788ad3378fbc05e9f6'[2:]) mix_hash = unhexlify( '0x0c0026c706351083c0a913e084dee16ca133b813baa6a174e4fb179d9f2ecc52'[2:])
Und es sagt mir, dass meine Schwierigkeit irgendwie nicht zusammenpasst. Hat das damit zu tun, dass ich einen Block von Ropsten verwende?
Roppsten wird auch funktionieren. Trinity (basierend auf py-evm) validiert pow mit diesem Code auf Ropsten.