
ERC721-O: 풀체인 NFT의 표준 프로토콜 및 구현
ERC721-O는Catddle NFT의 개발팀인 Catddle Lab이 설계했습니다. Catddle NFT는 ERC721-O를 사용해 개발된 최초의 풀체인(Full-chain) NFT가 될 예정입니다.
*ERC721-O는 완전히 오픈소스인 프로젝트입니다. GitHub에서 기여를 환영합니다!
개요
ERC721-O는ERC721을 기반으로 하는 풀체인 NFT(Non-Fungible Token)의 표준 프로토콜 및 구현입니다.
ERC721-O 프로토콜은 지갑/거래소 등 제3자 애플리케이션이 이 프로토콜을 구현한 모든 NFT와 일관된 방식으로 검증 및 상호작용할 수 있도록 도와줍니다.
ERC721-O는 다양한 크로스체인 기능을 추가하였으며, 크로스체인 보안 문제 해결을 위한 일련의 방안도 제시합니다.
배경
LayerZero는 블록체인 간 메시지 전달 서비스를 제공하는 새로운 블록체인 인프라입니다. LayerZero의 논문에 따르면, 이러한 메시지 전달 서비스는 유효한 전달을 보장합니다. 수신 측이 유효한 전달 서비스로부터 메시지 m을 수신하면, 해당 서비스는 관련 트랜잭션 t가 유효하며 발신 측 체인에서 커밋되었음을 보장합니다.
이러한 일반 메시지 프로토콜을 통해 풀체인 NFT의 실현이 가능해졌습니다.
기존 풀체인 NFT*와의 차이점

ERC721-O의 개선 사항
더 안전함
· 크로스체인 가스 보호 메커니즘
비차단(non-blocking) 등의 일련의 보안 설계를 갖추고 있음에도 불구하고, 크로스체인 가스 한도(destination gas limit)가 낮게 설정될 경우 NFT가 크로스체인 중에 멈출 수 있습니다.
이러한 상황을 방지하기 위해 크로스체인 가스 보호 메커니즘을 도입하였습니다. 계약 소유자는 합리적인 최소 크로스체인 가스 한도를 설정함으로써 모든 NFT가 성공적으로 크로스체인이 완료되도록 보장할 수 있으며, 가스 부족 현상 없이 다른 크로스체인 기능도 영향을 받지 않습니다.
· 원격 주소 보안 설정
운영 중인 풀체인 NFT 계약을 업데이트하면 자금 손실이 발생할 수 있습니다. 또한 풀체인 NFT 계약을 새로운 체인에 배포할 때 특정 함수 호출 순서를 따르지 않으면 크로스체인 중에 NFT가 막히거나 영구적으로 분실될 수 있습니다.
이러한 문제들을 해결하기 위해 ERC721-O는 안전한 원격 주소 설정 메커니즘을 도입하였습니다. 이 메커니즘을 통해 계약 소유자는 계약 업데이트 시 자금 손실 문제를 피할 수 있으며, 체인 간 함수 호출 순서를 신경 쓰지 않아도 됩니다.
· 외부 라이브러리 버전 고정
메시지 송수신은 LayerZero 라이브러리에 의존합니다. LayerZero가 업데이트될 때 잠재적 오류를 방지하기 위해 외부 라이브러리 버전을 고정할 수 있어야 합니다. 이는 LayerZero 공식에서도 권장하는 최선의 방법입니다.
· 마지막 수단 보유
다양한 보안 설계(예: 비차단, 크로스체인 가스 보호)를 도입하더라도 메시지 경로가 막혀 재시도가 불가능한 상황이 발생할 수 있습니다.
forceResumeReceive는 우리가 사용할 수 있는 마지막 수단이며, 그렇지 않으면 체인 오류가 영구적으로 멈춰버릴 수 있습니다. 이를 마지막 수단으로 구현에 남겨두었습니다.
추가 기능
· 제3자 전송 승인(Approval) 모드 제공
제3자가 귀하의 토큰을 이전하도록 승인하는 것은 ERC20 및 ERC721에서 제공하는 핵심 기능입니다. 우리는 이 기능을 추가하여 제3자 애플리케이션이 풀체인 NFT와 더 잘 상호작용할 수 있도록 하였습니다.
· 크로스체인 전송 대상 주소 자유 선택
사용자는 이제 NFT를 다른 체인의 동일 주소로만 전송하는 것이 아니라, 다른 체인의 임의 주소로 전송할 수 있습니다.
· NFT 전송과 동시에 가스 에어드롭 수행 가능
사용자가 NFT를 다른 체인으로 전송한 후 이를 사용하려면 목표 체인의 주소로 추가 네이티브 가스(Ether, BNB, AVAX 등)를 보내야 하며, 이 추가 단계는 번거롭습니다.
이제 가스 크로스체인 에어드롭을 NFT 전송과 동시에 완료할 수 있으므로, 목적지 체인에서 추가 작업이 필요 없습니다.
· 토큰으로 크로스체인 수수료 지불 허용
LayerZero가 자체 토큰을 출시하면, 사용자는 특정 토큰 소유자를 설정하여 크로스체인 수수료를 지불할 수 있습니다. 일부 할인 혜택이 제공될 수도 있습니다 :)
더 투명함
· 핵심 배포 정보 공개
ERC721-O 프로토콜 설계에서는 송신 포트 주소(endpoint)와 원격 계약 주소(remote)를 모두 공개하도록 강제하고 있습니다. 따라서 모든 사용자와 제3자는 송신 포트 주소(endpoint)가 LayerZero 공식인지, 원격 계약 주소(remote)가 올바르게 설정되었는지 확인할 수 있습니다.
따라서 거래소 및 지갑과 같은 제3자는 ERC721-O 토큰에 대해 사용자 자금 손실 방지를 위한 검사 메커니즘을 쉽게 구현할 수 있습니다.
· 중요한 체인 상 활동 공개
중요한 체인 상 활동이 발생할 때 이벤트를 전송하면 사용자와 제3자가 체인에서 무엇이 발생했는지 즉시 알 수 있습니다.
ERC721-O 인터페이스 설계에서는 다른 체인으로 NFT를 전송하거나 수신할 때 모두 이벤트 전송을 강제합니다. 이를 통해 사용자와 제3자는 체인에서 발생하는 일을 명확히 이해할 수 있습니다.
ERC721-O 구현에서는 일시 정지(pause), 원격 계약 주소 설정 등 기타 중요한 활동도 이벤트를 발생시켜 중요한 변경 사항을 사용자에게 알려줍니다.
· Nonce 추적 허용
Nonce는 특정 주소에서 보낸 몇 번째 트랜잭션인지 표시합니다. LayerZero는 Nonce 추적 기능을 제공하며, ERC721-O는 이를 크로스체인 이벤트에 포함합니다. 발생한 이벤트에서 제공되는 정보를 통해 사용자와 제3자는 소스 체인과 대상 체인의 트랜잭션을 쉽게 매칭할 수 있습니다.
가스 소모 감소
LayerZero가 이미 사용자를 위해 가스 예측 검사를 수행하기 때문에 메시지 전송 전 가스 예측 검사는 불필요합니다. ERC721-O는 이를 제거하여 크로스체인 시의 연료 소모를 줄입니다.
코드의 오버라이드 및 재사용 용이성
모든 함수와 변수는 오버라이드 및 재사용이 용이하도록 설계되었습니다.
기반 클래스로서 코드 내에서 virtual, override, internal이 광범위하게 사용되며, 개발자가 계약 코드를 상속받을 때 더 명확한 힌트와 안내를 제공하기 위해 잘 주석 처리되어 있습니다.
보안 설계의 원리
LayerZero 공식은 훌륭한 기본 구현예제를 제공합니다. 또한,Gh0stly Gh0sts와 같은 NFT는 누구에게나 크로스체인 NFT의 거대한 잠재력을 증명하였습니다.
그러나 풀체인 토큰이 더 멀리 나가려면 심각한 보안 문제를 인식하고 해결해야 합니다. 이러한 문제들을 해결하기 위해 ERC721-O는 일련의 독특한 보안 설계를 도입하였습니다.
구체적인 설계를 소개하기 전에 중요한 개념 하나를 소개하겠습니다. 바로 '크로스체인 메시지 차단(blocking)'입니다. 크로스체인 메시지 차단은 소스 계약에서 대상 체인으로 메시지를 전달할 수 없는 상태입니다. 이 상태에서는 소스 계약이 계속해서 메시지를 보낼 수 있지만, 모두 공중에 머물며 소스 체인에도, 대상 체인에도 존재하지 않아 수신 및 실행이 불가능합니다.
이는 NFT 사용자에게 불쾌감을 주는 것뿐만 아니라 위험한 상태인데, 그 이유는 다음과 같습니다:
모든 차단된 메시지는 체인에서 사라져 LayerZero가 관리하는 큐에서 대기하며 리스크를 초래할 수 있습니다.
실패한 메시지를 해결할 수 없으면 차단된 메시지 큐가 영원히 멈춰버립니다.
계약 소유자가 실패한 메시지를 처리하기 위해 retryPayload가 아닌 forceResumeReceive 함수를 사용하면 실패한 메시지가 영구적으로 분실될 수 있습니다. 풀체인 NFT 구현에서 메시지 분실은 곧 NFT 분실과 동일하다는 점에 유의하세요.
따라서 보안 설계의 주요 목표는 메시지 차단 가능성을 최소화하는 것입니다.
· 크로스체인 가스 보호 메커니즘
주의할 점은 비차단 메커니즘을 사용하더라도 크로스체인 가스 한도(desination gas limit)가 낮은 문제로 인해 토큰이 멈출 수 있다는 것입니다.
ERC721-O 설계에서는 사용자에게 더 많은 기능을 제공하기 위해 어댑터 파라미터를 완전히 공개합니다. 예를 들어, NFT 전송과 동시에 가스 토큰(Ether, BNB, AVA 등)을 에어드롭할 수 있습니다. 사용자는 필요에 따라 수동으로 크로스체인 가스 한도를 설정할 수도 있습니다. 사용자가 크로스체인 가스 한도를 100으로 설정하고 크로스체인 요청을 시작하면, 이것은 LayerZero 엔드포인트 입장에서는 합법적이지만 실제로는 트랜잭션이 막히게 됩니다. 비차단 모드를 사용하더라도 마찬가지입니다.
이는 크로스체인 가스 한도가 너무 낮을 경우 수신 측 체인의 트랜잭션이 try-catch 부분 코드 실행 전에 실패하기 때문입니다. 즉, 이런 경우 비차단 모드는 무효입니다.
이 문제를 해결하기 위해 ERC721-O는 가스 보호 메커니즘을 도입하였습니다. 이 메커니즘은 사용자가 입력한 어댑터 파라미터의 유효성을 검사합니다. 어댑터 파라미터가 부적절하거나 할당된 가스가 계약 소유자가 지정한 최소 가스 한도보다 낮으면 트랜잭션은 전송되지 않습니다. 이 보호 메커니즘은 사용자가 향상된 어댑터 파라미터를 사용하는 것을 제한하지 않으며, 사용자는 여전히 향상된 파라미터를 통해 가스 에어드롭 등의 기능을 구현할 수 있습니다.
이 메커니즘을 통해 계약 소유자는 수신 함수의 가스 소모량에 따라 합리적인 최소 가스 한도를 설정하여 차단 문제를 방지할 수 있습니다.
· 원격 주소 보안 설정
누구나 LayerZero를 통해 누구에게나 메시지를 보낼 수 있으므로, 타인의 부당한 메시지 실행을 방지하기 위해 원격 계약을 설정해야 합니다. 기존 구현에서는 setTrustedRemote 함수가 메시지 발신자를 제한하는 데 도움이 됩니다. 계약 소유자는 setTrustRemote를 호출하여 원격 계약 주소를 설정하면, 해당 계약은 그 원격 계약 주소로부터만 메시지를 수신하게 됩니다.
이것은 합리적으로 들리지만, 서로 다른 체인에서의 작업 제출 시간에는 항상 간격이 존재한다는 점을 고려하지 않았습니다.
다음 시나리오를 가정해 봅시다. A 체인의 계약 a와 B 체인의 계약 b가 서로를 원격 계약으로 설정하고 모두 사용 중입니다. 사용 중이라는 것은 두 체인 모두에 발행된 NFT가 존재한다는 의미입니다. 이제 A 체인의 계약 a를 같은 A 체인의 새 계약 c로 업데이트하고자 합니다.
B 체인에서 setTrustRemote 함수를 호출하여 c를 계약 b의 새로운 원격 계약 주소로 설정할 수 있습니다. 하지만 이 경우 좋지 않은 상황이 발생할 수 있습니다. 이때 A 체인의 사용자는 여전히 B 체인으로 NFT를 보낼 수 있지만, B 체인의 원격 계약 주소가 이미 변경되어 A 체인이 아니므로, 그들이 보낸 모든 NFT는 영구적으로 분실됩니다. 여기서 비차단 메커니즘이 무력하다는 점에 유의하세요. 왜냐하면 올바른 원격 계약 주소가 설정된 후에만 작동하기 때문입니다.
반대로 계약 a의 원격 계약 주소를 먼저 변경하더라도 결과는 마찬가지입니다. B 체인의 NFT 사용자는 B 체인도 설정되기 전에 계약 a로 NFT를 보낼 수 있습니다. 이 역시 NFT가 영구적으로 분실되는 결과를 초래합니다. 왜냐하면 계약 a의 원격 계약 주소는 이미 변경되었고 더 이상 계약 b의 주소로 설정되지 않기 때문입니다.
여기서 주목해야 할 점은, 우리는 서로 다른 체인의 작업이 동시에 발생함을 보장할 수 없다는 것입니다. 그렇다면 계약이 사용 중인 이후에는 계약을 업데이트할 수 없다는 말인가요?
실제로 해결 방법이 있습니다. 예를 들어 ERC721-O의 원격 계약 보안 설정 메커니즘이 이 문제를 해결할 수 있습니다. 우리는 pauseMove 함수를 도입하였으며, 이는 chainId를 매개변수로 받습니다. 이 함수는 chainId 체인에서 move 기능을 잠급니다. 즉 현재 체인의 사용자는 chainId 체인으로 NFT를 보낼 수 없게 됩니다. 계약 소유자는 두 체인의 setRemote 작업이 모두 확인된 후 unPauseMove(chainId)를 호출하여 chainId 체인에 대한 move 작업을 해제함으로써 사용자가 다시 chainId 체인으로 NFT를 보낼 수 있도록 합니다.
이러한 설계를 통해 계약 소유자는 사용 중인 계약의 업데이트 문제를 처리할 수 있습니다. 우리의 예제로 돌아가면, 계약 소유자는 B 체인에서 pauseMove(A)를 호출하여 B 체인 사용자가 A 체인으로 NFT를 보낼 수 없게 하고, A 체인 사용자는 여전히 B 체인으로 NFT를 보낼 수 있게 할 수 있습니다. 이때 계약 b는 여전히 계약 a로부터 NFT를 정확히 수신할 수 있으므로, 이 시간 간격 동안 어떤 NFT도 분실되지 않습니다. 그런 다음 계약 소유자는 A 체인의 계약 a에서 pauseMove(B)를 호출하여 A 체인 사용자도 B 체인으로 NFT를 보낼 수 없게 합니다. 마찬가지로 A 체인의 계약 c에서도 pauseMove(B)를 호출해야 합니다.
이제 계약 소유자는 계약 b와 계약 c에서 setRemote 함수를 임의의 순서로 호출하여 서로를 원격 계약 주소로 설정할 수 있습니다. 마지막으로 계약 b와 계약 c에서 unpause를 호출하여 크로스체인 전송을 복구하면, A 체인의 계약 a는 계약 c로 성공적으로 교체된 것입니다.
이 설계는 다른 시나리오에도 적용할 수 있습니다. 예를 들어, A 체인에 배포되어 사용 중인 NFT가 B 체인에 배포되기를 원할 경우, 계약 소유자는 먼저 B 체인에서 원격 주소를 설정해야 하며, 그렇지 않으면 NFT가 막힐 수 있습니다. pauseMove 기능 덕분에 계약 소유자는 먼저 pauseMove를 호출한 후 체인 A 또는 체인 B에서 상대방을 원격 계약 주소로 설정할 수 있으므로 함수 호출 순서로 인한 영향을 걱정할 필요가 없습니다.
사실 이 패턴은 ERC20과 같은 다른 유형의 토큰으로도 확장 가능하지만 여기서는 자세히 다루지 않겠습니다.
논의
· 체인 상 가스 예측을 폐지해야 하는가?
LayerZero 공식 문서는 목표 체인에서 트랜잭션 실패를 방지하기 위해 체인 상 가스 예측을 권장합니다.
하지만 실제로는 이미 공식 배포된 스마트 계약에 이 검사를 시행하고 있습니다. 게다가 여러 메시지 유형의 경우, 체인 상 가스 예측을 한다고 해도 소스 체인에서 가스 예측의 정확성을 보장할 수 없습니다. 또한 가스 예측이 잘못되더라도 비차단 설계를 갖춘 ERC721-O 계약은 이 문제를 완벽하게 처리할 수 있으므로 중대한 손실을 초래하지 않습니다.
따라서 체인 상 가스 예측을 강제하는 것은 실질적인 의미가 없어 보이며, 현재 프로토콜 버전에서 제거하였습니다.
· forceResumeReceive 함수를 제거해야 하는가?
ForceResumeRecive 기능은 자금 손실을 초래할 가능성이 큽니다. 그러나 예기치 못한 오류 메시지가 메시지 경로를 막아 성공적인 재시도가 불가능한 경우, ForceResumeRecive는 이러한 차단 상태를 해제하는 유일한 방법입니다. 비차단 설계라도 항상 메시지 경로가通畅함을 보장하지는 않는다는 점에 유의하세요. 예기치 못한 차단을 방지하기 위해 현재 구현에 유지하였습니다. 귀하의 계약이 IFG 성질(즉시 결정성)을 갖출 경우에만 이 함수를 오버라이드하여 무효화할 수 있습니다. 즉시 결정성이란 소스 체인에서 트랜잭션이 수락되면 목표 체인에서도 수락됨을 의미합니다.
차단은 사용자 경험에 해로우며 자금 손실 위험도 초래할 수 있습니다. 따라서 우리는 차단 발생 가능성을 최소화하고자 합니다. NFT 크로스체인 작업에서 거래 순서가 중요하지 않다는 점을 이용해 비차단 메커니즘을 활용하여 예기치 못한 오류/예외적인 전송 후에도 메시지 경로가通畅함을 보장할 수 있습니다. 원격 주소 검사를 통과한 후 항상 올바르게 실행됨을 보장할 수 있다면 비차단 메커니즘 부분을 제거할 수 있습니다.
ERC721-O는 여전히 커뮤니티의 공동 건설이 필요한 열린 새로운 표준입니다. 우리는 커뮤니티의 기여를 통해 ERC721-O가 풀체인 NFT의 표준 프로토콜이 되리라 믿습니다.
위 모든 결론은 LayerZero 연구소의 오픈소스 문서와 오픈소스 코드, 그리고 LayerZero 공식 노드에서의 실험에서 나온 것입니다. 오류를 발견하시면 댓글을 달거나 Github에서 이슈를 제기해 주시기 바랍니다. 읽어주셔서 감사합니다!
* 참고: 본문에서 비교 기준으로Gh0stly Gh0sts 구현과 공식예제를 사용하였습니다.
TechFlow 공식 커뮤니티에 오신 것을 환영합니다
Telegram 구독 그룹:https://t.me/TechFlowDaily
트위터 공식 계정:https://x.com/TechFlowPost
트위터 영어 계정:https://x.com/BlockFlow_News















