EIP-658 영수증에 거래 상태 코드 기록 (Embedding transaction status code in receipts)
최종 확정 · EVM·실행 · 원문 상태 Final · 2017-06-30 작성
거래 영수증의 중간 상태 루트 필드를 상태 코드로 교체해 거래가 성공했으면 1, 실패했으면 0을 기록합니다. 누구나 재실행 없이 거래 성공 여부를 확인할 수 있게 됩니다.
왜 필요한가
예전에는 거래가 실패했는지 알려면 가스를 전부 썼는지를 봤습니다. 실패한 거래는 가스를 모두 소모했기 때문입니다. 그런데 EIP-140이 되돌리기(REVERT) 명령어를 도입하면서 거래가 남은 가스를 돌려받으며 실패할 수 있게 됐고, 이 추정 방법이 더 이상 통하지 않게 됐습니다. 호출자가 거래의 성공 여부와 상태 변경이 실제로 적용됐는지를 확인할 분명한 방법이 사라진 것입니다. 모든 데이터를 가진 풀 노드는 거래를 다시 실행해 결과를 알려 주는 RPC를 제공할 수 있지만 빠른 동기화 노드는 피벗 지점 이후의 거래만 재실행할 수 있고 가벼운 노드(라이트 노드)는 아예 재실행할 수 없습니다. 그래서 합의 규칙 밖에서 해결하는 방식은 현실적이지 않았고 영수증 자체에 성공 여부를 기록하는 합의 수준의 변경이 필요했습니다.
무엇이 바뀌나
지금
- 거래 실패 여부를 가스를 전부 썼는지로 추정했습니다
- REVERT 도입 뒤에는 이 추정이 맞지 않게 됐습니다
- 라이트 노드는 거래 성공 여부를 확인할 방법이 없었습니다
- 영수증에는 이미 쓸모가 없어진 중간 상태 루트가 들어 있었습니다
EIP-658 이후
- 영수증의 상태 코드만 보면 성공(1)인지 실패(0)인지 바로 압니다
- 거래를 다시 실행하지 않아도 결과를 알 수 있습니다
- 라이트 노드를 포함한 모든 노드가 같은 방식으로 확인합니다
- 중간 상태 루트 자리가 실제로 쓸모 있는 정보로 바뀝니다
누구에게 영향이 있나
- 사용자: 지갑이나 탐색기에서 거래가 성공했는지 실패했는지 정확하게 볼 수 있습니다.
- 지갑·앱 개발자: 거래 재실행이나 가스 소모량 추정 없이 영수증의 상태 코드로 성공 여부를 판별합니다.
- 클라이언트 팀: 영수증 구조에서 중간 상태 루트를 상태 코드로 바꾸는 합의 변경을 구현해야 합니다.
- 라이트 노드 운영자: 거래를 재실행할 수 없는 환경에서도 거래 결과를 확인할 수 있게 됩니다.
심층 설명
중간 상태 루트를 상태 코드로 교체
영수증에는 원래 각 거래 처리 직후의 중간 상태 루트(intermediate state root)가 들어 있었습니다. 이 필드는 EIP-98로 이미 쓸모가 없어진 상태였습니다. 이 EIP는 그 자리를 최상위 호출(top-level call)의 성공 여부를 나타내는 반환 상태로 바꿉니다. 성공이면 1, 실패면 0입니다. 호출자가 거래 성공 여부를 판별할 수 있게 되고 영수증에 실행 결과 정보가 빠져 있던 기존의 공백도 함께 메웁니다.
합의 밖 해법이 불가능한 이유
EIP-140의 REVERT 명령어가 도입되면서 '가스를 전부 소모했으면 실패'라는 등가 관계가 깨졌습니다. 거래가 성공했는지, 그 안의 상태 변경이 적용됐는지를 호출자가 판별할 명확한 수단이 없어진 것입니다. 풀 노드는 거래를 재실행해 반환 상태와 값을 알려 주는 RPC를 제공할 수 있지만 빠른 동기화(fast sync) 노드는 피벗 지점(pivot point) 이후의 거래에 대해서만 가능하고 라이트 노드는 아예 할 수 없습니다. 그래서 합의 규칙에 포함되지 않는 해법은 비실용적이고 영수증이라는 합의 데이터 구조 자체를 바꿔야 했습니다.
명세: 적용 시점과 코드 값
block.number >= BYZANTIUM_FORK_BLKNUM인 블록부터 영수증의 중간 상태 루트가 상태 코드로 교체됩니다. 0은 실패를 뜻하며 거래나 최상위 호출을 되돌릴(revert) 수 있는 모든 연산이 원인에 포함됩니다. 1은 성공을 뜻합니다. 명세는 이 두 값과 적용 시점만 정의하는 짧은 변경입니다.
설계 근거: 최소한의 변경
저자는 이 방식이 거래의 성공·실패 상태를 조회할 수 있게 하는 가능한 최소의 변경이라고 설명합니다. 기존 기능을 그대로 보존하면서 메트로폴리스(Metropolis) 업그레이드에 필요한 추가 작업과 혼란을 최소화하는 설계입니다. 이미 EIP-98로 폐기된 필드를 재활용하므로 영수증 구조의 크기나 형태가 달라지지 않습니다.
상태: Final, 비잔티움부터 적용
이 EIP는 2017년 6월 30일에 제안됐고 현재 상태는 Final입니다. 명세에 적힌 대로 비잔티움(Byzantium) 포크 블록(BYZANTIUM_FORK_BLKNUM) 이후의 모든 블록에 적용됩니다. EIP-140(REVERT 명령어)을 선행 조건(requires)으로 둡니다.