EIP-214 정적 호출 명령어 STATICCALL (New opcode STATICCALL)
최종 확정 · EVM·실행 · 원문 상태 Final · 2017-02-13 작성
다른 컨트랙트를 호출하되 그 호출 안에서는 어떤 상태 변경도 못 하게 막는 새 명령어 STATICCALL(0xfa)을 추가합니다. 상태를 바꾸려는 시도는 예외로 처리됩니다.
왜 필요한가
지금은 어떤 컨트랙트를 호출하면, 가스만 충분하다면 호출된 쪽이 무엇을 하든 막을 방법이 없습니다. 그래서 일반 호출을 한 번 하고 나면, 호출한 컨트랙트가 어떤 코드인지 정확히 알지 못하는 한 호출 뒤의 상태에 대해 아무것도 가정할 수 없습니다. 거래가 채굴자에게 확정되기 전에는 거래 순서도 알 수 없으므로, 외부 관찰자조차 모든 경우에 상태를 확신할 수 없습니다. 이 제안은 가장 단순한 방식으로 호출 상대의 행동을 제한하는 길을 엽니다. 정적 호출(static call) 전과 후에 모든 계정의 상태가 같다고 안전하게 가정할 수 있게 됩니다.
무엇이 바뀌나
지금
- 호출된 컨트랙트가 가스 한도 안에서 무엇이든 할 수 있습니다
- 일반 호출 뒤에는 상태가 어떻게 바뀌었는지 가정할 수 없습니다
- 읽기만 하려는 호출에도 재진입 같은 부작용 위험을 따져야 합니다
EIP-214 이후
- STATICCALL로 호출하면 그 안(과 하위 호출)에서 상태 변경이 전부 금지됩니다
- 상태를 바꾸려는 명령은 실행되는 대신 예외를 일으킵니다
- 정적 호출 전후로 모든 계정 상태가 같다고 안전하게 가정할 수 있습니다
누구에게 영향이 있나
- 스마트 컨트랙트 개발자: 읽기 전용임이 보장되는 호출을 쓸 수 있어 해당 호출에서 재진입 버그가 생길 수 없다고 확신할 수 있습니다.
- 코드 감사자·리뷰어: STATICCALL로 이뤄진 호출은 출력만 돌려주고 아무것도 바꾸지 않는 순수 함수로 간주하고 검토 범위를 줄일 수 있습니다.
- 클라이언트 팀: 가상 머신에 STATIC 플래그와 새 옵코드 0xfa, 금지 연산의 예외 처리를 구현해야 합니다.
- 고수준 언어 설계자: 원문은 순수 함수형 고수준 언어(HLL)를 구현하기 쉬워질 수 있다고 밝힙니다.
심층 설명
STATIC 플래그 도입
가상 머신에 새 STATIC 플래그를 도입합니다. 초기값은 false이고 그 값은 항상 하위 호출(sub-call)에 복사됩니다. 유일한 예외가 새 옵코드 STATICCALL로, 자식 실행에 대해 플래그를 true로 설정합니다. 호출이 반환되면 플래그는 호출 전의 값으로 재설정됩니다. 이 플래그 전파 규칙 때문에 정적 호출 안에서 일어나는 모든 깊이의 하위 호출까지 상태 변경 금지가 유지됩니다.
옵코드 형식: 0xfa, 인자 6개
STATICCALL의 옵코드는 0xfa입니다. 동작은 CALL과 동등하지만 인자를 6개만 받습니다. CALL의 "value" 인자가 빠지고 그 값은 0으로 간주됩니다. 즉 정적 호출로는 이더를 보낼 수 없습니다. 자신을 호출하는 것도 가능합니다.
금지되는 상태 변경 연산 목록
STATIC이 true인 실행 인스턴스 안에서 상태 변경 연산을 시도하면 수행 대신 예외가 발생합니다. 해당 연산은 CREATE, CREATE2, LOG0, LOG1, LOG2, LOG3, LOG4, SSTORE, SELFDESTRUCT이며 value가 0이 아닌 CALL도 포함됩니다. 예외적으로 CALLCODE는 value가 0이 아니어도 상태 변경으로 간주하지 않습니다.
설계 의도: 순수 함수 보장
이 제안으로 컨트랙트는 상태를 전혀 바꾸지 않음이 명확한 호출을 할 수 있습니다. 그 호출은 출력을 돌려줄 뿐 다른 아무 일도 하지 않는 순수 함수이므로, 개발자와 리뷰어는 그 특정 호출에서 재진입(re-entrancy) 버그나 다른 문제가 생길 수 없다고 안심할 수 있습니다. 원문은 이것이 순수 함수형 고수준 언어의 구현도 쉽게 만들 수 있다고 덧붙입니다.
하위 호환성과 현재 상태
새 옵코드를 추가할 뿐 다른 옵코드의 동작은 바꾸지 않습니다. 따라서 새 옵코드를 쓰지 않고 새 옵코드로 호출되지도 않는 기존 컨트랙트에는 하위 호환됩니다. 이 EIP는 2017년 2월 13일 비탈릭 부테린과 크리스티안 라이트비스너가 제안했고 상태는 Final로, 이미 확정된 명세입니다.