이번 포스팅에서는 코드체인의 주소 포맷에 대해 다룬다. 코드체인에는 두 가지 종류의 주소가 존재한다. 첫 번째는 PlatformAddress인데, PlatformAddress는 코드체인의 플랫폼 코인인 CCC를 소유할 수 있고 이를 트랜잭션 수수료로 지불할 수 있다. 두 번째로, AssetAddress는 코드체인에서 생성한 Asset을 소유할 수 있는 주소다. 코드체인 Asset은 비트코인의 UTXO 모델을 따르기 때문에 AssetAddress는 비트코인의 주소의 동작과 유사하다. 따라서 비트코인 주소가 어떻게 동작하는지 먼저 설명할 것이다.
Bitcoin Address
주소의 핵심 기능은 상대방에게 내 주소를 전달했을 때 해당 주소로 돈을 받을 수 있어야 한다. 비트코인의 경우 트랜잭션에 주소를 명시적으로 적는 부분이 없고 대신 트랜잭션 Output의 scriptPubKey 필드에 스크립트를 적어 소유자를 간접적으로 표시한다. 즉, 비트코인의 주소는 스크립트로 변환된다.
비트코인 코어가 지원하는 주소는 아래 3개 종류이다.
P2PKH which begin with the number 1, eg: 1BvBMSEYstWetqTFn5Au4m4GFg7xJaNVN2.
P2SH type starting with the number 3, eg: 3J98t1WpEZ73CNmQviecrnyiWrnqRhWNLy.
Bech32 type starting with bc1, eg: bc1qar0srrr7xfkvy5l643lydnw9re59gtzzwf5mdq.
P2PKH, P2SH는 비트코인의 표준 스크립트이다. 예를 들어 P2PKH의 scriptPubKey는 아래와 같다.
OP_DUP OP_HASH160
위에서 pubKeyHash를 제외하면 나머지는 정해진 상수값이다. 비트코인 주소에서 맨 앞의 “1”이 P2PKH를 의미하므로 pubKeyHash만 인코딩하면 P2PKH의 scriptPubKey를 온전히 복원할 수 있다. 실제로는 버전과 4바이트 체크섬을 포함해 인코딩한다. 버전과 체크섬은 잘못된 주소로 비트코인이 보내지는 것을 방지한다.
Bech32
Bech32는 비트코인에 새로 도입된 인코딩 포맷이다. Bech32 인코딩은 기존 주소 포맷에 비해 여러 장점을 가진다. 우선 Base58 인코딩이 아닌 Base32 인코딩을 사용한다. 알파벳 26개와 숫자 10개, 총 36개 중 서로 헷갈릴 수 있는 문자를 제외한 32개 문자만 사용한다. 하나의 주소 내에서는 대문자 혹은 소문자로 통일해서 사용하기 때문에 손으로 적거나, 키보드로 치거나, 소리내어 읽을 때 헷갈릴 여지가 적고 편리하다. QR 코드를 만들 때 alphanumeric mode를 사용하여 QR 코드가 간단하다는 장점도 있다.
Bech32는 Human-readable part(HRP)와 Data part를 구분한다. HRP는 base32로 인코딩되지 않고 값 그대로 주소 맨 앞에 나타난다. 비트코인에서는 메인넷과 테스트넷을 구분하는 용도로 사용한다. 예를 들면 메인넷 주소는 “bc”로 시작하고 테스트넷 주소는 “tb”로 시작한다.
bc1qar0srrr7xfkvy5l643lydnw9re59gtzzwf5mdq
HRP 뒤에는 Data와 위치를 구분해주는 separator “1”이 존재한다. 그 뒤에는 Data를 인코딩한 값이고 맨 마지막 6글자는 체크섬이다. 만약 HRP 혹은 데이터가 달라지면 체크섬도 달라진다. 만약 실수로 주소에 오타를 내면 체크섬 검증 과정에서 발견할 수 있다.
Ethereum Address
이더리움의 주소는 비교적 간단하다. 공개키를 KECCAK256 해시를 돌린 결과에서 160-bit를 떼어낸 값을 주소로 사용한다. 이더리움은 대소문자를 이용한 체크섬 방식을 사용하고 있다. 하지만 사용자 편의상의 이유로 체크섬 검증을 하지 않는 지갑과 거래소들이 많다. 대신 identicon 같은 그림을 보여주긴 하지만 사람이 직접 확인하는 용도이기 때문에 무시될 수 있다. 이는 잘못된 주소 사용을 방지하는데 효과적이지 않다.
CodeChain Address Formats
앞서 언급했듯이, 코드체인은 PlatformAddress와 AssetAddress 두 가지 종류의 주소가 있다. 두 주소 모두 Bech32에서 separator “1”을 제거한 형태를 사용한다.
CodeChain Platform Address
PlatformAddress는 Account 모델에 쓰이는 주소다. 코드체인에서 Account는 마이닝하거나, CCC를 주고 받거나, 트랜잭션을 보낼 때 사용된다.
메인넷 주소는 “ccc”로 시작하고 Corgi 테스트넷 주소는 “wcc”로 시작한다. 버전과 Account ID를 Data part로 인코딩한다. 버전은 미래에 기능 추가를 위해 남겨둔 필드이고 현재 1만 존재한다. Account ID는 공개키를 BLAKE160 해시를 돌려서 나오는 값이다. 이더리움 주소와 비교해서 메인넷/테스트넷 구분이 가능하고 체크섬이 존재하기 때문에 잘못된 주소 사용을 방지할 수 있는 장점이 있다.
PlatformAddress의 예제를 보자.
PlatformAddress의 예
위의 주소는 “ccc”, “qr5…yeq”, “jjd6g0” 세 부분으로 나눌 수 있다. “ccc”는 Bech32의 HRP이다. 앞의 두 글자 “cc”는 네트워크 아이디를 나타내고 세 번째 글자인 “c”는 이 주소가 PlatformAddress임을 의미한다. “qr5…yeq”는 버전과 Account ID를 인코딩한 값이다. 주소의 마지막 6개 문자 “jjd6g0”은 체크섬이다. HRP와 체크섬은 검증 이후로는 쓰이지 않는다. 코드체인 내부적으로는 Account ID만 사용한다.
CodeChain Asset Address
AssetAddress는 UTXO 모델에서 쓰이는 주소다. 코드체인에서 생성한 Asset을 주고 받을 때 사용된다. 비트코인에서는 트랜잭션 Output에 scriptPubKey로 소유자를 표시하고, 코드체인에서는 AssetTransfer 트랜잭션의 Output에 lockScriptHash와 parameters 필드로 소유자를 표시한다. 코드체인의 표준 스크립트는 항상 같은 lockScriptHash를 가진다. 코드체인의 P2PKH는 아래와 같다.
AssetAddress의 메인넷 주소는 “cca”로 시작한다. Corgi 테스트넷의 경우 “wca”로 시작한다.
AssetAddress의 예제를 보자.
PlatformAddress와 마찬가지로 “cca”, “qyq…0es”, “s3h5m2” 부분으로 나눌 수 있다. 체크섬은 PlatformAddress와 동일하다. HRP는 앞의 두 글자는 네트워크 아이디이고 세 번째 문자는 “a”이어야 한다. “qyq…0es”은 버전과 타입, 페이로드를 인코딩한 값이다. 버전은 현재 1만 존재한다. 타입은 0~2까지 세 종류가 있다. 타입 1과 타입2는 각각 P2PKH, P2PKHBurn을 나타낸다. 타입 1의 경우 lockScriptHash는 0x5f5960… 인 고정값이고 페이로드가 pubKeyHash로서 parameters의 첫 번째 인자가 된다. 타입 0은 parameters가 비어있고 lockScriptHash만 지정할 때 사용하는 주소 타입이다. 이 경우 페이로드는 lockScriptHash 값이 된다. 타입 0 주소를 이용해 표준 스크립트가 아닌 경우에도 주소를 만들 수 있다.
결론
코드체인에서는 사용되는 주소인 PlatformAddress와 AssetAddress에 대해서 살펴보았다. PlatformAddress는 내부적으로 Account ID로 변환되고, AssetAddress는 내부적으로 lockScriptHash와 parameters로 변환된다. 두 주소 모두 Bech32를 일부 변형하여 사용하고 있다. 주소의 앞 부분만 보고 메인넷인지 테스트넷인지, PlatformAddress인지 AssetAddress인지 구분할 수 있으며 뒷 부분에 체크섬이 있어서 실수로 주소의 어떤 글자가 의도치않게 바뀌더라도 이를 감지할 수 있다.