Python

如何在python中計算ethash?

  • March 29, 2021

我試圖用它ethash(hash(blockHeader),nonce) < TARGET來證明該區塊是以最低難度開采的。

上面的公式正確嗎?

當我嘗試使用來自 pyethereum 的 ehtereum.pow.ethash 時:

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)

我收到此錯誤:

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

**我做錯了嗎?**或者 ethereum.pow.ethash 中是否存在錯誤?

ethereum模組未維護。pyethash出於相同目的簽出。

您可以像這樣導入:

from pyethash import (
   EPOCH_LENGTH,
   hashimoto_light,
   mkcache_bytes,
)

py-evm使用它來檢查工作證明,如下所示:

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")

記憶體的生成和儲存位置

# 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

引用自:https://ethereum.stackexchange.com/questions/60986