본문으로 건너뛰기
Change page

이더해시

이더해시는 이더리움의 작업증명(PoW) 채굴 알고리즘이었습니다. 작업증명은 이제 완전히 종료되었으며, 이더리움은 대신 지분 증명(PoS)을 사용하여 보호됩니다. 머지, 지분 증명스테이킹에 대해 자세히 알아보세요. 이 페이지는 역사적 참고용입니다!

이더해시는 Dagger-Hashimoto 알고리즘의 수정된 버전입니다. 이더해시 작업증명은 메모리 하드(memory hard) (opens in a new tab) 특성을 가지며, 이는 알고리즘이 ASIC에 내성을 갖도록 만든다고 여겨졌습니다. 결국 이더해시 ASIC이 개발되었지만, 작업증명이 종료될 때까지 GPU 채굴은 여전히 실행 가능한 옵션이었습니다. 이더해시는 여전히 이더리움이 아닌 다른 작업증명 네트워크에서 다른 코인을 채굴하는 데 사용됩니다.

이더해시는 어떻게 작동하나요?

메모리 하드 특성은 논스와 블록 헤더에 종속된 고정 리소스의 하위 집합을 선택해야 하는 작업증명 알고리즘을 통해 달성됩니다. 이 리소스(수 기가바이트 크기)를 DAG라고 합니다. DAG는 30000 블록마다 변경되며, 이 약 125시간의 기간(대략 5.2일)을 에포크라고 부르고 생성하는 데 시간이 꽤 걸립니다. DAG는 블록 높이에만 의존하므로 미리 생성할 수 있지만, 그렇지 않은 경우 클라이언트는 블록을 생성하기 위해 이 프로세스가 끝날 때까지 기다려야 합니다. 클라이언트가 DAG를 미리 생성하고 캐시하지 않으면, 네트워크는 각 에포크 전환 시 대규모 블록 지연을 겪을 수 있습니다. 작업증명을 검증하는 데는 DAG를 생성할 필요가 없으므로, 본질적으로 낮은 CPU와 적은 메모리로도 검증이 가능하다는 점에 유의하세요.

알고리즘이 취하는 일반적인 경로는 다음과 같습니다.

  1. 해당 시점까지의 블록 헤더를 스캔하여 각 블록에 대해 계산할 수 있는 시드(seed)가 존재합니다.
  2. 시드로부터 16 MB의 의사 난수 캐시(pseudorandom cache)를 계산할 수 있습니다. 경량 클라이언트는 이 캐시를 저장합니다.
  3. 캐시로부터 1 GB 데이터 세트를 생성할 수 있으며, 데이터 세트의 각 항목은 캐시의 소수 항목에만 의존하는 특성을 가집니다. 풀 클라이언트와 채굴자는 이 데이터 세트를 저장합니다. 데이터 세트는 시간에 따라 선형적으로 증가합니다.
  4. 채굴은 데이터 세트의 무작위 조각을 가져와 함께 해싱하는 과정을 포함합니다. 검증은 캐시를 사용하여 필요한 데이터 세트의 특정 조각을 다시 생성함으로써 적은 메모리로 수행할 수 있으므로, 캐시만 저장하면 됩니다.

대규모 데이터 세트는 30000 블록마다 한 번씩 업데이트되므로, 채굴자 노력의 대부분은 데이터 세트를 변경하는 것이 아니라 읽는 데 집중됩니다.

정의

다음 정의를 사용합니다.

'SHA3'의 사용

이더리움의 개발은 SHA3 표준의 개발과 동시에 이루어졌으며, 표준화 과정에서 완결된 해시 알고리즘의 패딩에 뒤늦은 변경이 있었습니다. 따라서 이더리움의 "sha3_256" 및 "sha3_512" 해시는 표준 sha3 해시가 아니라, 다른 문맥에서 종종 "케착-256(Keccak-256)" 및 "Keccak-512"로 불리는 변형입니다. 관련 논의는 여기 (opens in a new tab), 여기 (opens in a new tab) 또는 여기 (opens in a new tab)를 참조하세요.

아래 알고리즘 설명에서 "sha3" 해시가 언급될 때 이 점을 유의하시기 바랍니다.

매개변수

이더해시의 캐시 및 데이터 세트 매개변수는 블록 번호에 따라 달라집니다. 캐시 크기와 데이터 세트 크기는 모두 선형적으로 증가하지만, 우발적인 규칙성으로 인해 순환 동작이 발생하는 위험을 줄이기 위해 항상 선형적으로 증가하는 임계값 아래의 가장 큰 소수를 취합니다.

데이터 세트 및 캐시 크기 값의 표는 부록에 제공됩니다.

캐시 생성

이제 캐시를 생성하는 함수를 지정합니다.

캐시 생성 프로세스는 먼저 32 MB의 메모리를 순차적으로 채운 다음, Strict Memory Hard Hashing Functions (2014) (opens in a new tab)에 나오는 Sergio Demian Lerner의 RandMemoHash 알고리즘을 두 번 통과시키는 과정을 포함합니다. 출력은 524288개의 64바이트 값 세트입니다.

데이터 집계 함수

우리는 XOR의 비결합적(non-associative) 대체재로서 일부 경우에 FNV 해시 (opens in a new tab)에서 영감을 받은 알고리즘을 사용합니다. 소수(prime)를 한 번에 1바이트(옥텟)씩 곱하는 FNV-1 사양과 달리, 전체 32비트 입력에 소수를 곱한다는 점에 유의하세요.

FNV_PRIME = 0x01000193

def fnv(v1, v2):
    return ((v1 * FNV_PRIME) ^ v2) % 2**32

황서(yellow paper)조차도 fnv를 v1*(FNV_PRIME ^ v2)로 명시하고 있지만, 현재의 모든 구현은 일관되게 위의 정의를 사용한다는 점에 유의하세요.

전체 데이터 세트 계산

전체 1 GB 데이터 세트의 각 64바이트 항목은 다음과 같이 계산됩니다.

본질적으로, 의사 난수로 선택된 256개의 캐시 노드에서 데이터를 결합하고 이를 해싱하여 데이터 세트 노드를 계산합니다. 그런 다음 전체 데이터 세트는 다음을 통해 생성됩니다.

def calc_dataset(full_size, cache):
    return [calc_dataset_item(cache, i) for i in range(full_size // HASH_BYTES)]

메인 루프

이제 특정 헤더와 논스에 대한 최종 값을 생성하기 위해 전체 데이터 세트에서 데이터를 집계하는 메인 "hashimoto" 유사 루프를 지정합니다. 아래 코드에서 header잘린(truncated) 블록 헤더, 즉 mixHashnonce 필드를 제외한 헤더의 RLP 표현에 대한 SHA3-256 해시를 나타냅니다. nonce는 빅 엔디언 순서의 64비트 부호 없는 정수의 8바이트입니다. 따라서 nonce[::-1]는 해당 값의 8바이트 리틀 엔디언 표현입니다.

본질적으로, 128바이트 너비의 "믹스(mix)"를 유지하고, 전체 데이터 세트에서 128바이트를 반복적으로 순차적으로 가져와 fnv 함수를 사용하여 믹스와 결합합니다. 알고리즘의 각 라운드가 항상 RAM에서 전체 페이지를 가져오도록 128바이트의 순차적 접근이 사용되며, 이는 이론적으로 ASIC이 피할 수 있는 변환 색인 버퍼(TLB) 미스를 최소화합니다.

이 알고리즘의 출력이 원하는 목표값보다 작으면 논스가 유효합니다. 마지막에 sha3_256를 추가로 적용하면 최소한 적은 양의 작업이 수행되었음을 증명하기 위해 제공할 수 있는 중간 논스가 존재하도록 보장합니다. 이 빠른 외부 작업증명(PoW) 검증은 DDoS 방지 목적으로 사용될 수 있습니다. 또한 결과가 편향되지 않은 256비트 숫자라는 통계적 보증을 제공하는 역할도 합니다.

채굴

채굴 알고리즘은 다음과 같이 정의됩니다.

def mine(full_size, dataset, header, difficulty):
    # 동일한 자릿수에서 해시와 비교하기 위해 타겟에 0을 채운다
    target = zpad(encode_int(2**256 // difficulty), 64)[::-1]
    from random import randint
    nonce = randint(0, 2**64)
    while hashimoto_full(full_size, dataset, header, nonce) > target:
        nonce = (nonce + 1) % 2**64
    return nonce

시드 해시 정의

주어진 블록 위에서 채굴하는 데 사용될 시드 해시를 계산하기 위해 다음 알고리즘을 사용합니다.

 def get_seedhash(block):
     s = '\x00' * 32
     for i in range(block.number // EPOCH_LENGTH):
         s = serialize_hash(sha3_256(s))
     return s

원활한 채굴 및 검증을 위해 별도의 스레드에서 미래의 시드 해시와 데이터 세트를 미리 계산하는 것을 권장합니다.

더 읽을거리

도움이 된 커뮤니티 리소스를 알고 계신가요? 이 페이지를 편집하여 추가해 주세요!

부록

위의 Python 사양을 코드로 실행하는 데 관심이 있다면 다음 코드를 앞에 추가해야 합니다.

데이터 크기

다음 조회 테이블은 약 2048개의 에포크에 대한 데이터 크기 및 캐시 크기를 표 형태로 제공합니다.