교육 목적으로만 제공되며 투자 조언이 아닙니다. 디지털 자산 거래와 서명은 되돌릴 수 없는 손실을 초래할 수 있습니다.
직접 답변
거버넌스 위임 서명은 디코딩된 메시지가 본인이 의도한 위임과 정확히 일치하고 거버넌스 컨트랙트가 충분한 재전송 방지 기능을 적용한 경우에만 안전합니다. 일반적인 투표 토큰 설계에서 위임은 서명자의 투표권을 누가 행사할 수 있는지를 바꿉니다. 토큰 잔액을 이전하거나 토큰 지출 승인을 부여하는 것은 아닙니다. 다만 서명이 실제로 무엇을 하는지에 대한 최종 기준은 배포된 컨트랙트입니다.
오프체인 서명은 릴레이어가 제출할 수 있으므로 서명자가 Gas를 지불하지 않아도 온체인 상태 변경을 허용하게 됩니다. 서명을 로그인이나 무해한 지갑 연결 요청이 아니라 실행 가능한 지시로 취급하세요.
작동 방식
일반적인 delegateBySig 흐름은 다음 네 단계로 진행됩니다.
- 애플리케이션이 위임 대상 주소, 논스, 만료를 포함한 EIP-712 형식화 데이터를 준비합니다.
- 지갑이 형식화된 메시지와 EIP-712 도메인에 결합된 다이제스트에 서명합니다.
- 어떤 계정이든 서명을 토큰 또는 거버넌스 컨트랙트로 중계할 수 있습니다.
- 컨트랙트가 서명자를 복구하거나 검증하고 논스와 만료를 확인한 뒤 새 위임 대상을 기록합니다.
EIP-712 도메인에는 name, version, chainId, verifyingContract가 포함될 수 있습니다. 이 필드는 내용이 같은 메시지라도 애플리케이션, 버전, 네트워크, 컨트랙트가 다르면 서로 분리해 줍니다. EIP-712 자체는 재전송 방지를 제공하지 않는다고 명시합니다. 컨트랙트가 논스를 소모하거나 각 승인을 한 번만 사용할 수 있도록 다른 장치를 마련해야 하며, 만료는 컨트랙트가 실제로 확인할 때에만 실행 가능 시간을 제한합니다.
서명하기 전에 공식 거버넌스 인터페이스, 문서 또는 독립적으로 검증한 컨트랙트 데이터와 대조하여 다음을 모두 확인하세요.
primaryType과 필드 이름이 Permit, 토큰 전송, 주문 또는 계정 관리 승인이 아니라 위임을 나타내는지 확인합니다.verifyingContract가 현재chainId에서 의도한 토큰 또는 거버넌스 컨트랙트인지 확인합니다.delegatee가 본인이 선택한 대표자 주소인지 표시 이름이 아닌 전체 주소로 확인합니다.nonce가 컨트랙트에 기록된 서명자의 현재 논스와 일치하고expiry가 목적에 비해 충분히 짧은지 확인합니다.- 지갑이 형식화된 데이터 전체를 표시하는지 확인합니다. 의미를 독립적으로 재현할 수 없는 원시 해시나 블라인드 서명을 요구하면 거부하세요.
구현 방식은 서로 다릅니다. 예를 들어 Compound의 COMP 컨트랙트는 위임 대상, 논스, 만료를 해싱하고, 논스가 서명자에 대해 저장된 논스와 같아야 한다고 요구하며, 해당 논스를 증가시키고 만료된 서명을 거부합니다. OpenZeppelin의 Votes 인터페이스도 delegateBySig, 논스 처리, 만료 확인을 제공합니다. 다른 컨트랙트에 이름이 비슷한 함수가 있다고 해서 동일한 보호 기능이 있다고 가정하지 마세요.
예시
Mira는 10,000표를 주소 0xAB...1234에 위임하려 합니다. 지갑에는 primaryType: Delegation, 검증된 투표 토큰 컨트랙트, 현재 체인 ID, delegatee: 0xAB...1234, 현재 논스, 20분 후의 만료가 표시됩니다. Mira가 두 번째 신뢰할 수 있는 출처에서 주소를 확인한 뒤 서명하면 릴레이어가 메시지를 제출하고 컨트랙트가 위임 이벤트를 내보냅니다. 토큰 잔액은 Mira의 지갑에 그대로 있고, 대표자는 해당 프로토콜 규칙에 따라 관련 투표권을 얻습니다.
이제 한 가지를 바꿔 보겠습니다. 페이지가 primaryType: Permit을 요청하면서 토큰 지출자를 지정하거나 verifyingContract가 무관한 컨트랙트인 경우입니다. 이는 동일한 위임 지시가 아닙니다. 버튼에 “위임”이라고 쓰여 있고 서명자가 Gas를 내지 않더라도 토큰 지출을 허용할 수 있습니다. Mira는 이를 거부해야 합니다.
위험과 통제 방법
- 잘못된 위임 대상: 주소 포이즈닝, 개인 메시지, 복사된 표시 이름 때문에
delegatee가 공격자가 관리하는 주소로 바뀔 수 있습니다. 공식 제안 또는 대표자 프로필에서 전체 주소를 확인하세요. - 잘못된 작업: 악성 인터페이스가 Permit 같은 다른 EIP-712 형식을 요청할 수 있습니다.
primaryType, 모든 필드, 검증 컨트랙트를 읽으세요. 버튼 라벨은 보안상 아무 의미가 없습니다. - 재전송: 논스 확인이 약하거나 없으면 서명을 재사용할 수 있습니다. 도메인이 의도한 체인이나 컨트랙트에 결합되지 않은 경우에도 원치 않는 맥락에서 사용될 수 있습니다. EIP-712만으로는 재전송을 막을 수 없으므로 실제 검증 코드를 확인하세요.
- 오래 유효한 서명: 사용하지 않은 서명 메시지는 만료되거나 논스가 무효가 될 때까지 실행 가능할 수 있습니다. 짧은 만료를 선택하고 서명을 공개하지 마세요. 취소가 필요하면 프로토콜 문서에 명시된 무효화 방식만 사용하세요.
- 오해를 부르는 지갑 표시: 필드가 잘리거나 도메인이 알려지지 않았거나 블라인드 서명을 요구하면 충분한 정보를 바탕으로 동의할 수 없습니다. 취소하고 메시지 전체를 보여 주는 지갑이나 디코더로 형식화 데이터 요청을 검사하세요.
- 컨트랙트 계정의 차이: 스마트 컨트랙트 지갑은 ERC-1271로 서명을 검증할 수 있으며, 유효성은 지갑 상태와 승인 정책에 따라 달라질 수 있습니다. EOA 방식의 복구를 가정하지 말고 지갑과 거버넌스 컨트랙트가 모두 지원하는지 확인하세요.
- 거버넌스 결과: 위임은 투표권을 집중시키거나 신뢰할 수 없는 위임 대상이 본인의 이익에 반하는 투표를 하게 할 수 있습니다. 위임 대상의 신원, 투표 이력, 이해 충돌과 프로토콜의 재위임 절차를 검토하세요.
제출 후 올바른 체인에서 거래를 검증하세요. 대상 컨트랙트, 디코딩된 함수, 이벤트에서 복구 또는 보고된 서명자, 새 위임 대상, 논스를 확인합니다. 릴레이어 거래가 성공했다는 사실은 컨트랙트가 호출을 받아들였다는 뜻일 뿐, 서명 의도가 안전했다는 뜻은 아닙니다.
서명했지만 아직 제출된 것을 확인하지 못했다면 서명 공유를 중단하고 프로토콜 문서에 명시된 취소 또는 논스 무효화 경로를 확인하세요. 원치 않는 위임이 실행되었다면 공식 컨트랙트로 재위임하고 새 상태를 검증하세요. 위임만으로는 일반적으로 토큰 사용 한도가 생기지 않으므로 재위임과 승인 철회를 혼동하지 마세요. Permit에도 서명했거나 시드 문구 또는 개인 키를 노출했다면 별도의 더 심각한 지갑 사고로 대응해야 합니다.
흔한 오해
- “Gas가 들지 않으면 권한도 주지 않는다.” 릴레이어가 Gas를 지불하고 서명이 서명자의 권한을 제공할 수 있습니다.
- “EIP-712를 쓰면 모든 서명이 안전하다.” 이 표준은 형식화 데이터 해싱과 도메인 분리를 표준화하지만 재전송 방지는 포함하지 않으며, 사용자가 표시된 작업을 실제로 의도했는지도 검증할 수 없습니다.
- “위임하면 내 토큰이 이전된다.” 일반적인 투표 위임은 토큰 소유권이 아니라 투표권을 이전하거나 배정합니다. 다만 실제 효과는 배포된 컨트랙트와 디코딩된 메시지를 통해서만 확정할 수 있습니다.
- “오프체인 서명은 언제나 철회할 수 있다.” 모든 서명에 통용되는 철회 거래는 없습니다. 만료, 논스 소모 또는 무효화, 재위임은 컨트랙트마다 다른 메커니즘입니다.
- “위임 대상을 바꾸면 이전 투표가 사라진다.” 재위임은 프로토콜 규칙에 따라 미래 또는 현재 투표권을 바꾸지만 이미 행사한 표를 되돌리거나 과거 스냅샷을 변경하지 못할 수 있습니다.
관련 주제
출처
- EIP-712: 형식화된 구조화 데이터의 해싱 및 서명 - Ethereum Improvement Proposals (확인일: 2026-08-20)
- Comp.sol - Compound Finance (확인일: 2026-08-20)
- 거버넌스 API - OpenZeppelin (확인일: 2026-08-20)
- ERC-1271: 컨트랙트용 표준 서명 검증 방법 - Ethereum Improvement Proposals (확인일: 2026-08-20)