ERC-5646 토큰 상태 지문 (Token State Fingerprint)

Final · 토큰 · 2022-09-11 작성

상태가 변할 수 있는 토큰의 현재 상태를 32바이트 지문(fingerprint) 하나로 요약해 주는 표준입니다. 외부 프로토콜이 토큰 내부 구현을 몰라도 상태가 바뀌었는지 확인할 수 있습니다.

왜 필요한가

유동성 포지션처럼 내부 상태가 계속 바뀌는 토큰이 있습니다. 어떤 프로토콜이 이런 토큰을 다루려면, 지금은 그 토큰에 어떤 상태 값이 있는지 구현 세부까지 알아야 토큰을 정확히 식별할 수 있습니다. 그 결과 새로운 토큰이 나올 때마다 프로토콜이 하나하나 따로 지원 작업을 해야 하는 병목이 생깁니다. 신뢰가 더 큰 문제입니다. 예를 들어 어떤 토큰에 매수 제안을 걸어 두었는데, 제안을 수락하기 직전에 소유자가 토큰의 상태를 몰래 바꿀 수 있다면 제안자는 생각했던 것과 다른 토큰을 받게 됩니다. 상태 변화를 밖에서 확실하게 감지할 공통 방법이 없으면 이런 가변 토큰을 믿고 거래하기 어렵습니다.

구현해야 하는 것

심층 설명

인터페이스는 함수 하나입니다

ERC5646 인터페이스는 getStateFingerprint(uint256 tokenId) 하나로 구성되며 ERC165를 상속합니다. view 함수이고 bytes32를 반환합니다. 토큰 id가 가리키는 토큰의 현재 상태 지문을 돌려주는 것이 전부이며 상태 값 자체를 노출하는 함수는 없습니다. 목표가 상태 내용을 알리는 것이 아니라 상태가 바뀌었는지만 밖에서 판별할 수 있게 하는 것이기 때문입니다.

지문이 지켜야 하는 규칙

getStateFingerprint는 토큰 상태가 바뀌면 반드시 다른 값을 반환해야 하고(MUST), 상태가 같으면 다른 값을 반환해서는 안 됩니다(MUST NOT). 또 토큰 수명 주기 동안 바뀔 수 있는 모든 상태 속성, 즉 불변이 아닌 속성을 전부 지문 계산에 포함해야 합니다(MUST). 이 세 규칙이 지켜져야 지문이 상태의 명확한 식별자 역할을 합니다.

계산 값과 메타데이터도 넣을 수 있습니다

지문에는 현재 타임스탬프에 따라 달라지는 계산 값을 포함할 수 있습니다(MAY). 원문은 만기(expiration, maturity)를 예로 듭니다. 예를 들어 만기가 지났는지 여부를 지문에 넣으면, 저장된 값이 그대로여도 시간이 흘러 만기가 지나는 순간 지문이 달라집니다. 토큰 메타데이터 URI도 포함할 수 있습니다(MAY).

ERC-165 지원 선언

구현 컨트랙트는 supportsInterface(0xf5112315) 호출에 반드시 true를 반환해야 합니다(MUST). 외부 프로토콜은 이 호출로 토큰이 상태 지문 표준을 구현했는지 먼저 확인한 뒤 getStateFingerprint를 사용할 수 있습니다.

불변 속성은 지문에서 빼도 됩니다

배포 후 절대 바뀌지 않는 속성은 토큰 id만으로 안전하게 식별되므로 지문 계산에 넣을 필요가 없습니다. 프로토콜은 지문을 토큰 식별자의 일부로 사용해, 상태 구현 세부를 전혀 모른 채 가변 토큰을 지원할 수 있습니다. 다만 이 표준은 상태 속성의 내용 자체를 알아야 하는 용도에는 맞지 않습니다. 그런 경우는 결국 토큰별 지원이 필요한 병목 문제를 피할 수 없다고 원문이 밝힙니다.

참조 구현: LP 토큰 예시

참조 구현 LPToken은 ERC721과 ERC5646을 구현하며, 토큰별 State 구조체에 asset1, asset2, amount1, amount2, fee, operator, expiration을 저장합니다. getStateFingerprint는 keccak256(abi.encode(...))로 지문을 만드는데, 불변인 fee와 operator는 계산에서 제외하고 expiration은 값 자체 대신 block.timestamp >= state.expiration이라는 만기 경과 여부를 넣습니다. supportsInterface는 type(ERC5646).interfaceId를 추가로 인정합니다.

쓸 때 주의할 점

ERC 원문 · ← ERCs