Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

개발자가 설명하는 블록체인 세미나

1,215 views

Published on

"개발자가 설명하는 블록체인" 세미나

일자: 2018년 3월 10일 토요일
시간: 19시~22시 (총 3시간)
참가비: 1인당 2만 원
장소: 대전 둔산동 윙스터디
주관 및 주최: Team. Kojal

세미나 구성:
- 18:30~19시(30분) 접수
- 19~21시(2시간) 강의
- 21~22시(1시간) 질의응답 및 자유토론

강의 구성:
1. 블록체인의 근본과 핵심: Probabilistic State Machine
2. 합의(Consensus) 알고리즘: Proof Of Work를 중심으로
3. 블록체인을 적용한 프로젝트들: 비트코인, 이더리움, 리플 등 비교

강사: 김태균
- 현 대전 SBS 아카데미 컴퓨터아트학원 프로그래밍 강사
- Team. Kojal 공동대표
- 프리렌서

세미나 참가를 위한 조건:
- 일반적인 데이터베이스를 활용한 어플리케이션 개발 경험이 있어야 합니다.
- 적어도 위와 같은 경험이 있다는 가정하에 모든 설명이 시작됩니다.
- 물론 그렇지 않더라고 참여하는 것은 자유입니다.

강의 내용 설명:
- 개발자의 입장으로 블록체인에 관해서 설명합니다.
- 블록체인이 무엇이고 무엇을 해결하고자 나온 문제인지 기술적인 관점에서 설명합니다.
- 채굴(Mining)이 무엇이고 왜 그러한 과정이 필요로 하는지에 대해서 설명합니다.
- '어려운 수학 문제를 풀기 위해경쟁한다.'의 의미를 명확하게 기술적으로 설명합니다.
- 현재 나와 있는 블록체인 기반 기술에 대해서 몇 가지를 뽑아서 알아보고 비교해봅니다.

강의 전 주의 사항:
- 비트코인을 중심으로 블록체인을 설명하고, 합의 알고리즘은 POW를 중심으로 다룹니다.
- 너무 깊은 주제까지는 다루지 않습니다. 블록체인을 이해하고자 하시는 분들을 위한 세미나입니다.

Published in: Technology

개발자가 설명하는 블록체인 세미나

  1. 1. 개발자가 설명하는 블록체인 발표자: 김태균 2018.03.10 세미나
  2. 2. 지금부터 설명하는 모든 내용은 발표자가 이해한 내용이지 학계의 관점과 관련이 없습니다. 주의!
  3. 3. Part 1. 블록체인의 근본과 핵심 : Probabilistic State Machine Part 2. 합의(Consensus) 알고리즘 : Proof Of Work와 Bitcoin을 중심으로 Part 3. 여러가지 프로젝트들 : Bitcoin, Bitcoin Cash, Ethereum, Ripple, Litecoin 등 순서
  4. 4. 강의 대상 • 데이터베이스를 다루어 본 경험이 있는 개발자 • 블록체인에 대해서 알고 싶은 개발자 들어도 큰 의미 없는 사람 • 블록체인 전문가
  5. 5. 보안의 3요소 • 기밀성(Confidentiality) • 무결성(Integrity) • 가용성(Availability) 뜬금 없기는 하지만… 이 말을 언제 넣어야 할지 모르겠다..
  6. 6. Part 1. 블록체인의 근본과 핵심 : Probabilistic State Machine http://ieeexplore.ieee.org/document/7756226/ What’s So Different about Blockchain? — Blockchain is a Probabilistic State Machine
  7. 7. Database 특정 시스템의 상태를 저장하기 위한 무언가
  8. 8. 게임 실행 시 나무 18개 풀 4개 돌 2개 데이터베이스
  9. 9. 어떻게 그 상태를 내부적으로 저장하는가는 생각하지 말자. https://martinfowler.com/bliki/AggregateOrientedDatabase.html
  10. 10. State Machine http://www.oracle.com/technetwork/systems/fsm-156381.html
  11. 11. https://medium.com/@brianray_7981/tutorial-write-a-finite-state-machine-to-parse-a-custom-language-in-pure-python-1c11ade9bd43 Finite State Machine 원래 이런 거지만…
  12. 12. State 0 ( Time 0 ) State 1 ( Time 1 ) State 2 ( Time 2 ) 초기상태 변화 1 변화 2 안녕하세요 끝에 “반갑습니다” 추가 안녕하세요 반갑습니다 ‘녕’을 삭제 안하세요 반갑습니다 처리 과정이 아니라 시간에 따른 상태를 기준으로 봐 보자
  13. 13. State 0 ( Time 0 ) State 1 ( Time 1 ) 초기상태 변화 1 State 2 ( Time 2 ) 변화 2 State n-1 ( Time n-1 ) 변화 n-1 State n ( Time n ) 변화 n State n+1 ( Time n+1 ) 변화 n+1 변화 데이터베이스의 시간에 따른 상태를 표현해 보자
  14. 14. State n ( Time n ) State n+1 ( Time n+1 ) Transition n+1 Transaction 1 Transaction 2 Transaction 3 Transaction 4 Transaction 5 Transaction 6 …. User 1 User 2 User 3 User n 현재 시간 현재시간 + 주기 주기동안 발생한 변화 목록
  15. 15. State는 특정 시간에 존재한 상태를 나타낸다. Transition은 상태의 변화를 나타낸다.
  16. 16. Local Database 하나의 저장소에서 모든 데이터를 관리한다. 한 사람에 의해서 데이터과 관리된다.
  17. 17. 예) 포인트 관리 시스템 State 0 ( Time 0 ) State 1 ( Time 1 ) State 2 ( Time 2 ) 초기상태 변화 1 변화 2 김태균: 100 김태균 -> 장희성 50 김태균: 50 장희성: 50 김태균: 0 장희성: 0 김치훈: 100 김태균 -> 김치훈 50 장희성 -> 김치훈 50
  18. 18. 데이터베이스를 혼자 유지하면 생기는 문제들 • 저장고가 사고로 인해서 소실될 경우 모든 데이터가 사라진다. • 요청이 많아지면 처리를 감당하지 못한다. • 서버가 죽으면 시스템이 모두 죽어버린다. • 기타 등
  19. 19. 중앙서버 데이터1 데이터2 데이터3 한국: 사용자 한국: 사용자 한국: 사용자 미국: 사용자
  20. 20. 중앙서버 데이터1 데이터2 데이터3 한국: 사용자 한국: 사용자 한국: 사용자 미국: 사용자 지연발생
  21. 21. 해결책: 데이터베이스를 분산시켜 버린다.
  22. 22. 분산서버 데이터1 데이터2 데이터3 한국: 사용자 한국: 사용자 한국: 사용자 미국: 사용자 분산서버(미국) 데이터1 데이터2 데이터3 분산서버 데이터1 데이터2 데이터3 동기화 동기화
  23. 23. 문제해결? • 저장고가 사고로 인해서 소실될 경우 모든 데이터가 사라진다. • 요청이 많아지면 처리를 감당하지 못한다. • 서버가 죽으면 시스템이 모두 죽어버린다. 한 저장소가 없어져도 데이터는 그대로 유지된다. 다시 만들고 복구하면 된다. 필요한 부분만 각자 처리하고 나중에 동기화한다. 다른 서버에서 처리해줄 것이다.
  24. 24. 분산 데이터베이스에 반드시 필요한 것 반드시 시스템 전체 상태는 동일해야만 한다. 특정 시간, 사건에 맞춰서 동기화가 이루어져야만 한다. 그런데 그게 쉬운 일은 아니다… 모든 노드가 동일한 상태를 가지고 있다. 그런데 샤딩이면..?
  25. 25. 문제 발생 • 동기화 실패로 인한 이중처리 • 중간에 저장소(노드)를 새로 만들 시 무결성 입증이 힘들다. • 데이터가 반드시 한 기관에 의해 유지돼야 한다. (가용성은 한 기관에게만 있다.) 그냥 그럴 수 있다는 것이다.
  26. 26. 동기화 실패로 인한 이중처리 1 분산서버 데이터1 데이터2 데이터3 사용자 1 분산서버 데이터1 데이터2 데이터3 동기화 사용자 2 사용자 3
  27. 27. 동기화 실패로 인한 이중처리 1 분산서버 데이터1 데이터2 데이터3 사용자 1 분산서버 데이터1 데이터2 데이터3 동기화 사용자 2 사용자 3 나는 100원만 소유100원???? 100원????
  28. 28. 동기화 실패로 인한 이중처리 2 중앙서버 데이터1 데이터2 데이터3 사용자의 장비1 사용자의 장비2 분산서버 파일 A 분산서버 파일 A 뭘 처리해야 하는가? 사용자의 장비1 분산서버 파일 A
  29. 29. 동기화 실패로 인한 이중처리 2 중앙서버 데이터1 데이터2 데이터3 사용자의 장비1 A를 변경 A를 삭제 사용자의 장비2 분산서버 파일 A 분산서버 파일 A 뭘 처리해야 하는가? 사용자의 장비1 분산서버 파일 A
  30. 30. 동기화 실패로 인한 이중처리 2 중앙서버 데이터1 데이터2 데이터3 사용자의 장비1 A를 변경A를 삭제 사용자의 장비2 분산서버 분산서버 파일 A+ 뭘 처리해야 하는가? 사용자의 장비1 분산서버 ?????? ?????
  31. 31. 분산서버 데이터1 데이터2 데이터3 분산서버 데이터1 데이터2 데이터3 동기화 데이터 관리는 한 기관에서만 해야 한다. 가용성이 한 기관에게만 열려 있다. 분산서버 데이터1 데이터2 데이터3 동기화 분산서버 데이터1 데이터2 데이터3 동기화 엉뚱한 녀석 무결성이 파손된다.
  32. 32. 동기화가 힘든 건 둘째 치고라도 거의 무조건 한 명(기관)에 의해서 유지돼야만 한다.
  33. 33. State 0 ( Time 0 ) State 1 ( Time 1 ) 초기상태 변화 1 변화 n State n ( Time n ) 기존분산서버 데이터1 데이터2 데이터3 State 0 ( Time 0 ) State 1 ( Time 1 ) 초기상태 변화 1 변화 n State n ( Time n ) 기존분산서버 데이터1 데이터2 데이터3 초기상태 State n ( Time n ) 새로운 분산서버 데이터1 데이터2 데이터3 이게 State0가 된다. 동기화 현재 상태를 전달 받는다. 중간에 저장소를 새로 만들 시 무결성 입증이 힘들다
  34. 34. 뭐가 문제인 것일까?
  35. 35. State 0 ( Time 0 ) State 1 ( Time 1 ) 초기상태 변화 1 State 2 ( Time 2 ) 변화 2 State n-1 ( Time n-1 ) 변화 n-1 State n ( Time n ) 변화 n State n+1 ( Time n+1 ) 변화 n+1 변화 데이터베이스는 상태를 저장한다. State는 특정시간에 표현된 시스템의 상태이다. 변화는 데이터의 변경, 발생인데 이것은 Log로 처리된다. DB는 어찌됐든 현재 상태만을 알고 있으면 되는 것이다.
  36. 36. 분산이든 분산이 아니든 중요한 것은 DB는 현재 상태만을 저장한다
  37. 37. State 0 ( Time 0 ) State 1 ( Time 1 ) 초기상태 변화 1 변화 n State n ( Time n ) 기존분산서버 데이터1 데이터2 데이터3 State 0 ( Time 0 ) State 1 ( Time 1 ) 초기상태 변화 1 변화 n State n ( Time n ) 기존분산서버 데이터1 데이터2 데이터3 초기상태 State n ( Time n ) 새로운 분산서버 데이터1 데이터2 데이터3 이게 State0가 된다. 동기화 현재 상태를 전달 받는다. 왜 무결성 입증이 어려운가?
  38. 38. State 0 ( Time 0 ) State 1 ( Time 1 ) 초기상태 변화 1 State 2 ( Time 2 ) 변화 2 State n-1 ( Time n-1 ) 변화 n-1 State n ( Time n ) 변화 n State n+1 ( Time n+1 ) 변화 n+1 변화 원래 상태의 흐름 최신상태 State n ( Time n ) State n+1 ( Time n+1 ) 변화 n+1 변화 최신상태 내가 시작하는 상태 동기화 ??? + 최초상태
  39. 39. 그 노드는 전달받은 데이터가 올바르다고 믿어야만 한다. 의심했다고 해도 확인할 방법이 없다.
  40. 40. 다시 본론으로 돌아와서…. 분산 데이터베이스가 이루고자 하는 것 1.저장소가 파괴돼도 다시 복구가 가능해야 한다. 2.하나의 저장소가 꺼져도 전체 시스템은 여전히 유지된다. 3.분산처리를 통한 시스템 속도 향상
  41. 41. 1번만 좀 자세히 살펴보자. 저장소가 파괴돼도 다시 복구가 가능해야 한다. 백업을 통해서
  42. 42. 방법 1 State 0 ( Time 0 ) State 1 ( Time 2 ) 초기상태 변화 1 State 2 ( Time 2 ) 변화 2 State n-1 ( Time n-1 ) 변화 n-1 State n ( Time n ) 변화 n State n+1 ( Time n+1 ) 변화 n+1 변화 최신상태 각 상태마다 스냅샷을 찍어 놓고 저장한다. 스냅샷 1 스냅샷 2 스냅샷 n-1 스냅샷 n 복구하고 싶은 부분의 스냅샷을 불러와서 복구한다. 사실 최신 상태 스냅샷만 있으면 된다. 스냅샷 0 미래
  43. 43. 방법 2 State 0 ( Time 0 ) State 1 ( Time 2 ) 초기상태 변화 1 State 2 ( Time 2 ) 변화 2 State n-1 ( Time n-1 ) 변화 n-1 State n ( Time n ) 변화 n State n+1 ( Time n+1 ) 변화 n+1 변화 최신상태 최초의 상태와 모든 시간의 변화를 저장해 놓는다. Log 1 반드시 스냅샷 0와 시간에 따른 모든 변화과정이 필요하다. 원하는 부분까지 스냅샷0부터 재생시키면 된다. 순서가 하나라도 뒤바뀌거나 빠지면 안된다. 스냅샷 0 미래 Log 2 Log n-1 Log n 이거 완전 SVC 아니야?
  44. 44. 방법 1을 선택하면…. • 필요한 스냅샷만 저장한다면 용량문제도 해결하고 복구에 문제가 없다. • 그런데 어떻게 이렇게 됐는지 확인할 방법이 없다. • 다른 사람을 통해서 특정상태만을 받았을 때 이게 옳다고 할 근거가 없다. 방법 2을 선택하면…. • 조금 시간이 걸릴지도 모르겠지만 복구에 문제가 없다. • 젤 큰 건 용량 문제… • 모든 기록을 전부 전달 받아야만 한다. • 그래도 이게 어떠한 과정을 통해서 왔는지 알 수 있다!
  45. 45. 은행은 돈을 어떻게 옮기는가? https://brunch.co.kr/@jeffpaik/8 간단하게만 알아보자. 쉬어 가는 타임!
  46. 46. 김태균 A은행 100만원
  47. 47. 김태균 A은행 100만원 김태균 100만원 A은행은 김태균에게 100만원을 빚진 상태이다. 현금이 움직인 것이기에 어떤 문제도 없다. -100 0원
  48. 48. A은행 100만원 김태균 0원 장희성 같은 A은행을 사용하는 장희성에게 돈을 보내고 싶다.
  49. 49. A은행 50만원 김태균 장희성 50만원 50만원 A은행 내부 장부에서 총 합만 맞다면 돈을 옮겨도 문제가 발생하지 않는다. 외부에서 빌린 돈 100만원 = 내부에 있는 돈 100만원 -50 +50
  50. 50. A은행 100만원 김태균 B은행 0만원 김치훈 김태균이 다른 은행을 사용하는 김치훈에게 돈을 보내려 한다.
  51. 51. A은행 50만원 김태균 B은행 0만원 김치훈 A은행에서 돈을 차감하는 것은 쉽지만 B은행이 김치훈의 계좌에 돈을 넣어줄 의무는 없다. 50만원 -50 +50??? B은행은 김치훈에게 없던 빚이 생기는 상황이다.
  52. 52. A은행 50만원 김태균 B은행 50만원 김치훈 50만원 -50 +50 -50만원 A은행 -50 50만원 B은행 +50 A은행과 B은행간에 환거래 약정을 맺는다. 서로 간의 신뢰관계 형성
  53. 53. A은행 50만원 김태균 B은행 50만원 김치훈 50만원 -50 +50 -50만원 A은행 -50 50만원 B은행 +50 파산?! B은행이 받을 A의 빚은 어디로 가는가?
  54. 54. A은행 50만원 김태균 B은행 50만원 김치훈 중앙은행 +50만원 B은행 -50만원 A은행 1. 중앙은행의 A에서 -50차감 2. 중앙은행의 B에 +50증감 3. A은행의 김태균에서 -50차감 4. B은행의 김치훈에서 +50증감 50만원 +50 +50 -50 -50 제 3자를 통한 신뢰관계 형성 수수료가 매우 매우 비싸다
  55. 55. 그렇다면 국제은행 끼리는????
  56. 56. Society of Worldwide Interbank Financial Telecommunication 그냥 프로토콜일 뿐이다.
  57. 57. A은행 D은행 B은행 C은행 SWIFT SWIFT SWIFT
  58. 58. 단, SWIFT 네트워크 사용은 매우 비싸다. 거래 하나하나 마다 하나의 통신을 한번씩 할 수 없다. 그렇기에 거래를 모아 놓고 한번에 청산을 해야 한다.
  59. 59. 청산기구A 청산기구B A은행 B은행 C은행 A은행: 거래1 B은행: 거래1 A은행: 거래2 C은행: 거래1 A은행: 거래3 B은행: 거래2 A은행: 거래4 A은행: 거래1 B은행: 거래1 A은행: 거래2 C은행: 거래1 A은행: 거래3 B은행: 거래2 A은행: 거래4
  60. 60. 청산기구(Clearing House) 사용시 문제점 • 즉시 처리가 되지 않는다. • 언제 처리될지는 청산기구에 달려있다. • 이래도 수수료는 비싸다. • 기타 등
  61. 61. 사실 가장 문제인 것은…. 모든 기관들이 다른 DB를 사용해서 상태를 관리하고 있다.
  62. 62. 이거 정말 잘 관리 되고 있는 거 맞아? 어찌됐든 남을 믿을 수 밖에 없는 것이다.
  63. 63. 이 모든 문제를 해결하는 방법
  64. 64. 모두가 같은 분산 데이터베이스를 사용하면 된다! 말은 참 쉽다…
  65. 65. 말 그대로 無缺, 결함이 없다. 없던 돈이 생기지도 안고, 있던 돈이 없어 지지도 않는! 공학적인 정의를 들이밀지 말자! ㅠㅡㅠ ㅎ 무결
  66. 66. 누구나 접근할 수 있고, 누구나 이 데이터베이스에 데이터를 작성하고 수정하지만 무결성은 깨지지 않는 그런 데이터베이스!!
  67. 67. - 마을 - 마을 중앙 (공동금고) 이것이 의미하는 바는…. 이 말은 마을 중앙에 공동 금고를 만들고 누구나 돈을 저장할 수 있고, 누구에게나 열려 있지만 돈이 하나도 안 없어지길 바라는 것과 같다.
  68. 68. 사토시 나카모토가 꿈꾼 것은? • 누구에게도 소속되지 않은 데이터베이스 • 누구나 열람이 가능하고, 변경이 가능한 데이터베이스 • 즉, 모두가 운영하는 하나의 데이터베이스! • 언제든지 나가도 되고, 다시 참여해도 된다! • 누구에게나 공개돼도 사생활은 보호 돼야한다. • 그런데! 무결성이 파괴돼서는 안된다!!!! = 비트코인은?
  69. 69. 허걱! 그런게 가능해?
  70. 70. 문제 하나하나를 해결해가면서 블록체인을 이해해보자.
  71. 71. 주의! • 이것을 장부라고 생각하지 말자 • 이것은 상태를 유지하는 데이터베이스이다. • 이것이 어떻게 상태를 저장하는지 내부 구현에 집중하지 말자. • 문제 하나 씩에만 일단 집중하자 • 하지만 복잡해지면 장부라고 생각하자!
  72. 72. 정말 다행이도 서로 모르는 사람들이 공동 분산 데이터베이스를 유지했다고 해보자 State n ( Time n ) 기존 노드A Node: 네트워크(데이터베이스)를 참여, 유지하는 컴퓨터 State n ( Time n ) 기존 노드B State n ( Time n ) 기존 노드C
  73. 73. 여기에 새로운 노드가 참여한다. State n ( Time n ) 기존 노드A State n ( Time n ) 기존 노드B State n ( Time n ) 기존 노드C 새로운 노드 X No State 노드 X는 기존의 노드에게 현재 상태를 전달 받아야만 한다. State n ( Time n )
  74. 74. 노드 X는 기존의 노드로 부터 전달 받은 상태가 변조되지 않았다고 어떻게 믿을 수 있는가? State 0 ( Time 0 ) State 1 ( Time 2 ) 초기상태 변화 1 State 2 ( Time 2 ) 변화 2 State n-1 ( Time n-1 ) 변화 n-1 State n ( Time n ) 변화 n State n+1 ( Time n+1 ) 변화 n+1 변화 최신상태 각 상태마다 스냅샷을 찍어 놓고 저장한다. 스냅샷 1 스냅샷 2 스냅샷 n-1 스냅샷 n 스냅샷 0 미래 위의 스냅샷 중 어떤 것을 줘도 믿지 못할 것이다.
  75. 75. State 0 ( Time 0 ) State 1 ( Time 2 ) 초기상태 변화 1 State 2 ( Time 2 ) 변화 2 State n-1 ( Time n-1 ) 변화 n-1 State n ( Time n ) 변화 n State n+1 ( Time n+1 ) 변화 n+1 변화 최신 상태 최초의 상태와 모든 시간의 변화를 저장해 놓는다. Log 1 스냅샷 0 미래 Log 2 Log n-1 Log n 그렇다면 최초 상태와 변화의 기록을 모두 전달해 준다면? 그나마 쪼끔은 더 믿을 만 해졌다.
  76. 76. 상태가 아닌 상태의 변화를 모두 전달해 주는 것 그러기 위해서는….
  77. 77. 전제사항 1. State0(Genesis)는 모든 노드가 동일한 것을 가지고 있다. 2. 로그의 순서가 반드시 올바르다. 다른 노드를 통해서 받으면 안된다. 네트워크 참여 전부터 알고 있어야 한다. 이것을 어떻게 입증하지?
  78. 78. 여기서 중요한 것 아무도 믿지 마라!
  79. 79. Log 1 Log 2 Log 3 Log 4 Log 4 Log 5 Genesis 이 녀석은 반드시 올바르다. 나 한태 전달된 로그들 로그 1이 1번이라고 어떻게 믿지…? 로그 4는 왜 두 개지? 누가 진짜이지? 짜샤 여기 1번이라고 써 있잖아! 그럼 내가 1번이지! 내가 진짜임 ㅋ 전달 받은 Log의 순서가 올바른 지 어떻게 알지
  80. 80. 그런데 Log는 어떻게 구성해야 할까?
  81. 81. State n ( Time n ) State n+1 ( Time n+1 ) Transition n+1 Transaction 1 Transaction 2 Transaction 3 Transaction 4 Transaction 5 Transaction 6 …. User 1 User 2 User 3 User n 현재 시간 현재시간 + 주기 주기동안 발생한 변화 목록 Log
  82. 82. 이제부터 Log가 아니라 Block이라고 부른다. 블록의 구성: head와 body 헤드 바디 블록 No 이전 Hash Bitcoin: A Peer-to-Peer Electronic Cash System 블록 Hash Root Hash Tx 1 Tx 2 Tx 3 Tx n …. Nonce 주의: 이게 비트코인인지 이더리움인지 이런 거 생각하지 말자. Meta-data 실제 데이터 시간
  83. 83. 그런데 왜 이름이 블록(Block)인가? 상태변화를 일으키는 최소 단위인 Transaction을 뭉텅이로 담고 있어서
  84. 84. 블록안에 TX들이 올바른지 검증하기 State n ( Time n ) State n+1 ( Time n+1 ) Transition n+1 현재 시간 현재시간 + 주기 Transaction 1 Transaction 2 Transaction 3 Transaction 4 Transaction 5 Transaction 6 …. 현재 상태로부터 정상적으로 변경가능한 요청인지 확인한다.
  85. 85. 블록 No 이전 Hash 블록 Hash Root Hash Tx 1 Tx 2 Tx 3 Tx n …. Nonce • 블록은 특정 주기동안의 Tx의 집합이다. • Tx 하나하나가 상태의 변화를 나타낸다. • Tx들을 모아서 하나의 Hash를 만든다. • 이를 통해서 Tx이 하나라도 변경되면 블 록이 변조됐 음을 확인할 수 있다. • N번째 블록은 반드시 n-1의 블록Hash를 포함해야 한다. • 헤더 내의 정보를 모두 모아서 Hash를 만든다. 시간
  86. 86. 여기서 잠깐! Hash? Hash는 ‘으깬다’란 뜻이다. 그래서 해시 포테이토는 으깬 감자 원본 데이터를 으깨 버리는 것이다. 해시, 해시 등
  87. 87. Cryptography Hash functions https://www.tutorialspoint.com/cryptography/cryptography_hash_functions.htm 가변길이 데이터를 해시 함수에 통과시키면 고정길이 데이터가 나온다.
  88. 88. 결과물은 고정된 길이의 bit sequence로 나온다. 만약 4bit hash 함수라고 해보자. 이 4개의 칸에 0과 1로 채워진다. 정수로 생각해보면 0000~1111까지니까 0~15까지 총 16개의 결과가 나온다. 어떤 데이터 든 상관없이 반드시 이 4개의 비트배열로 결과가 나온다. 0001 = 01 = 0x1 1010 = 10 = 0xa 1100 = 14 = 0xe ….
  89. 89. • 같은 입력은 반드시 같은 출력이 나온다. • 입력에서 1bit라도 변경되면 출력의 모든 bit 배열이 변경된다. • 출력은 이상적으로는 모두 동일한 확률 분포를 가지고 있다. • 다른 입력일지라도 결과가 동일할 수 있 다. -> 해시충동 • 출력결과를 보고 입력 값을 알아낼 수는 없다. -> 비가역적
  90. 90. Hash 값을 통해서 원본 데이터의 변경여부와 동일한지를 파악할 수 있다. • SHA-256 Hash 함수는 출력이 256bit이다. • 총 가지수는 11579208923731619542357098500868790785326998466 5640564039457584007913129639936 이다. • 충돌이 날 경우는 거의 없다고 생각해도 좋다. • 16진수로 표현하면 총 32자
  91. 91. https://en.wikipedia.org/wiki/Merkle_Tree Merkle Hash Tree Transaction들의 Root Hash를 구하는 방법
  92. 92. State 0 또한 사실 Block이다. 블록 No 이전 Hash 블록 Hash Root Hash Tx 1 Tx 2 Tx 3 Tx n …. Nonce • 블록 No : 0번 • 이전 Hash : 0x0000000000(32자리) • 블록 Hash : 모두가 동일하게 알고 있다. • Tx들의 의미 : 초기 상태를 표현한다. • 즉, 생성의 의미 Block 0는 반드시 옳다! 시간
  93. 93. 다시 본론으로…. Log(Block)의 순서가 어떻게 맞는지 알 수 있을까? Bitcoin: A Peer-to-Peer Electronic Cash System 전달 받은 다음블록의 내용과 전블록의 Hash를 기반으로 Hash 검증 했을 때 모든 값이 옳다면 다음 블록으로 적합하다. 주의: 블록 내 tx는 반드시 옳다고 가정
  94. 94. Block 2Genesis Block 이 녀석은 반드시 올바르다. 나 한태 전달된 로그들 Block 1 Block 3 Block 4 Block 4 Block 5 순서가 올바른지 확인할 수 있게 됐다.
  95. 95. 여기서 잠깐 진짜 중요한 것!
  96. 96. n번째 상태는 0번 블록부터 재생시키면 나온다. Genesis Block Block 1 Block 2 Block n Block n+1 State 0 State 1 State 2 State n State n+1
  97. 97. Genesis Block Block 1 Block 2’ Block n Block n+1 내부 TX 변경 = 해시 값 변경 뒤부터 해시 값 불일치 모든 블록은 해시 체인화를 통해서 이전 기록을 변조 불가
  98. 98. Genesis Block Block 1 Block 2’ Block n Block n+1 변경된 Block 2’가 Block n안의 정보와 일치하려면 변경 전 Block 2와 동일한 Hash를 찾으면 된다. 확률은 1/115792089237316195423570985008687907853269984665640564039457584007913129639936
  99. 99. 블록??? 체인??? 블록체인?! 노드들이 전송하는 것은 블록이고 이 블록들은 반드시 앞뒤로 연결된다.
  100. 100. 결론적으로 블록체인은 상태가 아닌 상태의 변화를 저장하는 데이터베이스가 된다. 조금만 단순하게 생각해보자.
  101. 101. 기존의 DB와 차이점 • 순간의 상태를 저장하는 것이 아니라 상태의 변화를 저장한다. • 기존의 DB는 현재 상태만 가지고 올바르게 진행돼 왔는지를 확인 할 수 없다. 뭔가 문제가 발생하면 Log를 뒤져서 원인을 찾아야 한다. 잠깐! 그럼 SVC랑 다른 점이 뭔 데? 그것도 상태의 변화를 저장하잖아! 그건 그냥 변화과정만 있을 뿐 올바른 변화인지에 대한 기준이 없다.
  102. 102. 데이터베이스 안에 있는 상태의 변화 문제를 간단하게 만들어 보자. 상태는 돈이라고 해보자. 김태균: 10000 장희성: 0 김치훈: 0 State 0 또는 Genesis State 처음 상태가 이렇다고 해보자. 이 상태의 주인은 각각 김태균, 장희성, 김치훈 이다. 각 상태는 주인만 조작이 허락된다.
  103. 103. 김태균: 10000 장희성: 0 김치훈: 0 State 0 또는 Genesis State 김태균이 장희성에게 5000을 보내고 싶다. 이를 위해서 김태균은 Transaction을 만들어야 한다. From To Value 김태균 장희성 5000 이러한 Tx는 김태균만 만들 수 있다. 간단하게 김태균의 개인키로 서명만 하면 된다. From To Value 김태균 장희성 5000 Signature as234lkjdfsgj9
  104. 104. 여기서 잠깐! 공개키 암호화 https://en.wikipedia.org/wiki/Public-key_cryptography
  105. 105. 상태의 주인은 공개키로 표시한다. 김태균: 10000 장희성: 0 김치훈: 0 State 0 또는 Genesis State From To Value 김태균 장희성 5000 Signature as234lkjdfsgj9 여기서 김태균과 장희성은 사실 공개키 값이다. As98897asfoi3 lji4758ugdf8u 089gdfs83 이를 Account 계좌라 부를 수 있다.
  106. 106. 그렇다면 공개키를 누군가 전부 관리해야 하는 건가? 김태균: 10000 장희성: 0 김치훈: 0 State 0 또는 Genesis State As98897asfoi3 lji4758ugdf8u 089gdfs83 From To Value 김태균 누군가 5000 Signature sgdf0897sg4 김태균: 5000 장희성: 0 김치훈: 0 State 1 dsgfusdfgj4932 lji4758ugdf8u 089gdfs83 누군가: 5000 As98897asfoi3 새로운 공개키가 등장한 순간부터 상태에 반영된다.
  107. 107. 블록은 다음 상태로 변화하는 과정들을 담고 있다. Block n State n State n+1 김태균: 5000 장희성: 0 김치훈: 0 State n dsgfusdfgj4932 lji4758ugdf8u 089gdfs83 누군가: 5000 As98897asfoi3 김태균 -> 김치훈 5000 (김태균 서명) 누군가 -> 장희성 500 (누군가 서명) 누군가 -> 김치훈 1000 (김치훈 서명) 김태균: 0 장희성: 500 김치훈: 5000 State n+1 dsgfusdfgj4932 lji4758ugdf8u 089gdfs83 누군가: 4500 As98897asfoi3
  108. 108. State n ( Time n ) 노드A State n ( Time n ) 노드B State n ( Time n ) 노드C State n ( Time n ) 노드D 다음 상태로 어떻게 넘어갈 수 있을까? 현재 상태가 State n이기에 State n+1로 넘어가야 한다. 1. Tx 전파 2. 적당한 양의 tx가 쌓인다. 3. 블록으로 생성 4. 블록 전파 5. 노드들 상태 반영
  109. 109. Tx를 전파하는 과정 1. 각각의 노드들이 상태를 변화시키는 tx를 생성시킨다. 2. 생성된 tx를 자신과 연결된 노드들에게 전파(broadcast)한다. 3. 전달 받은 tx가 자신의 현재 상태를 보아 올바른지 확인한다. 4. 올바르지 않다면 버리고, 올바르다면 다른 다시 노드에게 전파시킨다. 5. Tx는 수 초안에 모든 노드에 알려진다. 6. 각각의 노드들은 전달받은 tx를 저장하는 리스트를 각각 가지고 있다. 7. 이 tx 리스트가 동일하다는 보장은 없다.
  110. 110. Block을 생성하고 전파하는 1. Tx리스트에서 각자의 기준에 따라서 선택하고 블록에 담는다. 2. 블록에 담을 수 있는 tx 수는 용량제한이 있다. (예, 비트코인 1MB) 3. 블록에 담긴 tx들의 root hash를 구한다. 4. 블록이 생성된 시간을 기록한다. 5. 바로 전 상태를 결정지은 블록의 해시를 기록한다. 6. 새로 만들어지는 블록에 적합한 해시를 찾아낸다. 7. 다른 노드들에게 블록을 전파한다.
  111. 111. 누군가 만든 새로운 블록을 전달 받으면 1. 블록안에 tx가 올바른 서명의 tx인지 확인한다. 2. Tx가 현재 상태를 기준으로 올바른 변경을 시도하는지 확인한다. 3. 만일 하나라도 틀린 것이 있다면 이 블록은 잘못된 블록이다. 그러므로 버리고, 다른 블록을 기다린다. 4. Root hash가 올바른지 확인한다. 5. 헤더 안에 값을 기준으로 블록hash 값이 적합한지 확인한다. 6. 올바르다면 이 블록안에 tx를 기준으로 현재 상태를 업데이트 시킨다.
  112. 112. 블록을 생성시킨다는 것의 의미는? • 블록은 상태를 n에서 n+1로 전환하겠다는 것이다. • 즉, 블록이 만들어지지 않으면 상태는 영원히 변하지 않는다. 그저 트랜잭션(상태변화 요청)만 있을 뿐이다. • 블록은 상태변화의 확립이다.
  113. 113. 단순히 장부라는 생각에서 벗어나자 • 게시판 DB를 생각해보자. • 모두가 참여가능한 게시판 DB이다. • 공통 분산 데이터베이스를 사용한다. • 어떻게 해결하지???
  114. 114. 사토시 나카모토가 꿈꾼 것은? • 누구에게도 소속되지 않은 데이터베이스 • 누구나 열람이 가능하고, 변경이 가능한 데이터베이스 • 즉, 모두가 운영하는 하나의 데이터베이스! • 언제든지 나가도 되고, 다시 참여해도 된다! • 누구에게나 공개돼도 사생활은 보호 되어야한다. • 그런데! 무결성이 파괴돼서는 안 된다!!!! = 비트코인은?
  115. 115. 누구나 접근할 수 있고, 누구나 이 데이터베이스에 데이터를 작성하고 수정하지만 무결성은 깨지지 않게 만들 수는 없는 것일까?
  116. 116. 블록체인 네트워크에서 발생하는 가장 큰 문제 동시에 블록이 여러 노드에서 생성됐다면 무엇을 선택해야 하는가?
  117. 117. State n ( Time n ) 노드A State n ( Time n ) 노드B State n ( Time n ) 노드C State n ( Time n ) 노드D 다음 상태로 어떻게 넘어갈 수 있을까? 현재 상태가 State n이기에 State n+1로 넘어가야 한다. • 모두 다른 tx 리스트를 갖고 있다. • 결정한 tx가 모두 다르다. • 결국 모두 다른 다음 상태를 꿈꾸고 있다.
  118. 118. Block n Block n+1 Block n-1 Block n+1 Block n+1 Block n+1 모두가 다른 꿈을 꾼다! 노드 A가 제시(Propose)한 블록 노드 B가 제시한 블록 노드 C가 제시한 블록 노드 D가 제시한 블록
  119. 119. Part 2. 합의(Consensus) 알고리즘 : Proof Of Work와 Bitcoin을 중심으로
  120. 120. 비트코인에서 돈은 어떻게 생기는가? 블록 생성에 성공하면 보상을 받는다. 헉 그러면 아무렇게나 빨리 만들면 부자 되는 거네?! 참고로 tx에 수수료를 줄 수 있다.
  121. 121. 아무나 떠들면 안된다. • 다음 블록을 만들 사람을 랜덤으로 모두가 납득하는 알고리즘으로 결정한다. • 투표로 다음 블록을 만들 사람을 결정한다. • 엄청 어려운 문제의 정답을 먼저 맞추는 사람만 블록 떠들 수 있다. 그러면 어떻게 해결해야 할까? Proof of Work
  122. 122. 블록을 만든다는 것은… • 다음 상태로 전환을 의미한다. • 그러므로 다음 상태 후보가 여러 개면 네트워크 안정도가 떨어진다. • 그러므로 아무나 정해진 사람만 떠들어야 한다.
  123. 123. 엄청 어려운 문제를 맞춘 사람만 떠들 수 있다! = 다음 상태를 제안한 수 있다. • 케익이 있다고 하자. • 3사람이 있다. • 모두가 케익을 먹고 싶어한다. • 10분에 한번씩 먹을 기회가 주어진다. • 주사위를 굴려서 1이 나온 사람만 먹을 수 있다.
  124. 124. 모두가 인정하는 블록의 조건은? 블록 No 이전 Hash 블록 Hash Root Hash Tx 1 Tx 2 Tx 3 Tx n …. Nonce 시간 • 생성시간, 블록No, 이전Hash, Root Hash는 변하지 않는다. • 여기서 변할 수 있는 것은 Nonce(Number Used Once) 뿐 • 반드시 블록 Hash값은 특정수(target, 난이도) 이하여야 한다. Hash 값은 0~ 11579208923731619542357098500868790785326998466564 0564039457584007913129639931 중에 하나다. 모두가 인정하는 특정 수 이하만 올바른 블록으로 인정한다!
  125. 125. 해시의 특성 • 입력 값 중에서 1bit라도 바뀐다면 출력 값의 완전히 바뀐다. • 완전히 확률적이란 말이다. • 어떻게 찾을 수 있는가? = 그냥 nonce값 계~~~속 바꾸면서 나올 때까지 해본다.
  126. 126. 목표 값? Bitcoin의 해시는 2^256이다. 간단하게 2^10으로 해보자. • 해시 값은 0~1023 중에 하나일 것이다. • 확률적으로 1/1024이다. • 목표 값 이하가 나와야만 한다. • 100이하 수가 나와야만 한다면 확률은 100/1024 = 9.76% • 쉽다고?
  127. 127. 115792089237316195423570985008687907853269984665640564039457584007913129639931 = 2^256 SHA-256 해시 알고리즘에서 목표 값이 1000000000000000000000000000000000000000000000 이라고 해도….. 성공할 확률은 8.63e-31 % 에….. 있기는 한가?
  128. 128. 목표 값은 어떻게 결정되는가? • 2016개의 블록마다 새로 갱신 • 2016개의 블록이 생성되는데 걸린 시간과 20160분(10분에 한 개씩 2주)의 비율을 조절하여 한 개 블록이 10분에 한 개 나올 수 있는 목표 값을 찾아낸다. • 만약 지난 2016개 동안 평균 10분이 안 결렸으면 난이도 상승 평균 10분 보다 더 오래 걸렸다면 난이도 하강 • 물론 맨 처음(block 0)에는 정해진 목표 값을 따른다.
  129. 129. 결론은 10분에 간신히 하나 나오게 만든다. 왜?! 아무나 떠들면 안 되니까!
  130. 130. 모두가 다음 상태를 제시하기 위해서 경쟁을 한다. • 블록을 찾으면 보상을 얻는다. 왜? 네트워크 상태를 갱신해 줬으니까! • 하지만 업데이트를 하기 위해서는 목표치 이하의 값을 찾아야 한다. • 확률적으로 매우 어렵다. • 찾을 때까지 값을 변경시켜가면서 시도한다. • 이것을 보고 Mining이라고 한다.
  131. 131. https://commons.wikimedia.org/wiki/File:History_of_Bitcoin_difficulty_and_mining_hardware.svg
  132. 132. Proof Of Work 본인이 한 일을 증명하는 것. 내가 다음 상태로 업데이트 하기 위해서 이렇게 엄청난 노력을 했으므로 내가 제시한 상태로 업데이트 해야 하며 나는 보상을 받을 것이다!
  133. 133. Block n Block n-1 현재 ? Block n+1 Block n+1 Block n+1 Block n+1 노드 A가 채굴 중인 블록 노드 B가 채굴 중인 블록 노드 C가 채굴 중인 블록 노드 D가 채굴 중인 블록 모두가 다른 꿈을 꾼다. 누가 성공할지는 아무도 모른다. 완전히 확률적이다. 그렇기에 다음 상태는 확률적이다. Probabilistic State Machine
  134. 134. 채굴이 진행되는 과정 1. 각 노드들은 자신만의 기준으로 tx 목록을 구성한다. 2. 목표 값에 맞는 hash 연산을 시작한다. 3. 제일 먼저 일치하는 hash 값을 찾아낸다면 모든 네트워크에 알린다. 4. 만약 다른 사람이 찾은 블록을 전달 받는 다면 현재 하던 채굴을 중단한다. 본인이 가지고 있는 전체 tx리스트에서 발견된 블록에 있는 tx를 제외시킨다. 5. 1번 부터 다시 무한 반복
  135. 135. 그런데 만약 엄청난 확률을 깨고 동시에 두개 이상이 찾아지면?! Block n Block n-1 현재 Block n+1 Block n+1 노드 A가 채굴한 블록 노드 B가 채굴한 블록 어떤 블록을 선택해야 하는가? Fork!
  136. 136. Fork 발생의 의미 • 반드시 둘 중 하나만 살아 남는다. • 두 가지 상태가 공존할 수는 없다. • 네트워크의 상태 일치도가 떨어지니 안정성이 떨어진다. • 누군가는 돈을 벌었는데 강제로 잃게 된다는 말이다. • 의욕 상실로 참여를 하지 않고, 안정성이 떨어진다.
  137. 137. 무엇을 선택해야만 하는가? • 선택은 전적으로 자유다. • 단 하나라도 먼저 이어진다면 그 블록이 정식체인이다. = 무조건 긴 체인이 정식체인(Canonical Chain) • 그러므로 먼저 이어질 만한 녀석을 고르는 게 맞다. • 결국 1초라도 먼저 온 블록을 선택한다.
  138. 138. https://www.safaribooksonline.com/library/view/mastering-bitcoin/9781491902639/ch08.html
  139. 139. https://medium.com/@preethikasireddy/eli5-what-do-we-mean-by-blockchains-are-trustless-aa420635d5f6
  140. 140. 과연 몇 번까지 분리된 체인이 유지 될까? Block n Block n-1 현재 Block n+1 Block n+1 Fork! Block n+2 Block n+2 Block n+3 Block n+3 일단 확률적으로 매우매우 힘들다. 최대 6개라 보통 본다.
  141. 141. 네트워크를 장악하려면? Block n+1 Block n+1 Block n+1 노드 A가 채굴 중인 블록 노드 B가 채굴 중인 블록 노드 C가 채굴 중인 블록 주사위를 굴려서 특정 수 아래가 나오면 게임에서 이긴다. 1초에 주사위 1번 던짐 1초에 주사위 2번 던짐 1초에 주사위 3번 던짐 1배의 이길 확률 2배의 이길 확률 3배의 이길 확률A 기준 1회의 확률은 결국 동일하지만, 많이 실행하면 이길 확률이 올라간다. 50% 장악력33% 장악력16% 장악력
  142. 142. 장악력의 의미 그러한 확률로 이길 가능성이 존재한다는 말! 주의하라! 그러한 확률로 이길 수도 있다! 반드시 이기려면 100% 확률이 필요하다.
  143. 143. 51% Hash Power • 내가 네트워크의 51%의 해시 파워를 소유한다면 • 네트워크의 51%를 장악했다는 말이다. • 내가 51% 확률로 이긴다는 말이다. • 즉, 거의 모든 게임에서 내가 이길 확률이 꾀 크다는 말이다. 내가 원하는 방향으로만 상태를 이끌 수 있다는 말이다.
  144. 144. 다음 상태를 고를 수 있다는 말의 의미는? • 내가 원하는 tx만 처리 시켜준다. • 반대로 싫은 것은 영원히 처리되지 않는다. • 수수료를 높게 부른다. • 강제로 fork를 만들어서 현재 상태를 뒤틀어 버린다.
  145. 145. 2중 지불은 가능한가? Block n Block n-1 현재 Block n+1 Block n+1 Fork! 김태균: 10000 김태균->장희성 10000 김태균->김치훈 10000 일시적으로는 가능한 것처럼 보이나 언젠가 하나는 취소된다. 결국 불가능하다.
  146. 146. 강제로 fork 만들어서 결제 취소시키기 (1) • 김태균은 네트워크 장악력이 51% 이다. • 굉장히 비싼 물건을 사려고 한다. Block n Block n-1 현재 Block n+1 김태균: 1,000,000,000 김태균->장희성 1,000,000,000 장희성은 상태가 변경된 것을 보고 물건을 줬다.
  147. 147. 강제로 fork 만들어서 결제 취소시키기 (2) • 김태균이 물건을 받고 10분 안에 멀리 도망을 갔다. • 엄청난 해시 파워로 fork를 만들었다. • 다른 블록에는 공범자 김치훈에게 보냈다. Block n Block n-1 현재 Block n+1 김태균: 1,000,000,000 김태균->장희성 1,000,000,000 Block n+1 Fork! 김태균->김치훈 1,000,000,000
  148. 148. 강제로 fork 만들어서 결제 취소시키기 (3) • 둘 중에 하나는 취소 될 것이다. • 당연히 아래 것에 힘을 준다. Block n Block n-1 현재 Block n+1 김태균: 1,000,000,000 김태균->장희성 1,000,000,000 Block n+1 Fork! 김태균->김치훈 1,000,000,000 Block n+2 • 장희성의 거래는 결국 취소 되고 말았다. • 취소 됐으므로 재시도 하려 했으나 이미 김태균의 계좌에는 한 푼도 없으므로 시도조차 하지 못했다.
  149. 149. POW는 좋은가? • 51%의 hash power를 얻지 않는 이상 네트워크는 매우 안전하다. • 쓸 때 없는 전력 낭비가 매우 심하다.
  150. 150. 그런데 이거 왜 필요한 거였지? 왜?! 아무나 떠들면 안 되니까!
  151. 151. Block n Block n+1 Block n-1 Block n+1 Block n+1 Block n+1 모두가 다른 꿈을 꾼다! 노드 A가 제시(Propose)한 블록 노드 B가 제시한 블록 노드 C가 제시한 블록 노드 D가 제시한 블록
  152. 152. 아무나 떠들면 안된다. • 다음 블록을 만들 사람을 랜덤으로 모두가 납득하는 알고리즘으로 결정한다. • 투표로 다음 블록을 만들 사람을 결정한다. • 엄청 어려운 문제의 정답을 먼저 맞추는 사람만 블록 떠들 수 있다. • 떠들 수 있는 사람이 정해져 있다.
  153. 153. 결론 블록체인에서 정말 중요한 것은 합의 알고리즘이다.
  154. 154. Part 3. 여러가지 프로젝트들 : Bitcoin, Bitcoin Cash, Ethereum, Ripple, Litecoin 등
  155. 155. 그래서 결국 하고 싶은 것은? 누구나 참여할 수 있는 분산 데이타베이스 그러나! 무결성이 파괴돼선 안돼! 데이터베이스!!! 란 말이다. 그저 장부가 아니라고!!!! 주의: 강의자의 주장입니다.
  156. 156. Bitcoin 사이버 펑크가 만든 탈중앙화 은행 시스템 이건 완전 아나키스트~ 블록체인이라는 아이디어를 제시하였다.
  157. 157. Name Coin 분산 데이터베이스라는 장점을 활용해서 DNS 시스템 구축 .bit 도매인
  158. 158. Bitcoin Cash 비트코인 프로토콜 업데이트 중에 맘에 안 들어서 코인 만들었다. 비트코인 블록 최대 크기: 1M 캐시 블록 최대 크기: 2M~8M 가변
  159. 159. Ethereum This system can be said to be a very specialized version of a cryptographically secure, transaction-based state machine. 블록체인 위에 프로그램을 올렸다.
  160. 160. Smart Contract Externally Owned Account Contract Account 공개키 암호화 인증 프로그램 코드 등록 주소만 생성 SQL의 Trigger 같은? 변수, 변수 함수(입력) { 처리처리 } 함수2(입력2) 객체를 등록하고 메서드로 실행하는 것과 같다.
  161. 161. Smart Contract Externally Owned Account Contract Account 변수, 변수 함수(입력) { 처리처리 } 함수2(입력2) 실행할 컨트랙트 주소 실행할 함수 입력 값 1, 2, 3
  162. 162. Ripple 우리가 (거의)공짜 PayPal을 만들어 주겠다. 정해진 노드만 블록을 생성해서 2초에 한번씩 거래 확립

×