이더리움 “이스탄불” 하드포크

feat. EIP

신건우(Thomas Shin)
Tokamak Network
20 min readNov 27, 2019

--

현재 시간 2019년 11월 27일 수요일 13시 44분 [https://etherscan.io/block/countdown/9069000]

이더리움 블록체인의 이스탄불 하드포크가 한국 시간으로 12월 7일 토요일 새벽 5시 36분쯤 진행될 것으로 보입니다(블록 #9069000). 이스탄불 하드포크에 포함된 EIP(Ethereum Improvement Proposal; 이더리움 개선 제안)들은 다음과 같습니다.

이번 포스팅은 이스탄불 하드포크에 포함된 각각의 EIP에 대한 내용을 상세히 다루고 있습니다. 이 글이 한국의 이더리움 커뮤니티에게 12월 7일 이후 업그레이드되는 이더리움에 관한 이해와 응용의 폭을 넓혀주는 계기가 되기를 희망합니다.

Reference

EIP-152

EIP-152은 BLAKE2b 해시 함수를 구현한 새로운 precompiled contract의 도입을 제안합니다. EIP-152가 이스탄불 하드포크에 포함된 동기는 두가지로 볼 수 있습니다.

  1. 많은 프로젝트에서 SHA-3 해시 함수보다 BLAKE2 해시 함수를 더 많이 사용하고 있습니다. 그렇기 때문에 이더리움 역시 BLAKE2를 precompiled contract로 지원하여 이더리움 스마트 컨트랙트가 BLAKE2로 해싱된 데이터와의 상호운용성을 가지도록 지원해야 합니다.
  2. Ethereum이 EIP-152를 지원하면 Zcash와 Ethereum 사이의 상호운용성이 더욱 향상됩니다. Zcash의 PoW 알고리즘인 Equihash PoW는 BLAKE2b 해시 함수를 사용하기 때문에 이더리움 스마트 컨트랙트가 Equihash PoW 검증을 할 수 있게 됩니다.

BLAKE2b

BLAKE2는 MD5, SHA-1, SHA-2 그리고 SHA-3 해시 함수보다 빠르면서도, 표준 SHA-3 해시 함수 만큼의 보안성을 갖춘 암호학(cryptographic) 해시 함수입니다. BLAKE2는 빠른 속도와 보안성, 그리고 심플한 디자인을 갖추고 있어 많은 프로젝트에서 사용 되고 있습니다. BLAKE2b는 BLAKE2를 64 비트 플랫폼에 맞게 최적화를 한 것입니다.

Hash functions speed 비교 [https://blake2.net/]

ZRelay

ZRelayBTCRelay로부터 영감을 받아 만들어진 Zcash 버전의 Relay입니다. 예를 들어 A 체인과 또 다른 B 체인이 존재할 때, A 체인에서 만들어진 a 컨트랙트가 B 체인의 라이트 노드의 기능을 수행할 때 이 a 컨트랙트를 Relay라고 부릅니다. 즉 BTCRelay는 비트코인의 라이트 노드의 기능을 수행하는 이더리움 스마트 컨트랙트입니다. 이와 마찬가지로 ZRelay란 결국 Zcash의 라이트 노드 기능을 수행하는 이더리움 스마트 컨트랙트가 됩니다. ZRelay가 가능하게 되면 Zcash와 이더리움 사이에서 아토믹 스왑(atomic swap)도 가능하게 됩니다.

Zcash에서는 BLAKE2b 해시 함수를 사용하기 때문에 ZRelay를 구현하기 위해서는 BLAKE2b 해시 함수를 사용해야 합니다. EIP-152이 도입되기 이전에는 BLAKE2b 함수를 컨트랙트로 구현해서 사용했지만, EIP-152의 도입으로 ZRelay를 더 적은 비용으로 빠르게 사용할 수 있게 되었습니다.

Reference

EIP-1108

EIP-1108은 ECADD, ECMUL,Pairing check이 3개의 precompiled contract 연산의 가스 비용을 낮추는 것에 대한 제안입니다( ECADD, ECMUL 그리고 Pairing check precompiled contract 자체는 EIP-196EIP-197에서 각각 제안되었습니다).

최근 go-ethereum에서 ECADD, ECMUL 그리고 Pairing check을 구현하기 위해 사용된 bn 라이브러리가 cloudflare의 bn256 라이브러리를 사용하는 것으로 변경되었습니다. 그리고 Parity 클라이언트에서도 bn 라이브러리의 최적화가 이루어졌죠. 덕분에 ECADD, ECMUL 그리고 Pairing check를 하는 컴퓨터 연산 부담이 크게 감소했습니다. 그렇기 때문에 ECADD, ECMUL 그리고 Pairing check의 precompiled contract에 대한 가스 비용 역시 줄어드는게 자연스럽습니다. 아래의 표는 EIP-1108에서 포함되어있는 각각의 연산에 대한 변경된 가스 소모량을 비교하고 있습니다.

the current gas cost and new gas cost [https://github.com/ethereum/EIPs/blob/master/EIPS/eip-1108.md]

EIP-196 & EIP-197

EIP-196EIP-197는 이전에 진행되었던 Byzantin hard fork에 포함되어 있습니다.

  • EIP-196: Elliptic curve에서의 덧셈스칼라 곱에 대한 precompiled contract를 추가하는 것.
  • EIP-197: Elliptic curve에서의 Pairing check에 대한 precompiled contract를 추가하는 것.

EIP-196과 EIP-197의 도입으로 타원곡선 기반의 암호학적 연산을 precompiled contract로 지원하게 되었습니다. 이를 통해 이더리움 상에서 zkSNARKs 검증을 블록 가스 리밋(800만) 한도 내에서 더 효율적으로 수행 할 수 있게 되었습니다. zkSNARKs 검증이 이더리움 상에서 가능해지면 유저의 프라이버시 문제와 확장성 솔루션에 큰 도움을 줄 수 있습니다.

Reference

EIP-1344

EIP-1344는 체인의 chainId를 리턴하는 opcode 추가에 대한 제안입니다. chainId는 EIP-155에서 replay attack을 막기 위해 만들어졌습니다.

현재 이더리움의 chainId는 1입니다. 하지만 이더리움 블록체인은 어떠한 문제로 인해 (이더리움 클래식과 이더리움이 나뉜 것처럼)체인이 분기될 수 있습니다. 분리된 체인은 기존의 체인과 다른 chainId를 가지게 됩니다.

EIP-1344가 도입되면 트랜잭션이 실행되면서 chainId를 동적으로 조회할 수 있게 됩니다. 예를 들어 chainId를 호출하는 함수를 구현한 스마트 컨트랙트가 이더리움에 배포되어 있다면 해당 함수는 1을 리턴하고, 이더리움 클래식에 배포되어 있다면 61을 리턴합니다(이더리움의 chainId는 1이고, 이더리움 클래식의 chainId는 61입니다.). 결국 스마트 컨트랙트가 올바른 체인을 따를 수 있도록 할 수 있습니다.

EIP-1344는 플라즈마와 같은 Layer 2 솔루션에서 매우 요긴하게 활용될 수 있습니다. 플라즈마는 플라즈마 체인에 존재하는 일련의 블록들의 요약본을 이더리움에 배포된 컨트랙트에 제출하는 방식을 사용합니다. 여기서 이더리움은 플라즈마 체인의 부모 체인이 됩니다. 만약 어떠한 이유로 부모 체인의 chainId가 바뀌게 된다면 플라즈마 체인 역시 부모 체인에 대한 정보(chainId)를 업데이트 해야 합니다. 왜냐하면 플라즈마 체인에 있는 블록들의 요약본을 부모 체인에 제출함과 동시에 이 두 체인의 동기화가 이루어지기 때문이죠. 만약 플라즈마 체인에서 고정된 chainId를 사용하고 있고, 부모 체인의 chainId가 변경되면 이 두 체인의 동기화가 끊어지게 됩니다.

Reference

EIP-1884

EVM에서 사용되는 opcode 또는 precompiled contract는 노드에서 이루어지는 컴퓨터 연산을 고려해 가스 비용(gas cost)이 부여됩니다. 그렇기 때문에 특정 오퍼레이션을 실행하기 위해 사용되는 컴퓨터 비용과 가스 비용의 밸런스가 맞춰지게 되는 것이죠. 만약 이 밸런스가 무너지게 되면, 예를 들어 특정 오퍼레이션에 대한 컴퓨터 비용은 크지만 가스 비용이 작을 때, 이 오퍼레이션을 이용해서 이더리움 네트워크에 악의적인 공격(DoS, Denial-of-service 공격)이 가능해집니다. EIP-1884는 특정 opcode에서 이와 같은 밸런스를 재조정하기 위해 제안한 것으로 볼 수 있습니다.

이더리움의 생태계가 커지는 과정에서, 이더리움 데이터에서 큰 부분을 차지하는 state 또한 지속적으로 늘어났습니다. 이에 따라 state를 조회하기 위해 state trie 노드들을 순회하는 부담도 같이 커졌죠. EIP-1884는 이에 맞게 SLOADBALANCE 그리고 EXCODEHASH opcode의 가스 비용을 높이고, SELFBALANCE opcode를 추가하는 것을 포함합니다.

  • SLOAD(0x54): 200에서 800 가스만큼 높임.
  • BALANCE(0x31): 400에서 700 가스만큼 높임.
  • EXCODEHASH (0x3F): 400에서 700 가스만큼 높임.
  • SELFBALANCE(0x47): 새로 추가된 opcode로 5 가스를 사용.
the execution time for SLOAD opcode [https://eips.ethereum.org/EIPS/eip-1884]

위의 자료는 SLOAD opcode의 실행 시간(execution time)을 그래프로 나타낸 것입니다. EIP-150 이후 SLOAD의 실행 시간이 급격히 떨어진 것을 확인할 수 있습니다. EIP-150은 SLOAD의 가스 비용을 50에서 200으로 재조정한 것입니다. 현재는 SLOAD의 실행 시간이 EIP-150 이전 수준의 2배를 넘기기도 하는데,그렇기 때문에 SLOAD의 가스 비용을 높일 수 밖에 없게 된 것이죠.

the execution time for BALANCE opcode [https://eips.ethereum.org/EIPS/eip-1884]

BALANCE opcode 역시 state trie로부터 어카운트 잔액을 조회합니다. BALANCE opcode도 EIP-150를 통해 20에서 400 가스로 재조정되었습니다. 현재 BALANCE opcode 또한 임의의 어카운트 잔액을 조회하기 위해 많은 실행 시간이 소요되는 것을 위의 그래프에서 확인할 수 있습니다. 이를 반영해 BALANCE opcode의 비용을 400에서 700으로 높였습니다.

하지만 “현재” 어카운트의 잔액을 조회하는 것은 많은 컴퓨터 자원을 사용하지 않습니다(컨트랙트가 실행될 때 해당 컨트랙트 어카운트의 데이터를 미리 가져오기 때문에). 이를 위해 현재 어카운트의 잔액을 조회하는 SELFBALANCE opcode를 새로 추가했고 SELFBALANCE는 5 가스만을 소모합니다. 현재 어카운트 이외의 잔액을 조회할 때는 모두 SELFBALANCE가 아닌 BALANCE opcode가 사용됩니다.

EXTCODEHASH opcode 또한 BALANCE opcode 가스 비용과 같은 수준으로 재조정됩니다. 왜냐하면EXTCODEHASH는 컨트랙트 어카운트의 코드 해시를 조회하는 것으로 어카운트의 잔액을 조회하는 BALANCE opcode를 실행하는 것과 같은 수준의 컴퓨터 비용이 들기 때문입니다.

Reference

EIP-2028

EIP-2028은 Calldata의 가스 비용을 줄이는 내용을 포함하고 있습니다. 현재 이더리움의 Calldata는 1 byte마다 가스를 소모하는데, 해당 1 byte가 0으로 채워져 있으면 4 가스(TxDataZeroGas), 0이 아닌 값으로 채워져 있으면 68 가스(TxDataNonZeroGas)를 소모합니다. EIP-2028은 TxDataNonZeroGas를 68 가스에서 16 가스만큼 소모하도록 변경하는 것을 제안하고 있습니다.

EIP-2028로 인해 Calldata에 데이터를 더 많이 포함할 수 있게 되었습니다. 이는 Calldata를 사용하는 많은 솔루션에게 큰 이점을 가져다 줄 수 있습니다.

예를 들어, Calldata는 다음과 같이 사용될 수 있습니다.

  • STARKs나 SNARKs와 같은 Proof 시스템에서 큰 연산에 대한 무결성을 입증할 수 있는 proof를 제출하는 용도.
  • fraud proofs를 사용하는 솔루션들 또한 Merkle Proof를 제출하는 용도.
  • Layer 2 솔루션에서 데이터 가용성(data availability) 문제를 Calldata에 데이터를 둠으로써 해결.

EIP-2028이 반영되면 더 많은 데이터들이 적은 부담으로 Calldata를 통해 이더리움 네트워크에 전송될 수 있습니다. 하지만 이로 인해 데이터를 전송하는데 있어서 이더리움의 네트워크 지연(network delay)이 발생할 수 있습니다. 하지만 이와 같은 네트워크 지연은 데이터를 전송하는 것에 한정되어 있고, 실제로 이더리움 네트워크의 지연을 일으키는 것은 블록 처리 시간, state가 커짐에 따라 더 많은 컴퓨터 비용이 소요되는 스토리지 접근 시간입니다.

Reference

EIP-2200

EIP-2200은 EIP-1283과 EIP-1706을 결합한 새로운 스펙으로 SSTORE에 대한 가스 비용 계산의 변경을 제안합니다. 그리고 EIP-1884에서 SLOAD의 가스 비용의 변경이 이루어졌기 때문에 EIP-2200에서도 이를 반영했습니다.

EIP-1283은 원래 콘스탄티노플 하드포크에 포함된 EIP였지만, 재진입 공격 가능성 때문에 제외되었습니다. EIP-2200에서는 EIP-1283에서 제안한 용어인 original valuecurrent value 그리고 new value라는 용어를 그대로 사용하고 있습니다. EIP-1283에 대한 자세한 글은 이전 포스팅에서 확인할 수 있습니다.

이에 더해 새로운 변수를 제안합니다.

  • SLOAD_GAS: 800 (EIP-1884에 의해 SLOAD에 대한 가스 비용이 200에서 800으로 재조정되었습니다.)
  • SSTORE_SET_GAS: 20000
  • SSTORE_RESET_GAS: 5000
  • SSTORE_CLEARS_SCHEDULE: 15000

이제 SSTORE는 다음의 스펙에 맞게 가스가 소모됩니다.

(1) current value == new value
→ 800(SLOAD_GAS) 가스 소모 (eg. 0 / 100/ 100)

(2) current value != new value && original value == current value
→ 20000(SSTORE_SET_GAS) 가스 소모 (eg. 0 / 0 / 200)
→ 5000(SSTORE_RESET_GAS) 가스 소모 (eg. 100 / 100 / 200)
→ 15000(SSTORE_CLEARS_SCHEDULE) 가스 환불 (eg. 100 / 100 / 0)

(3) current value != new value && original value != current value
→ 800(SLOAD_GAS) 가스 소모 (eg. 0 / 100 / 200 or 100 / 200 / 300)
→ 15000(SSTORE_CLEARS_SCHEDULE) 가스 환불 취소 (eg. 100 / 0 / 200)
→ 15000(SSTORE_CLEARS_SCHEDULE) 가스 환불 (eg. 100 / 200 / 0)

(4) current value != new value && original value == new value
→ 19200(SSTORE_SET_GAS-SLOAD_GAS) 가스 환불 (eg. 0 / 100 / 0)
→ 4200(SSTORE_RESET_GAS-SLOAD_GAS) 가스 환불 (eg. 100 / 200 / 100)

그리고 EVM이 실행되면서 SSTORE opcode를 만났을 때 남은 가스가 2300보다 같거나 작다면 out of gas 에러를 발생시킵니다(EIP-1706).

EIP-1283에서는 fallback 함수를 통해 재진입 공격이 가능했지만, EIP-2200에서는 EIP-1706 스펙 때문에 불가능해졌습니다. 컨트랙트가 ETH를 받게 되면 fallback 함수가 실행되는데, fallback 함수가 실행되는 동안 해당 컨트랙트는 단지 2300 가스인 gas stipend만을 사용합니다. 그렇기 때문에 fallback 함수에서의 SSTORE opcode 사용은 항상 out of gas 에러를 발생시킵니다.

Reference

--

--