EIP-2612 permit은 토큰 보유자가 EIP-712 서명으로 spender와 allowance 수량을 승인하는 ERC-20 확장입니다. 서명에는 owner, spender, value, nonce, deadline과 토큰 계약·체인 domain이 결합됩니다. 서명 자체는 가스를 쓰지 않지만 누구든 유효한 서명을 permit 함수에 제출하면 온체인 allowance가 생기므로 전송 거래가 아니라는 이유로 가볍게 서명하면 안 됩니다.
permit은 approve를 서명으로 표현한다
일반 ERC-20 approve는 토큰 보유자가 직접 온체인 거래를 보내 spender allowance를 바꿉니다. EIP-2612는 permit(owner, spender, value, deadline, v, r, s)를 추가해 보유자가 만든 서명을 제3자가 제출할 수 있게 합니다. 제출자가 가스를 내므로 owner가 네이티브 코인을 보유하지 않아도 승인과 후속 작업을 한 흐름으로 묶을 수 있습니다.
permit 실행이 성공하면 allowance[owner][spender]가 value로 설정되고 Approval 이벤트가 발생합니다. 토큰을 즉시 이동하는 것은 아니지만 spender는 이후 transferFrom을 사용할 수 있습니다. 사용자가 보는 결과는 서명 요청 하나여도 경제적 효과는 approve 거래와 같은 토큰 이동 권한입니다.
| 필드 | 의미 | 확인 질문 |
|---|---|---|
| owner | 토큰 소유자 | 내 주소인가 |
| spender | 이동 권한을 받을 주소 | 공식 계약인가 |
| value | 승인 수량 기본 단위 | 의도한 한도인가 |
| nonce·deadline | 재사용·시간 제한 | 현재 값과 만료가 적절한가 |
| domain | 토큰·체인 구분 | 계약과 chain ID가 맞는가 |
nonce는 같은 서명의 재사용을 막는다
표준은 owner별 nonces 값을 서명 데이터에 넣고 성공한 permit 뒤 1 증가하도록 합니다. 이미 사용한 nonce의 서명은 다시 제출할 수 없어 동일 승인을 반복 실행하는 재생을 막습니다. 서명 화면이 nonce를 숨기더라도 토큰 계약의 현재 nonces(owner)와 요청 값을 비교할 수 있습니다.
nonce는 취소 수단과 동일하지 않습니다. 아직 제출되지 않은 서명을 무효화하려면 같은 nonce를 소비하는 다른 permit이나 토큰 구현이 제공하는 방식이 필요할 수 있습니다. 표준은 일반적인 서명 취소 함수를 정의하지 않으므로 발행 전에 deadline을 짧게 두는 것이 중요합니다.
가스를 쓰지 않은 서명도 제출되는 순간 온체인 권한이 된다.
JOBCOIN 해설
deadline은 제출 창을 제한할 뿐 자동 취소가 아니다
permit은 현재 block timestamp가 deadline보다 늦으면 실패해야 합니다. 짧은 deadline은 서명이 피싱 로그나 중계자에 오래 남아 실행되는 범위를 줄입니다. 무기한에 가까운 큰 값을 쓰면 사용하지 않은 서명이 장기간 유효할 수 있습니다.
deadline 전에 permit이 제출돼 allowance가 설정되면 이후 deadline이 지나도 이미 만들어진 allowance가 자동으로 0이 되지는 않습니다. 만료는 서명 제출 가능 시간에 적용됩니다. 생성된 승인을 없애려면 토큰 계약에서 별도의 approve 0 또는 새 permit으로 allowance를 변경해야 합니다.
- 토큰 계약과 chain ID가 공식 배포와 맞는지 확인한다.
- spender를 이름이 아니라 전체 주소로 대조한다.
- value를 decimals로 환산해 실제 승인량을 계산한다.
- deadline 뒤에도 기존 allowance는 남는다는 점을 기억한다.
EIP-712 domain이 다른 계약과 체인을 구분한다
EIP-2612 서명 해시는 DOMAIN_SEPARATOR와 Permit 구조체 해시를 결합합니다. domain에는 name, version, chainId, verifyingContract 등이 사용될 수 있어 다른 토큰이나 체인에서 같은 필드 서명을 재생하는 일을 줄입니다. 토큰 프록시와 체인 포크에서는 구현이 domain을 어떻게 계산하는지 확인합니다.
지갑이 typed data를 사람이 읽게 보여 주면 필드를 하나씩 검토합니다. blind signing처럼 해시만 보이면 spender와 value를 독립적으로 확인하기 어렵습니다. 공식 디앱에서 다시 시작하고 하드웨어 지갑이 typed data를 해석해 표시하는지 확인합니다.
permit과 후속 호출은 한 거래에 묶일 수 있다
디앱은 사용자의 permit 서명을 받은 뒤 라우터 거래에서 permit을 먼저 제출하고 곧바로 transferFrom이나 deposit을 실행할 수 있습니다. 사용자 입장에서는 approve와 예치 두 번의 온체인 거래를 한 번으로 줄일 수 있습니다. 하지만 후속 호출이 실패했을 때 permit도 같은 트랜잭션에서 함께 revert되는지, 별도 제출됐는지에 따라 남은 allowance가 다릅니다.
중계자가 permit만 먼저 제출한 뒤 후속 작업을 실행하지 않을 수도 있습니다. 프로토콜은 permit과 목적 작업을 원자적으로 처리하고 최소 수령 조건을 적용해야 합니다. 사용자는 거래 실패 뒤 allowance와 nonce를 다시 조회해 권한이 남았는지 확인합니다.
모든 permit이라는 이름이 EIP-2612는 아니다
DAI 스타일 permit처럼 value 대신 allowed bool을 쓰는 선행 구현이 있고, NFT permit이나 Permit2도 필드와 nonce 체계가 다릅니다. UI에 permit이라고 표시된다는 이유만으로 EIP-2612 형식이라고 가정하지 않습니다. 실제 verifying contract와 type hash, 함수 selector를 확인합니다.
OpenZeppelin ERC20Permit 구현은 EIP-712와 nonce 유틸리티를 결합하지만 각 토큰의 이름·버전·프록시 배포 방식은 다를 수 있습니다. verified source와 공식 인터페이스를 확인하고 테스트넷에서 서명 디코딩을 연습합니다. 서명 뒤에는 Approval 이벤트와 allowance를 기록합니다.
자주 묻는 질문
permit 서명만 하면 토큰이 바로 빠져나가나요?
서명 자체는 allowance 승인 권한입니다. 유효한 서명이 온체인에 제출되고 spender가 transferFrom을 호출해야 토큰이 이동합니다.
deadline이 지나면 만들어진 승인도 사라지나요?
아닙니다. deadline은 permit 서명의 제출 가능 시간입니다. 이미 설정된 allowance는 별도 취소 전까지 남을 수 있습니다.
permit에 가스비가 전혀 없나요?
owner는 서명만 할 수 있지만 누군가는 permit을 온체인에 제출하며 가스를 냅니다. 보통 디앱이나 중계자가 후속 호출과 함께 제출합니다.



