Coinbase Rosetta
CoinMarketCap은 현재 약 2800개 암호화폐를 보여준다. 거래소나 크립토 통계 사이트는 여러 암호화폐를 다루어야 한다. 대부분 (약 1600개) ERC20과 같이 표준적인 방식으로 처리할 수 있고, 다행히도 DeFi는 이 경우에 해당한다. 그러나 여전히 동작 방식이 제각각인 1000개가 넘는 암호화폐를 처리할 전문가를 확보하기란 불가능하다. 그래서 BitGo나 Binance Cloud 혹은 전문 API 서비스를 많이들 사용한다. 여기에 Coinbase가 지난달 Rosetta란 도전장을 내밀었다.

로제타석은 기원전 196년에 만든 비석이다. 동일한 내용을 이집트 상형문자와 이집트 민중문자와 고대 그리스어 이렇게 세가지 언어로 기록해서 후대 사람들이 상형문자를 해독하는데 큰 도움을 주었다. IT 세상에서는 프린터 같은 기기나 데이터베이스 같은 소프트웨어에 공통된 인터페이스를 제공하여 다양성에서 오는 불편함을 해소한다.
Rosetta의 표어는 “Build Once. Integrate Your Blockchain Everywhere.”이다. 거래소와 지갑으로 유명한 Coinbase가 만든 Rosetta도 블록체인계의 공통 인터페이스로 기대받고 있다. 한편으로 블록체인은 합의 방식과 잔액 표현 등이 서로 다르고 스마트 컨트랙트와 샤딩 등 기능을 또 제각기 다른 방식으로 구현하기 때문에 Rosetta가 이 숙제를 어떻게 풀지 염려가 되기도 한다.
Rosetta는 크게 데이터를 읽는 Data API와 트랜잭션을 만드는 Construction API로 나뉘고, 웹(OpenAPI 3.0)으로 API에 접근할 수 있다. Data API를 먼저 살펴보자.
/network/list - 블록체인 네트워크를 나타내는
network_identifier목록을 조회한다. 만약 샤딩을 사용한다면, 각각 샤딩을 sub network으로 반환한다./network/options - 앞에서 조회한 특정 네트워크가 어떤 기능을 지원하는지 알아본다. 버전과 네트워크가 지원하는 명령(
operation)과 에러 목록 등을 반환한다./network/status - 앞에서 조회한 특정 네트워크의 최신 블록과 친구 노드 목록을 반환한다.
/block - 앞에서 조회한 특정 네트워크/블록을 가지고 해당 블록 내용을 알아본다. 여기에는
transaction_identifier(보통 트랜잭션 해시) 목록도 포함된다./block/transaction - 앞에서 조회한 특정 네트워크/블록/트랜잭션을 가지고 트랜잭션 내용을 알아본다. 명령(
operation)은 송금, 스마트컨트랙트 호출, 수수료 등 트랜잭션이 하는 일을 추상화한다. 여러 명령이 모여서 한 트랜잭션을 이룬다. 트랜잭션 내용에서 중요한 부분은 계좌의 잔액 변동이다. UTXO 모델을 사용하는 블록체인에게 편하도록 잔액 절대값 대신 잔액이 얼마만큼 늘거나 줄었는지만 기록한다. (잔액 절대값을 쉽게 파악할 수 있다면metadata항목에 추가로 기록해도 무방하다.) 스마트컨트랙트에서 어떤 작업을 수행했는지 구체적으로 기록할 필요는 없지만, 최소한 스마트컨트랙트 수행 결과 잔액이 어떻게 변했는지 알려주어야 한다./account/balance - 앞에서 조회한 특정 네트워크/블록/계정을 가지고 계정의 잔액을 알아본다. stacking이나 vesting과 같이 특별한 형태의 잔액을 표현하기위해 sub account란 개념을 사용한다. 예를 들어, 계정이 얼마를 스테이킹하면 본계정에서 stacking sub account로 해당 금액을 옮기는 식으로 표현한다.
/mempool - 아직 블록에 포함되지 않은
transaction_identifier목록을 조회한다./mempool/transaction - 앞에서 조회한 트랜잭션을 가지고 트랜잭션 내용을 조회한다.
어떻게 생겼는지 보여주려는 /block/transcation 요청과 응답 예
{
"network_identifier": {
"blockchain": "bitcoin",
"network": "mainnet",
"sub_network_identifier": {
"network": "shard 1",
"metadata": {
"producer": "0x52bc44d537…"
}
}
},
"block_identifier": {
"index": 1123941,
"hash": "0x1f2cc6c502…"
},
"transaction_identifier": {
"hash": "0x2f23fd8cca…"
}
}
응답
{
"transaction": {
"transaction_identifier": {
"hash": "0x2f23fd8cca…"
},
"operations": [
{
"operation_identifier": {
"index": 1,
"network_index": 0
},
"related_operations": [
{
"index": 0,
"operation_identifier": {
"index": 0
}
}
],
"type": "Transfer",
"status": "Reverted",
"account": {
"address": "0x3a065000ab…",
"sub_account": {
"address": "0x6b175474e8…",
"metadata": {}
},
"metadata": {}
},
"amount": {
"value": "1238089899992",
"currency": {
"symbol": "BTC",
"decimals": 8,
"metadata": {
"Issuer": "Satoshi"
}
},
"metadata": {}
},
"metadata": {
"asm": "304502201f…",
"hex": "4830450220…"
}
}
],
"metadata": {
"size": 12378,
"lockTime": 1582272577
}
}
}
현재 Go 언어 SDK를 제공한다. SDK는 Data API를 기반으로 몇가지 편의기능을 제공한다. 예를 들어, fetcher와 syncer 모듈을 사용하면, 자동으로 포크(reorg)를 처리하며 병렬로 블록 정보를 가져온다. 블록 익스플로러를 만들 때 수고를 덜 수 있다. 자동 테스트 기능도 제공한다. 앞으로 JavaScript/TypeScript SDK도 공개할 예정이라고 한다. rosetta-cli 명령어를 사용하면 코딩 없이 정보를 조회할 수 있다.
Construction API는 트랜잭션을 만든다. 많은 부분 오프라인 상태로 사용할 수 있다. 블록체인에 따라 트랜잭션과 명령(operation) 형식이 다르기 때문에 Data API로 조회한 트랜잭션 내용을 조금 수정해서 새로운 트랜잭션을 만드는 경우가 일반적이다.
/construction/derive - 공개키를 가지고 주소를 만든다.
/construction/preprocess, /construct/metadata - 트랜잭션을 만들고, 트랜잭션을 완성하는데 필요한 부가 정보(예, 이더리움 트랜잭션 nonce)를 온라인 상태에서 조회한다.
/construction/payloads, /construct/combine - 트랜잭션을 만들고, 서명을 받아서 온전한 트랜잭션을 만든다.
/construction/parse - 디버깅 용도로 트랜잭션 상세 정보를 확인한다.
/construction/hash - 트랜잭션을 가지고 트랜잭션 해시를 만든다.
/construction/submit - 온라인 상태에서 네트워크로 트랜잭션을 보낸다.
장황해 보이기도 하지만, 여러 암호화폐를 취급하는 지갑을 개발하기위한 설계로 보인다.
현재 Rosetta 인터페이스를 작업하고 있거나 혹은 완료한 프로젝트는 Celo, Near, Oasis, Coda, Ontology, Kadena, Handshake, Blockstack, Sia, Oasis Network, IoTeX, Decred 등이 있다. 한 블록체인에 대해 여러 프로그래밍 언어로 여러 구현체가 나올 수 있다. Rosetta 인터페이스를 서비스하도록 1) 직접 노드에 개발을 하거나 2) 노드 변경 없이 중간에 미들웨어를 둘 수 있다. 제작사는 직접 노드에 개발하고 독자적으로 실행할 수 있는 도커(Docker) 이미지로 제공하는 편을 권장한다. 현재는 코인베이스 상장시 요구사항이 아니다.
