이더리움 블록체인 상에서 수많은 자산들이 발행되고 거래된다. 이더리움의 네이티브 토큰인 ETH, ICO를 통해 발행된 ERC-20 토큰들, 크림토키티로 대표되는 ERC-721 NFT 토큰들이 대표적이다.
그런데 이러한 자산들은 실제로 어디에 저장될까?
이더리움은 계정 모델(account model)을 채택하였기 때문에 모든 상태(state)는 계정에 저장된다. 이더리움 계정은 크게 EOA(Externally Owned Account)와 Contract Account로 나뉘는데, 각 계정은 nonce, balance, storageRoot, codeHash 네 개의 필드를 가진다. 이 중 balance 필드에 해당 계정의 ETH가 저장되어 있다. 즉, 계정 주소만 알면 이더리움의 상태 값을 읽어 ETH 잔고를 확인할 수 있다는 뜻이다.
그런데 왜 ETH만 확인 가능할까? 내 이더리움 지갑에는 OMG나 REP 같은 ERC-20 토큰들도 보이고, 내가 키우고 있는 크립토키티 고양이도 보이는데 말이다. 크립토키티 소스 코드인 KittyCore를 보면 보면 내 고양이가 어디에 있는지 확인할 수 있다.
/// @dev A mapping from cat IDs to the address that owns them. All cats have
/// some valid owner address, even gen0 cats are created with a non-zero owner.
mapping (uint256 => address) public kittyIndexToOwner;
kittyIndexToOwner은 고양이 ID를 키로 고양이 주인을 돌려주는 매핑이다. 지갑에서 보이는 것처럼 내 고양이가 내 계정에 있는 것이 아니라 크립트키티 스마트 컨트랙의 kittyIndexToOwner 매핑에만 존재함을 알 수 있다.
ETH와 다른 자산들 사이의 차이점은 이더리움 트랜잭션을 통해서도 확인할 수 있다. ETH를 보내거나 스마트 컨트랙을 호출하는 이더리움 트랜잭션에는 value 필드가 있다. value는 트랜잭션을 호출할 때 얼마 만큼의 ETH를 보낼 것인지를 결정한다. 스마트 컨트랙 내에서는 msg.value 값을 이용하여 트랜잭션을 통해 보내는 ETH 양을 확인할 수 있다.
내 고양이를 누군가한테 선물할 때는 어떨까? 아무리 찾아봐도 이더리움 트랜잭션에 고양이를 지정할 수 있는 필드는 없다. 고양이를 양도하기 위해서는 크립토키티의 transfer 함수를 호출해야 하는데, 크립토키티 소스 코드를 보면 고양이를 실제로 주고 받는 게 아니라 그저 kittyIndexToOwner 값을 바꿀 뿐이다.
/// @dev Assigns ownership of a specific Kitty to an address.
function _transfer(address _from, address _to, uint256 _tokenId) internal {
… // stuff
// transfer ownership
kittyIndexToOwner[_tokenId] = _to;
… // more stuff
}
이더리움은 오직 ETH만 자산으로 취급하고, 이더리움 위에서 발행된 다른 자산들은 단순히 스마트 컨트랙 스토리지에 저장된 값으로 취급한다. 이더리움 사용자들이 ERC-20이나 ERC-721 등의 인터페이스를 정의하고 이러한 값들을 자산으로 인정하고 있지만 스마트 컨트랙 개발자 입장에서 ERC-20 토큰이나 크립토키티 고양이는 그저 스마트 컨트랙 스토리지에 저장된 하나의 값일 뿐이다.
ETH와 같은 자산을 First-class 자산이라 부르는데, First-class 자산은 임의로 찍어내거나 삭제할 수 없는 등 여러 면에서 보호 장치를 제공받는다. 스마트 컨트랙을 잘못 짜더라도 ETH가 늘어나거나 줄어들게 만들 수 없는 이유도 여기에 있다. 이더리움은 ETH외에는 커스텀한 First-class 자산을 만들 수 없는 체인이라고 볼 수 있고, 이더리움의 스마트 컨트랙에서 발견되는 수많은 치명적인 버그들이 이더리움의 이러한 특성과 무관하지 않다.
이더리움 이후에 나온 대부분의 계정 모델 기반의 체인들이 이더리움과 비슷한 실수를 반복하고 있다. 물론 자산 발행과 거래가 주된 목적이 아닌 체인의 경우 First-class 자산을 지원하지 않는 것이 큰 결점이 아닐 수도 있지만, 블록체인의 가장 큰 어플리케이션 중 하나가 자산 발행이라는 점을 생각하면 이러한 실수가 반복되는 것은 안타깝다.
참고로 코드체인은 UTXO 기반이라 코드체인 상에서 발행되는 모든 자산들이 First-class이다.