ERC-5192 최소 소울바운드 NFT (Minimal Soulbound NFTs)
Final · NFT·멀티토큰 · 2022-07-01 작성
EIP-721 NFT에 locked 함수 하나와 이벤트 두 개를 더해, 토큰이 한 계정에 묶여 전송할 수 없는지 지갑과 앱이 표준 방식으로 확인하게 합니다.
왜 필요한가
소울바운드 토큰(Soulbound Token)은 한 계정에 묶여 다른 사람에게 넘길 수 없는 NFT입니다. 이더리움 커뮤니티는 월드 오브 워크래프트의 귀속 아이템처럼 양도할 수 없고 사회적 의미로 가치가 매겨지는 토큰을 원해 왔습니다. 그런데 이를 위한 표준이 없어서 많은 개발자가 사용자가 전송 기능을 부르면 그냥 오류를 내는 식으로 구현했습니다. 지갑이나 앱 입장에서는 어떤 토큰이 전송 불가인지 미리 알 방법이 없고 구현마다 방식이 달라 서로 맞물려 쓰기 어렵습니다. 이런 상태가 길어지면 구현이 갈라지고 조합 가능성이 떨어집니다. 이 표준은 EIP-721에 아주 작은 인터페이스를 더해, 지갑이 EIP-165 기능 감지로 토큰 컨트랙트의 영구적인 전송 가능 여부를 확인할 수 있게 합니다.
구현해야 하는 것
event Locked(uint256 tokenId);: 토큰의 묶임 상태가 locked로 바뀔 때 발생합니다. 묶인 상태로 발행될 때도 내야 합니다.event Unlocked(uint256 tokenId);: 토큰의 묶임 상태가 unlocked로 바뀔 때 발생합니다. 풀린 상태로 발행될 때도 내야 합니다.function locked(uint256 tokenId) external view returns (bool);: 해당 토큰이 계정에 묶여 있는지 돌려줍니다. 제로 주소에 배정된 토큰은 유효하지 않으며 조회가 throw합니다.function supportsInterface(bytes4 interfaceID) external view returns (bool): EIP-165 함수입니다. interfaceID가 0xb45a3c0e이면 이 표준을 구현한 컨트랙트는 반드시 true를 돌려줍니다.
심층 설명
EIP-721 확장과 EIP-165 감지
이 표준은 EIP-721을 확장하는 인터페이스이며 EIP-165와 EIP-721이 필요합니다(requires: 165, 721). 새 토큰 규격을 만드는 것이 아니라 기존 EIP-721 토큰에 IERC5192 인터페이스를 덧붙이는 방식입니다. 원문은 이 모델이 소울바운드 토큰의 정식 인터페이스로 가는 가장 단순한 경로이며 전송 시 그냥 revert하는 수많은 기존 구현을 반영한 것이라고 설명합니다. 인터페이스 코드는 pragma solidity ^0.8.0을 쓰고 SPDX-License-Identifier는 CC0-1.0입니다.
locked 함수와 전송 금지 규칙
function locked(uint256 tokenId) external view returns (bool)은 해당 tokenId의 묶임 상태를 돌려줍니다. uint256 tokenId를 가진 토큰은 locked가 true를 반환하면 받은 계정에 묶인 것으로 봅니다. 이 경우 토큰을 한 계정에서 다른 계정으로 옮기는 이 컨트랙트의 모든 EIP-721 함수는 반드시 throw해야 합니다. 제로 주소에 배정된 소울바운드 토큰은 유효하지 않은 것으로 간주하며 이런 토큰에 대한 조회는 throw합니다.
Locked와 Unlocked 이벤트
event Locked(uint256 tokenId)는 묶임 상태가 locked로 바뀔 때, event Unlocked(uint256 tokenId)는 unlocked로 바뀔 때 발생합니다. 토큰을 발행(mint)할 때도 상태가 locked이면 Locked를, unlocked이면 Unlocked를 내야 합니다(원문 표현은 should). 두 이벤트 모두 인자는 tokenId 하나뿐입니다. locked 함수는 현재 상태를 돌려주고 이벤트는 상태 변화를 알리는 역할이므로, 발행 시점에도 이벤트를 내야 처음 상태를 이벤트만으로 알 수 있습니다.
인터페이스 ID 0xb45a3c0e
EIP-721 토큰이 이 표준으로 소울바인딩을 구현했음을 알리기 위해, EIP-721의 function supportsInterface(bytes4 interfaceID) external view returns (bool)을 interfaceID=0xb45a3c0e로 호출하면 이 표준을 구현한 컨트랙트는 반드시 true를 반환해야 합니다. 지갑 구현자는 이 호출 한 번으로 토큰 컨트랙트의 영구적인 전송 (불)가능성을 확인할 수 있습니다. EIP-165의 기능 감지 방식을 그대로 쓰는 것입니다.
하위 호환성, 보안, 상태
이 제안은 EIP-721과 완전히 하위 호환됩니다. 원문 Security Considerations는 이 표준 구현과 직접 관련된 보안 고려 사항이 없다고 밝힙니다. 상태는 Final이며 Standards Track의 ERC 범주에 속합니다. 2022년 7월 1일에 만들어졌고 저작권과 관련 권리는 CC0로 포기되어 누구나 자유롭게 쓸 수 있습니다.