ERC-7208 온체인 데이터 컨테이너 (On-Chain Data Containers)

Final · 기타 · 2023-06-09 작성

자산 데이터의 저장과 그 데이터를 다루는 로직을 별도 컨트랙트로 분리하는 표준입니다. 같은 데이터를 여러 토큰 표준의 인터페이스로 노출할 수 있어 표준 간 호환이 쉬워집니다.

왜 필요한가

이더리움에는 토큰 표준이 많고, 같은 자산이라도 표준마다 데이터를 저장하고 다루는 방식이 다릅니다. 서로 다른 표준으로 발행된 자산끼리 교환하거나 상호작용하려면 프로토콜마다 해당 인터페이스를 일일이 지원해야 하는데, 지금까지는 프로젝트마다 제각각의 임시 해법을 만들어 생태계가 조각나 있습니다. 게다가 스마트 컨트랙트는 한번 배포하면 바꿀 수 없어서 이미 배포된 프로토콜이 새로 나온 토큰 표준에 맞추기도 어렵습니다. 데이터 저장을 로직에서 떼어 내면 저장된 데이터는 그대로 두고 로직만 바꾸거나 여러 표준으로 동시에 노출할 수 있어 표준 사이를 잇는 어댑터를 만들 공통 틀이 생깁니다.

구현해야 하는 것

심층 설명

다섯 가지 구성 요소

이 표준은 역할이 다른 다섯 요소를 정의합니다. 데이터 포인트(DP)는 온체인 데이터 구조를 가리키는 고유 식별자입니다. 데이터 오브젝트(DO)는 데이터 포인트로 색인되는 정보의 저수준 저장을 담당하는 컨트랙트입니다. 데이터 매니저(DM)는 고수준 로직과 최종 사용자 인터페이스를 구현하는 하나 이상의 컨트랙트입니다. 데이터 포인트 레지스트리(DPR)는 데이터 포인트의 발급을 관리하며 서로 호환되는 데이터 포인트의 공간을 정의합니다. 데이터 인덱스(DI)는 데이터 매니저의 데이터 오브젝트 접근을 관리하는 관문입니다. 저장(DO)과 로직(DM)을 분리하고 그 사이를 발급(DPR)과 접근 제어(DI)가 잇는 구조입니다.

데이터 포인트의 내부 구조

데이터 포인트는 반드시 bytes32 저장 단위여야 하며, 자산 데이터 자체를 담는 용도가 아니라 데이터를 색인하는 용도로 써야 합니다. 권장 구조는 앞 4바이트 접두사(타입 접두사 2바이트, 명세 버전 1바이트, 예약 1바이트), 레지스트리 내부용 32비트 식별자, 체인 ID 4바이트(필수), 마지막 20바이트는 이를 발급한 레지스트리 주소입니다. 접두사는 데이터 오브젝트가 호환성 문제를 빠르게 식별하는 데 쓰이고 레지스트리 주소 접미사는 다른 레지스트리의 데이터 포인트를 쓰려는 잘못된 트랜잭션을 빠르게 걸러내는 데 쓰입니다. bytes32 인코딩을 택한 이유는 다양한 인코딩을 수용하고 미래의 데이터 타입도 큰 수정 없이 참조할 수 있게 하기 위해서입니다.

IDataObject 인터페이스

데이터 오브젝트는 자산 데이터 저장에 쓰여야 하고 내부 구조의 색인에 데이터 포인트를 써야 합니다. 반드시 IDataObject 인터페이스를 구현해야 하며 read(dp, operation, data)와 write(dp, operation, data)는 연산 식별자(bytes4)와 연산별 데이터(bytes)를 받아 결과를 bytes로 돌려주는 범용 원시 함수입니다. setDIImplementation(dp, newImpl)은 해당 데이터 포인트의 관리 기능을 새 IDataIndex 구현에 위임하는 함수로, 데이터 오브젝트가 다른 데이터 인덱스 구현으로 관리를 옮기는 로직을 구현해야 한다는 요구와 짝을 이룹니다. 데이터 오브젝트는 단일 데이터 인덱스가 제공하는 관문 메커니즘에 따라 요청에 응답합니다.

데이터 매니저의 규칙

데이터 매니저는 비즈니스 로직을 구현하는 독립 컨트랙트입니다. 읽기는 IDataIndex.read() 또는 IDataObject.read()를 쓰면 되지만(SHOULD), 쓰기는 반드시 IDataIndex.write()를 거쳐야 합니다(MUST). 하나의 데이터 매니저가 여러 데이터 포인트를 쓸 수 있고 하나의 데이터 포인트를 여러 데이터 매니저가 공유할 수도 있습니다(MAY). 또한 데이터 포인트 레지스트리에 데이터 포인트 할당을 요청하는 로직을 구현해야 합니다(SHOULD). 같은 저장소를 공유하는 여러 데이터 매니저가 각각 다른 표준 인터페이스를 노출하는 것이 이 표준이 그리는 어댑터 구조입니다.

레지스트리와 인덱스의 역할 분담

데이터 포인트 레지스트리는 데이터 포인트의 생성, 이전, 접근 제어를 관리합니다. allocate()로 발급하고 transferOwnership()으로 소유권을 옮기며 grantAdminRole()과 revokeAdminRole()로 관리자 역할을 관리합니다. 애플리케이션 운영 중에 데이터 매니저가 새로 배포되는 경우에 유용합니다. 데이터 인덱스는 데이터 매니저가 데이터 오브젝트에 접근할 때의 관문입니다. isApprovedDataManager()로 쓰기 승인 여부를 확인하고 allowDataManager()로 승인을 관리하며 read()와 write()는 대상 데이터 오브젝트 주소를 함께 받아 요청을 전달합니다. 데이터 인덱스는 사용자별 내부 ID도 관리해야 하며 이 ID 관리 방식이 구현 간 호환 가능한 공간을 결정합니다.

수평적 데이터 이동성

데이터 매니저는 데이터 오브젝트의 저장 관리 전체를 한 데이터 인덱스 구현에서 다른 구현으로 옮길 수 있습니다. 사용자 ID 관리를 데이터 인덱스가 맡고 있으므로, 가치가 저장된 곳(데이터 오브젝트)은 건드리지 않은 채 내부 접근 제어 메커니즘만 업그레이드할 수 있습니다. 원문은 이를 수평적 데이터 이동성(Horizontal Data Mobility/Portability)이라고 부릅니다. 데이터 오브젝트가 변경 가능한 온체인 데이터를 담을 수 있어서 다른 표준 인터페이스의 정적인 저장과 달리 시간에 따라 변하는 상태를 위임 저장소에 둘 수 있다는 점도 함께 제시됩니다.

하위 호환성과 참조 구현

이 표준은 기존 토큰 표준의 기능을 보강하는 것이지 깨뜨리는 변경을 도입하지 않습니다. 이미 배포된 다른 ERC의 토큰도 감싸서 데이터 포인트로 색인하고 데이터 오브젝트로 관리한 뒤 어떤 데이터 매니저 구현으로든 노출할 수 있습니다. 다만 모든 연동은 사용 사례에 따른 호환성 분석이 필요합니다. 참조 구현은 교육용 예시로, 대체 가능 토큰과 준대체 가능 토큰 두 인터페이스가 하나의 Fungible Fractions 데이터 오브젝트로 저장소를 공유하며 어느 쪽에서 transfer()가 호출되든 두 인터페이스 모두 이벤트를 냅니다. 이 예시는 감사를 받지 않았으므로 프로덕션에서 쓰면 안 됩니다. 이 제안의 상태는 Final로 확정되었습니다.

쓸 때 주의할 점

ERC 원문 · ← ERCs