티스토리 뷰

1. 들어가기에 앞서

  1. 이 글은 리플 공식 개발자 가이드 를 보고 제가 직접 간단한 코드를 만들어보면서 작성하였음을 알려드립니다.
  2. 이 글에서는 기술로써의 리플(ripple)과 코인으로써의 리플(XRP)이라는 단어를 혼용해서 사용합니다. 혼용 중 헷갈리더라도 너그럽게 이해해주세요.
  3. 저는 장난식으로 썼지만 제가 참고한 공식 개발 사이트는 엄격근엄진지합니다. 오해 없으시길 바랍니다.

2. 이 글의 범위

  • 리플을 이용한 프로그램 개발할 때 필요한 간략한 소개
  • rippled(아래에 설명) 서버 설치 및 실행(Hello world)

3. 참고자료

4. 리플(ripple)은 무엇인가

Ripple은 간단하게 말하면 SWIFT(은행간 송금시스템)망을 대체할 블록체인 송금 기술입니다. 여기에 쓰이는 코인을 XRP라고 부르며 최근 가격이 어마어마하게 뛰었습니다. 리또속이라는 말은 옛말이 된 지 오래입니다.

5. 리플을 직접 써볼까

물론 리플이라는 걸 직접 사용해보고 싶은 변태들 사람들이 있을겁니다. 저도 그래서 리플을 써보는 겸 해서 글을 작성하게 되었습니다.

6. rippled??

XRP(이하 리플)은 중앙집중형 코인이며, 이를 사용하기 위해서는 rippled에 액세스하는 방법을 사용해야만 합니다. rippled는 XRP 원장을 담당하는 P2P 코어 서버를 의미합니다. 각각의 rippled 는 다른 rippled와 통신하여 리플의 전체 원장을 로컬 카피를 만들어 공유합니다. rippled는 C++로 작성되어있고 github에 다 나와있습니다.

7. 리플 서버에 접속하기 위해서는…

rippled(이하 리플 서버)에 접속하기 위해서는 Websocket 혹은 JSON-RPC API를 사용해야 합니다. 귀찮다 싶으면 node.js 혹은 웹 브라우저에서 사용 가능한 RippleAPI를 이용하시면 됩니다. node.js 프로그래머이신 분들은 RippleAPI 사용하는 게 골치 썩힐 일 없어서 좋습니다.

그리고 리플 사에서는 Websocket을 사용하는 것을 권장합니다. 웹소켓의 푸시 패러다임이 낮은 지연에 네트워크 오버헤드가 적다고 하네요.

또한 rippled 커맨드라인을 사용해도 되는데 이건 관리용이니까 API로는 쓰지 말라고 합니다.

8. API 문의

여기다 해달래요. https://groups.google.com/forum/#!forum/ripple-server

9. rippled에 접속하기

자체적으로 rippled를 구축하거나 외부 rippled 서버에 연결해볼 수 있습니다. 9장에서는 외부 rippled 서버에 접속하는 걸 예제로 해보겠습니다.

9.1. WebSocket API를 통한 연결

Ripple WebSocketAPI Tool 을 이용하여 간단하게 확인해볼 수 있습니다. 또한 설치한 리플 서버에 접속하려면 브라우저에 설치된 클라이언트 혹은 npm 라이브러리 를 이용하세요.

9.1.1. 요청 포맷

rippled 서버와의 소켓을 열었다면 JSON으로 명령을 쏘시면 됩니다.

  • 최상위 레벨의 "command"에는 명령을 입력합니다.
  • 각종 명령에 관계된 파라미터 역시 최상위 레벨에 넣습니다.
  • 선택 옵션으로 최상위 필드에 id를 넣으면 정신없이 요청이 수행되는 와중에 무엇을 실행했는 지 알 수 있습니다.
    위의 웹소켓 툴에 보면 이렇게 나와있습니다.
{
  "id": 1,
  "command": "server_info"
}

쏘면 다음과 같이 응답이 옵니다.

{
  "id": 1,
  "status": "success",
  "type": "response",
  "result": {
    "info": {
      "build_version": "0.80.2",
      "complete_ledgers": "35430686-35450728",
      "fetch_pack": 71567,
      "hostid": "ALVA",
      "io_latency_ms": 1,
      "last_close": {
        "converge_time_s": 2,
        "proposers": 5
      },
      "load_factor": 1,
      "peers": 90,
      "pubkey_node": "n9KJz3Poz4HNQAtim6kpq9aBiDhZN4mAaSWNXUgBMacFfDDsMCD4",
      "server_state": "full",
      "state_accounting": {
        "connected": {
          "duration_us": "228412277",
          "transitions": 1
        },
        "disconnected": {
          "duration_us": "1169297",
          "transitions": 1
        },
        "full": {
          "duration_us": "4679313222",
          "transitions": 2
        },
        "syncing": {
          "duration_us": "10647950",
          "transitions": 2
        },
        "tracking": {
          "duration_us": "13984",
          "transitions": 2
        }
      },
      "uptime": 4920,
      "validated_ledger": {
        "age": 3,
        "base_fee_xrp": 0.00001,
        "hash": "93F0C24DE3BA8C2678DD24A6F4D4661B151FACB673BCF339D7582FDAA0E98BEA",
        "reserve_base_xrp": 20,
        "reserve_inc_xrp": 5,
        "seq": 35450728
      },
      "validation_quorum": 3
    }
  }
}

9.1.2. 공용 서버

리플 사의 rippled 서버 주소는 다음과 같습니다.

Domain Port Notes
s1.ripple.com 443 wss:// only; general purpose server
s2.ripple.com 443 wss:// only; full-history server

이 서버는 테스트용이니까 실제 운영하려면 자체 rippled 서버를 사용하라고 합니다.

9.1.3. 코드로 가즈아

역시 코드 한 번 짜봐야죠? 안그러면 그냥 대충 쓴 거밖에 안될테니까요. node.js 기준으로 작성하겠습니다.
먼저 npm install ws로 웹소켓 라이브러리를 설치해주세요.

const WebSocket = require('ws');

const ws = new WebSocket('wss://s1.ripple.com', {
  perMessageDeflate: false
});

ws.on('open', function() {
    console.log('connected');

    let sendData = {
        "id": Math.floor(Math.random() * 10000),
        "command": "server_info"
      };
    ws.send(JSON.stringify(sendData));
});

ws.on('message', function(data) {
    console.log(JSON.parse(data));
    ws.close();
});

직접 짠 코드라 문제를 일으킬 수도 있습니다. 이거 돌리면 요래 나옵니다.

connected
{ id: 9852,
  result:
   { info:
      { build_version: '0.80.2',
        complete_ledgers: '35407046-35451415',
        hostid: 'DEEM',
        io_latency_ms: 1,
        last_close: [Object],
        load_factor: 1,
        peers: 105,
        pubkey_node: 'n9KFUrM9FmjpnjfRbZkkYTnqHHvp2b4u1Gqts5EscbSQS2Fpgz16',
        server_state: 'full',
        state_accounting: [Object],
        uptime: 147292,
        validated_ledger: [Object],
        validation_quorum: 3 } },
  status: 'success',
  type: 'response' }

예외에 대한 핸들링은 일단 여기서는 생략하겠습니다.

9.2. JSON-RPC로 연결하기

HTTP 클라이언트를 이용하여 접속하는 방법입니다. 이건 뭐 이야기할 게 없어보이네요. 대신 몇 가지 주의하면 될 거 같습니다.

  • TLS v1.2 이상
  • Content-Type: application/json
  • "command" 대신"method" 필드에 명령 삽입
  • 다른 파라미터들은 "params" 필드 하위에 삽입

9.2.1. 공용 서버

Domain Port Notes
s1.ripple.com 51234 general purpose server
s2.ripple.com 51234 full-history server

이건 위의 websocket과 같은 설명이니 넘어갑시다.

9.2.2. POSTMAN으로 해보기

스샷은 귀찮으니 문구만 넣겠습니다.

  • URL은 https://s1.ripple.com:51234
  • Method는 POST
  • request 헤더에 Content-Type: application/json 추가
  • 데이터에는 다음과 같이 삽입
{
    "method" : "server_info"
}

그러면 결과가 날아옵니다.

{"result":{"info":{"build_version":"0.80.2","complete_ledgers":"35400189-35451562","hostid":"TOAD","io_latency_ms":1,"last_close":{"converge_time_s":1.999,"proposers":5},"load_factor":1,"peers":113,"pubkey_node":"n9MSA757umjWR9FXUoisWg4urZNW7SzaubptwhutbrbpCn46dRCy","server_state":"full","state_accounting":{"connected":{"duration_us":"168452268","transitions":16},"disconnected":{"duration_us":"1126606","transitions":1},"full":{"duration_us":"168326334224","transitions":103},"syncing":{"duration_us":"4621420632","transitions":118},"tracking":{"duration_us":"3646838","transitions":103}},"uptime":173121,"validated_ledger":{"age":0,"base_fee_xrp":1e-05,"hash":"505DF80FEA8ACE24E52FF1845E227E2A732229A76D98AF235BB2201F2D20C1B1","reserve_base_xrp":20,"reserve_inc_xrp":5,"seq":35451562},"validation_quorum":3},"status":"success"}}

Commandline에서 테스트하기는 언젠가 다시 설명하겠습니다.

10. rippled 서버 구축하기

10.1. 들어가기 앞서

정확하고 자세한 내용은 다음 링크 https://ripple.com/build/rippled-setup/에 나와있고 저는 대충 컴퓨터에 설치해서 잘 되는지만 확인해보려고 합니다.

10.2. rippled 서버의 종류

rippled 서버는 Stock, Validator, Stand-alone 이렇게 세 종류가 있습니다.

  • Stock Server - 리플 원장의 로컬 카피를 떠오는 서버입니다. 아마 이게 핵인 거 같네요
  • Validating Server(이하 Validator) - 리플 원장의 합의 절차를 수행합니다.
  • Stand-alone - 테스팅용입니다. 다른 rippled에 엑세스할 수 없습니다.
    그리고 CLI 기능도 있다고 합니다.

10.3. Stock Server를 실행해야 할 이유

알다시피 개인이 작성한 솔루션에서의 리플 거래에 대한 효율적인 통제를 위한거겠죠. 그러려고 쓰는거니까요.(번역기 돌려보니까 너가 직접 만든 게 믿고 쓸만하지 않니? 이런 느낌이더라고요. DB 서버 따로 쓰는 그런 느낌 같네요)

10.4. Validator를 실행해야 할 이유

검증은 필수잖아요.

좋은 Validator의 조건

  • 가용성(Availability): uptime 100% 가즈아
  • 협의(Agreement): 수정 없는 최신 rippled
  • 적시성(Timeliness): 언제든 투표를 빠르게 해야 함. 고성능 인터넷 망이면 좋지.
  • 확인된(Identified): 검증된 검사기라는 걸 알려줘야 신뢰가 가능하죠. 도메인 검증하세요.

현재는 리플에서 만든 5개의 검증서버 이외에는 추천 못한다고 합니다. 다른 회사의 Validator을 사용할 때에는 다음 사이트를 통해 신뢰할 수 있는지 확인해보라고 합니다. https://validators.ripple.com/

10.5. rippled 설치

개발용이면 소스코드를 컴파일하세요. <- 경고 발생합니다. 바이너리를 직접 설치합시다.

운영용이면 실행 가능한 바이너리 버전을 사용하세요. Ripple yum에 올라와있어요.

요구사항

  • OS:
    • 상용: CentOS or RHEL(최신) or Ubuntu(15.04+)
    • 개발: 맥 OSX, 윈도(64비트), 온갖 리눅스들
  • CPU: 2 Core 이상의 x64
  • RAM: 4GB 이상
  • Disk: 50GB 이상의 SSD(500 IOPS 이상). DB용을 쓰세요.

EC2를 사용하신다면 m3.large 이상 고려해보세요. Validator까지 쓰면 더 필요해요.

설치하기(Ubuntu 16.04 in Windows 10)

전 Windows 10에 내장된 Ubuntu를 기준으로 할 것이기 때문에 그 외의 OS에서 쓰고 싶은 분들은 해당 링크를 참고바랍니다.https://ripple.com/build/rippled-setup/#installing-rippled

alien으로 설치하는 방법이 있고 컴파일하여 설치하는 방법이 있습니다. alien은 ubuntu에서 rpm을 설치할 수 있게 도와주는 프로그램입니다. 컴파일 설치는 비추하는 거 같네요.

  1. yum utils과 alien을 설치한다.
$ sudo apt-get update
$ sudo apt-get install yum-utils alien
  1. Ripple RPM 저장소 등록
$ sudo rpm -Uvh https://mirrors.ripple.com/ripple-repo-el7.rpm
  1. rippled 소프트웨어 패키지 다운로드
$ yumdownloader --enablerepo=ripple-stable --releasever=el7 rippled

위 명령을 실행하면 해당 디렉터리에 rippled-*.rpm(2017-12-31 기준 0.80.2-1.fc25.x86_64) 파일이 생깁니다.

  1. rippled 시그니쳐 검증
$ sudo rpm --import https://mirrors.ripple.com/rpm/RPM-GPG-KEY-ripple-release && rpm -K rippled*.rpm
  1. rippled 설치 및 rpm 제거
$ sudo alien -i --scripts rippled*.rpm && rm rippled*.rpm
  1. startup에 rippled 등록
$ sudo systemctl enable rippled.service
  1. rippled service 시작
$ sudo systemctl start rippled.service
  1. trubleshooting
    Windows 10의 Ubuntu는 6, 7 명령이 제대로 작동하지 않습니다. 그래서 수동으로 실행시켜야 합니다. 설치된 경로는 /opt/ripple/bin/rippled 입니다.
수동 실행

이건 제 멋대로 적는겁니다. 어지간해선 하지 마세요. rippled.service 를 열어보니 다음과 같은 내용이 있습니다.
/opt/ripple/bin/rippled --net --silent --conf /etc/opt/ripple/rippled.cfg
이 명령대로 실행 시켜봅시다.

$ sudo /opt/ripple/bin/rippled --net --silent --conf /etc/opt/ripple/rippled.cfg

설치 후 해야 할 작업

서버를 키게 되면 네트워크를 통해 싱크를 맞추게 됩니다. 그 사이에 존재하지 않는 원장에 대해서 경고를 표시할 수 있습니다.

rippled 업데이트 방법

rippled Google Group을 구독하여 최신 버전으로 업데이트할 준비를 해야 합니다.

자동 업데이트

crontab에 다음과 같이 등록합니다.

RANDOM_DELAY=59
0 * * * * /opt/ripple/bin/update-rippled.sh

수동 업데이트는 가이드 문서를 참고하시기 바랍니다.

더 해야 할 것

여기까지 설치했으면 테스트용 rippled 서버 셋팅이 완료된 것입니다. 실제 운영으로 돌리기 위해서는 공식 가이드에 적힌 뒤의 설명대로 계속 진행하셔야 합니다. 여기서는 범위 밖이라 하지 않겠습니다.

11. 결론

체력의 한계로 여기까지만 적겠습니다. 제가 늘 그렇듯 리플 가이드 문서에 제 이상한 사견을 밀어넣은 괴상한 문서가 나왔습니다. 앞으로 리플이 본연의 장점을 내세워 암호화폐 시장에서 큰 입지를 차지할텐데 이 때 리플을 이용한 서드파티 프로그램을 만들 때 이 글이 조금이나마 도움이 되었으면 하는 바람입니다.

12. 2부 혹은 그 이후에서 다룰 것

2부를 쓸 지 안쓸 지 모르겠지만 2부 뒤에는 다음과 같은 내용을 넣으려고 합니다.

  • 내 지갑엔 얼마가 들어있을까? <- 2부에서 다룰 예정
  • 실전 po송금wer <- 2부에서 다룰 예정
  • 번외편, 리플의 가격은. <- 2부에서 다룰 예정
  • 리플의 메커니즘 <- 2부, 3부에 나눠서 다룰 예정
  • 간단한 쇼핑몰 느낌 내보기 <- 3부에서 다룰 예정

번외. 내 계좌 확인하기

리플 개발자 가이드 문서에 예시로 내 계좌 정보 알아보는 API를 넣어놨습니다. POSTMAN에 어떻게 넣는 지, 어떤 결과가 나오는지만 보고 마치겠습니다.

먼저 입력에 다음과 같이 넣습니다.

{
    "method": "account_info",
    "params": [
        {
            "account": "당신의 지갑주소",
            "strict": true,
            "ledger_index": "validated"
        }
    ]
}

전 제 빗썸 계정의 리플 지갑을 넣어보겠습니다. 그리고 실행하면 뭔가 결과가 나옵니다. 올바른 지갑이면 성공, 아니면 실패겠죠. 값을 보면 블록체인에 쓰이는 요소들만 보입니다. 이제 자세한 건 다음시간에 확인해 볼 생각입니다. 성질 급하신 분들은 참고자료에 써놓은 리플 부교주님의 ripplectron 코드를 보시기 바랍니다. 감사합니다.

댓글
댓글쓰기 폼