RFC: this.balance
를 사용한 저장소 없는 비활성화 메커니즘 - 캔쿤 이후
캔쿤 업그레이드와 EIP-6780에 의해 도입된 변경사항 이후, 계약을 동적으로 비활성화하고 재활성화하는 기능이 더욱 어려워졌습니다. 특히 모든 거래에 대해 저장소를 쿼리하는 것이 바람직하지 않은 시나리오에서 그렇습니다. 저는 내장된 this.balance
변수를 제어 플래그로 사용하여 계약(특히 라우터 계약)을 활성화 및 비활성화하는 최소한의 메커니즘을 제안합니다.
사용 사례
문제의 라우터 계약:
- 사용자 승인을 보유하지만 토큰이나 중요한 비즈니스 로직은 없습니다.
- 정상 작동 시 이더리움(ETH)을 보유하지 않습니다.
- 활성 및 비활성 상태 간을 전환할 수 있는 신뢰할 수 있고 저장소 없는 방법이 필요합니다.
다음과 같은 경우에 특히 유용합니다:
- 계약에 버그가 발견되어 수정될 때까지 사용자가 상호작용하지 못하도록 해야 할 경우.
- 사용자 승인을 수동으로 취소할 필요 없이 신속하게 라우터를 비활성화해야 할 경우.
제안된 메커니즘
이 메커니즘은 계약의 이더리움(ETH) 잔액(this.balance
)만을 사용하여 상태를 전환합니다. 로직은 다음과 같습니다:
- 상태 정의:
- 비활성화:
this.balance == 0
. 계약이 모든 상호작용을 거부합니다. - 활성화:
this.balance == 1 wei
. 계약이 정상적으로 작동합니다.
- 상태 전환:
- 계약 활성화: 변경 불가능한 DEACTIVATOR 주소로 제한된
activate()
함수가 1 wei를 계약에 전송하여 활성 상태로 설정합니다. - 계약 비활성화: 마찬가지로 제한된
deactivate()
함수가 계약의 모든 이더리움(ETH)을 DEACTIVATOR로 전송하여 잔액을 0으로 설정합니다.
- 핵심 기능:
- 라우터에
receive
함수가 없어 이더리움(ETH)이 우발적으로 또는 악의적으로 전송될 수 없습니다. - 모든 상태 전환은 이더리움(ETH) 잔액에만 의존하므로 사용자 정의 상태 변수를 쿼리하거나 저장할 필요가 없습니다.
장점
- 저장소 읽기 없음:
this.balance
를 사용하여 상태를 확인하므로 저장소 읽기 가스 비용이 발생하지 않습니다. - 효율적인 상태 전환: 활성화 또는 비활성화에는 최소한의 이더리움(ETH) 전송만 필요합니다.
- 안전성:
receive
함수가 없어 라우터가 우발적으로 이더리움(ETH)을 누적할 수 없습니다.
왜 이것이 유용한가
이 메커니즘은 다음과 같은 시나리오에서 라우터 비활성화를 처리하는 경량 방법을 제공합니다:
- 라우터 계약의 버그로 인해 사용자가 수동으로 승인을 취소해야 하는 경우.
- 가스 비용 또는 복잡성 때문에 모든 거래에 대한 상태 쿼리가 바람직하지 않은 경우.
계약의 이더리움(ETH) 잔액을 토글로 사용하면 저장소 변수가 필요 없으면서도 신속하고 효율적인 상태 변경이 가능합니다. 이 접근 방식은 저장소 없는 컨텍스트에서 유사한 활성화/비활성화 메커니즘이 필요한 다른 계약 설계에도 도움이 될 수 있습니다.