ERC-5585 NFT 사용권 위임 표준 (ERC-721 NFT Authorization)
Final · NFT·멀티토큰 · 2022-08-15 작성
NFT의 소유권과 상업적 사용권을 분리해 소유자가 다른 사용자에게 특정 권리를 정해진 기간 동안 위임할 수 있게 하는 ERC-721 확장 표준입니다.
왜 필요한가
대부분의 NFT는 소유자가 한 명뿐인 단순한 소유권 확인 구조입니다. 이 구조에서는 전시, 2차 창작물 제작, 배포 같은 다른 권리를 따로 나눠 줄 방법이 없어 NFT의 가치와 상업화가 제한됩니다. 상업적 권리(commercial right)는 저작권에 바탕을 둔 넓은 개념으로 복제, 전시, 배포, 대여, 상업적 이용, 수정, 재허가 등을 포함합니다. 메타버스가 발전하면서 NFT는 디지털 수집품, 가상 부동산, 음악, 예술, 소셜 미디어 등 온갖 디지털 자산으로 다양해지고 있고 NFT에 기반한 저작권과 이용 허락이 새로운 사업 형태가 될 수 있습니다. 그래서 소유권과 사용권을 분리해 각각 독립적으로 관리할 수 있게 하면 NFT의 상업적 가치를 높일 수 있습니다.
구현해야 하는 것
function getRights() external view returns(string[]);: 이 NFT 프로젝트에서 사용자에게 위임할 수 있는 모든 권리 목록을 반환합니다.function authorizeUser(uint256 tokenId, address user, uint duration) external;: NFT 보유자가 해당 NFT의 모든 권리를 지정한 기간 동안 사용자에게 위임합니다.function authorizeUser(uint256 tokenId, address user, string[] rights, uint duration) external;: NFT 보유자가 대여, 배포, 전시 같은 특정 권리만 골라 지정한 기간 동안 사용자에게 위임합니다. 프로젝트에 정의되지 않은 권리면 예외가 발생합니다.function transferUserRights(uint256 tokenId, address newUser) external;: NFT의 사용자가 자신이 위임받은 권리를 새 사용자에게 넘깁니다.function extendDuration(uint256 tokenId, address user, uint duration) external;: NFT 보유자가 이미 위임한 권리의 기간을 연장합니다.function updateUserRights(uint256 tokenId, address user, string[] rights) external;: NFT 보유자가 사용자에게 위임한 권리 내용을 새 권리 목록으로 갱신합니다.function getExpires(uint256 tokenId, address user) external view returns(uint);: 지정한 NFT와 사용자에 대한 위임 만료 시각을 반환합니다.function getUserRights(uint256 tokenId, address user) external view returns(string[]);: 지정한 NFT와 사용자에 대해 위임된 권리 목록을 반환합니다.function updateUserLimit(uint256 userLimit) external onlyOwner;: 컨트랙트 소유자가 NFT 하나당 위임할 수 있는 사용자 수를 갱신합니다.function updateResetAllowed(bool resetAllowed) external onlyOwner;: 컨트랙트 소유자가 위임을 중간에 취소할 수 있는지 여부를 나타내는 resetAllowed 플래그를 갱신합니다.function checkAuthorizationAvailability(uint256 tokenId) public view returns(bool);: 해당 NFT가 지금 위임 가능한 상태인지 참 또는 거짓으로 반환합니다. 유효하지 않은 NFT면 예외가 발생합니다.function resetUser(uint256 tokenId, address user) external;: 지정한 사용자의 위임을 해제합니다. resetAllowed가 true일 때만 동작하고 false면 예외가 발생합니다.event authorizeUser(uint256 indexed tokenId, address indexed user, string[] rights, uint expires);: NFT의 사용자가 바뀌거나 위임 만료 시각이 갱신될 때 발생하는 이벤트입니다.event updateUserLimit(uint256 userLimit);: NFT 하나당 위임 가능한 사용자 수가 갱신될 때 발생하는 이벤트입니다.
심층 설명
UserRecord 구조체와 권리 모델
위임 정보는 UserRecord 구조체에 담습니다. user는 위임받은 사용자 주소, rights는 위임된 권리의 문자열 배열, expires는 만료 시각입니다. 권리는 대여, 배포, 전시처럼 문자열로 표현하며 프로젝트가 정의한 전체 권리 목록은 getRights()로 조회합니다. 정의되지 않은 권리를 위임하려 하면 예외가 발생합니다. 모든 함수에서 제로 주소는 사용자가 없음을 뜻합니다. NFT 소유자는 특정 권리만 골라 위임하고 필요할 때 updateUserRights()로 갱신할 수 있습니다.
authorizeUser의 두 가지 오버로드
authorizeUser(uint256 tokenId, address user, uint duration)은 NFT의 모든 권리를 지정 기간 동안 위임하고, authorizeUser(uint256 tokenId, address user, string[] rights, uint duration)은 특정 권리만 위임합니다. 두 함수 모두 public 또는 external로 구현할 수 있습니다. 위임 후에는 extendDuration()으로 기간을 연장하고 updateUserRights()로 권리를 바꿀 수 있으며 사용자는 transferUserRights()로 자신의 권리를 새 사용자에게 이전할 수 있습니다.
컨트랙트 소유자의 통제 장치
컨트랙트 소유자는 두 가지 전역 설정을 관리합니다. updateUserLimit(uint256 userLimit)은 NFT 하나당 위임 가능한 사용자 수를 정하고, updateResetAllowed(bool resetAllowed)는 위임을 중간에 취소할 수 있는지를 정합니다. 두 함수 모두 onlyOwner 제한이 붙습니다. resetAllowed가 true면 NFT 소유자가 언제든 resetUser()로 모든 위임 사용자의 사용권을 해제할 수 있고 false면 resetUser() 호출이 예외를 던집니다. 이는 관련 당사자들의 이해관계를 보호하기 위한 설계입니다.
이벤트 발생 규칙
authorizeUser 이벤트는 NFT의 사용자가 바뀌거나 위임 만료 시각이 갱신될 때 반드시(MUST) 발생해야 하며 tokenId와 user가 indexed로 기록되고 rights와 expires가 함께 담깁니다. updateUserLimit 이벤트는 NFT 하나당 위임 가능한 사용자 수가 갱신될 때 반드시 발생해야 합니다. 조회 함수인 getExpires(), getUserRights(), getRights(), checkAuthorizationAvailability()는 pure 또는 view로 구현할 수 있습니다.
ERC-721 확장으로서의 호환성
이 표준은 ERC-721의 확장이므로 ERC-721과 호환되며 새 NFT 프로젝트에 쉽게 통합할 수 있습니다. 다른 프로젝트가 이 인터페이스와 직접 상호작용해 자신만의 거래 형태를 구현할 수 있습니다. 원문은 예시로, 공지 플랫폼이 이 표준을 이용해 모든 NFT 소유자가 언제든 위임과 해제를 할 수 있게 만드는 경우를 듭니다. 이 제안은 Final 상태로 확정된 표준입니다.
쓸 때 주의할 점
- resetAllowed가 false일 때 위임 수수료 정산: resetAllowed가 false면 위임 기간 중에 NFT 소유자가 위임을 취소할 수 없습니다. 이때 NFT가 새 보유자에게 팔리면 사용자가 낸 위임 수수료를 공정하게 나눌 방법을 마련해야 합니다. 원문은 참고용 해법으로 에스크로 컨트랙트를 제시합니다. 위임 기간에 따라 수수료를 에스크로에 맡겨 두는 방식으로, 예를 들어 위임 기간이 12개월이고 수수료가 총 10 ETH일 때 3개월 뒤 NFT가 이전되면 2.5 ETH만 지급되고 나머지 7.5 ETH는 환불됩니다.