1 History
Introduction to Bitcoin and Existing Concepts
2009년 나카모토 사토시는 공개키 암호를 통한 coin의 소유권 관리할 수 있는 최초의 실용적인 분산 화폐를 만들었다. 이미 확립된 기본 요소와 "작업 증명"이라고 알려진 coin 소유자를 추적하기 위한 합의 알고리즘을 결합했다.
Pow는 두가지 문제를 동시에 해결했다
- 효과적인 합의 알고리즘
- 간단하고 적당히 효과적인 합의 알고리즘을 제공하여 네트워크의 노드가 비트코인 원장 상태에 대한 일련의 업데이트에 대해 집단적으로 합의할 수 있도록 했다.
- 합의결정권에 대한 정치적 문제를 해결
- 합의 과정에 자유롭게 진입할 수 있는 장치를 마련하여 합의 과정에 누가 영향을 미칠지를 결정하는 정치적 문제를 해결 하는 동시에 Sybil 공격을 방지함
- 각 노드의 결정권의 크기를 그 노드의 계산능력에 직접적으로 비례시키는 방식으로 대체함
POW와 POS
- 합의 투표 과정에서 단일 노드의 가중치는 노드의 컴퓨팅 능력에 정비례한다.
- 그 이후로, 노드 가중치를 컴퓨팅 능력이 아닌 통화 보유량에 비례하는 것으로 계산하는 지분 증명이라고 불리는 대체 접근법이 제안되었다.
Bitcoin As A State Transition System
-
비트코인과 같은 암호화 화폐의 장부는 하나의 상태 변환 시스템(state transition system)으로 생각해볼 수 있다
-
상태
- 현재 모든 비트코인의 소유권 현황으로 이루어진 하나의 상태
- 아직 사용되지 않은 코인(UTXO)들의 집합
- 각 UTXO는 액면금액과 소유자가 있다.
- 소유자: 20byte 의 주소로 정의되는 암호화된 공개키
-
거래
- 거래는 하나 이상의 입력을 포함한다
- 각 입력은 현재 사용되는 UTXO와 소유자의 주소와 관련된 개인 키에 의해 생성된 암호화 서명을 포함한다.
- 각 출력은 상태에 추가될 새로운 UTXO들이다.
-
상태 변환 함수
-
상태와 거래를 가지고 그 결과 새로운 상태를 출력하는 함수
-
각 입력에는 보내는 쪽 지갑주소에서 선택된 기존 UTXO 에 대한 참조정보와, 해당지갑주소에 대응되는 개인키(private key)가 생성한 암호화된 서명을 담고 있다.
-
각 출력들은 상태에 추가될 새로운 UTXO 정보를 가지고 있다.
-
APPLY(S,TX) -> S' or ERROR
APPLY({ Alice: $50, Bob: $50 },"send $20 from Alice to Bob") = { Alice: $30, Bob: $70 }
-
비트코인 거래
- TX의 각 입력에 대해:
- 참조된 UTXO가 S에 없다면 오류를 반환합니다. -> 존재하지 않는 코인
- 제공된 서명이 UTXO의 소유자와 일치하지 않으면 오류를 반환합니다. -> 다른 사람의 코인을 사용하지 못함
- 모든 입력 UTXO의 합계가 모든 출력 UTXO의 합보다 작으면 오류를 반환합니다.
- 모든 입력 UTXO가 제거되고 모든 출력 UTXO가 추가된 상태를 반환합니다.
비트코인 거래 예시
- 앨리스는 밥에게 11.7 BTC를 보내고싶다
- 먼저, Alice는 최소 11.7 BTC이상의 이용 가능한 UTXO들을 찾는다.
- 현실적으로, 앨리스는 정확히 액면가가 11.7 BTC인 UTXO를 얻을 수 없을 것이다;
- 그녀가 얻을 수 있는 가장 작은 UTXO들의 합은 6+4+2=12(UTXO)라고 가정하자.
- 그리고 나서 그녀는 그 세 개의 입력과 두 개의 출력으로 거래를 만든다.
- 첫 번째 출력물은 밥의 주소를 소유자로 둔 11.7 BTC이며, 두 번째 출력물은 나머지 0.3 BTC "잔돈"으로 소유자는 앨리스 자신이 될 것이다.
Mining
- 비트코인을 통해 우리는 탈중앙화 화폐 시스템을 구축하려 하고 있기 때문에 모든 사람이 거래 순서에 동의하도록 하기 위해 State Transition System과 합의 시스템을 결합할 필요가 있을 것이다.
- 비트코인의 분산된 합의 프로세스는 네트워크상의 노드들이 "블록"이라고 불리는 트랜잭션 패키지를 지속적으로 생성하려고 시도하도록 요구한다.
- 네트워크는 10분마다 대략 하나의 블록을 생성하도록 되어 있다
- 각 블록은 타임스탬프, 논스, 이전 블록(해시)과 이전 블록 이후 발생한 모든 트랜잭션의 목록으로 구성된 다.
- 시간이 지남에 따라 비트코인 원장의 최신 상태를 나타내기 위해 끊임없이 업데이트되는 "블록체인"을 만든다.
블록 유효성 검사 알고리즘
- 하나의 블록이 유효한지 아닌지를 확인하기 위한 알고리즘
- 블록에서 참조한 이전 블록이 존재하며 유효한지 확인합니다.
- 블록의 타임스탬프가 이전 블록의 타임스탬프 보다 크면서 2시간 이내인지 확인합니다.
- 블록의 작업증명이 유효한지 확인합니다.
- S[0]를 이전 블록의 끝에 있는 상태라고 하자.
- TX가 n개의 트랜잭션이 있는 블록의 트랜잭션 리스트라고 가정해 보자.
- 0...n-1의 모든 i에 대해 S[i+1] = APPLY(S[i],TX[i])
- 오류를 반환하는 경우 종료하고 false를 반환합니다.
- true를 반환하고 S[n]를 이 블록의 끝에 있는 상태로 등록합니다.
- 블록의 각 트랜잭션은 트랜잭션이 실행되기 전의 표준 상태에서 어떤 새로운 상태로 유효한 상태 전환을 제공해야 한다.
- 상태는 블록에 인코딩되지 않는다.
- 상태는 검증 노드에 의해 기억되어야한다.
- 상태는 발생 상태에서 시작하여 모든 블록의 모든 트랜잭션을 순차적으로 적용함으로써 계산될 수 있다.
POW
- POW의 조건은 256 비트의 숫자로 표현되는 각 블록의 이중-SHA256 해시가 동적으로 조정되는 target보다 반드시 작아야한다.
- 블록 생성을 전산적으로 '힘들게' 만들어 공격자가 자신들에게 유리하게 전체 블록체인을 다시 만드는 것을 막는 것이 목적이다.
- SHA256은 완전히 예측할 수 없는 유사 난수 함수로 설계되었으므로 유효한 블록을 생성하는 유일한 방법은 시행착오를 반복하여 nonce를 증가시키고 새 해시가 일치하는지 확인하는 방법밖에 없다.
- 평균적으로 10분마다 새로운 블록이 생성되도록 2016 블록마다 네트워크에 의해 target이 조절된다.
보상
- POW 작업에 대해 마이너를 보상하기 위해, 모든 블록의 마이너는 인풋없이 자신에게 25 BTC를 주는 트랜잭션을 포함시킨다.
- 이 트랜잭션을 코인베이스라고한다.
- BTC가 발행되는 유일한 메커니즘이다
- genesis 상태에는 coin이 전혀 존재하지 않았다
- 어떤 거래가 그것의 아웃풋보다 인풋이 더 높은 총액을 가지고 있다면, 그 차이는 "거래 수수료"로서 마이너에게 돌아간다.
공격자 시나리오
- 공격자는 암호학에 의해 직접적으로 보호되지 않는 비트코인 시스템의 한 부분인 거래 순서를 바꾸는 것을 목표로 함
- 일부 제품(가급적 빠른 배송 디지털 상품)과 교환하여 100 BTC를 판매점에 보냅니다.
- 제품이 배송될 때까지 기다립니다.
- 동일한 100 BTC를 자신에게 보내는 다른 트랜잭션을 생성합니다.(이중지불 시도)
- 비트코인 네트워크가, 공격자 자신에게 보내는 트랜잭션이 판매자에게 지불하는 트랜잭션보다 먼저 수행된 것으로 인식하도록 속이기
일단 (1) 단계가 실행되면, 몇 분 후에 일부 마이너는 트랜잭션을 블록(블록 번호 270000)에 포함할 것이다. 약 1시간 후, 이 블록 이후에 5개의 블록이 체인에 추가되며, 각 블록은 트랜잭션을 간접적으로 가 리키며 "confirming"한다. 이 시점에서 판매자는 결제를 확정된 것으로 받아들이고 상품을 배송할 것이다; 우리는 이것이 디지털 상품이라고 가정하고 있기 때문에 배송은 즉시 이루어진다. 이제 공격자는 100 BTC를 자신에게 보내는 또 다른 거래를 만든다. 만약 공격자가 단순히 그것을 네트워크에 브로드캐스팅한다면, 트랜잭션은 처리되지 않을 것이다; 마이너는 APPLY(S,TX)를 실행하려고 시도하고 TX가 더 이상 state에 있지 않은 UTXO를 소비한다는 것을 알 수 있기때문이다.
따라서 공격자는 다른 버전의 블록 270000을 마이닝하는 것으로 시작하여 블록 체인의 "포크"를 생성한다. 다른 버전의 블록은 부모 블록 269999를 가리키지만 위조된 트랜잭션을 포함하고 있다.이 블록 정보는 원래 것과 다르므로 작업증명(proof of work)이 다시 수행되어야 한다. 그리고 공격자의 새버전 블록 270000 은 기존 270000 과 다른 해시를 가지므로 원래 블록 270001 부터 270005 는 공격자의 블록을 가리키지 않는다. 그러므로 원래 체인과 공격자의 새로운 체인은 완전히 분리된다. 포크에서는 가장 긴 체인이 진실로 받아들여지는 규칙 있다. 그래서 올바른 마이너들은 270005 뒤에 연결할 블록을 만들 때 공격자 혼자 270000블록을 작업하고 있을 것이다. 공격자가 자신의 체인을 가장 길게 만들기 위해선 그는 나머지 노드들의 컴퓨팅 파워를 합친 것 보다 더 많은 컴퓨팅 파워가 필요하다.("51% attack")
Merkle Tree
- 머클트리(Merkle Tree)는 블록에 포함된 거래 내역을 요약한 자료구조이다.
- Merkle 트리는 이진 트리의 일종이다.
- 머클 트리는 많은 노드로 구성된다
- 리프 노드에는 저장하고자 하는 데이터가 들어있다.
- 중간 노드는 두 자식의 해시이다.
- 루트 노드 또한 두 자식의 해시이다.
- 이 과정을 통해 다수의 데이터를 하나로 묶어 용량을 절약할 수 있다.
- SHA256 해시를 사용
용도
- 머클트리에서는 모든 거래내역들을 해시화한 머클루트를 통해 거래내역의 변동여부를 쉽게 확인할 수 있다
- 머클트리 자체가 해시로 이루어진만큼 하나의 트랜잭션 혹은 블록 내 필드값이 변조될 경우 머클루트 해시 값이 변조되는 쇄도 효과(avalanche effect)가 발생한다.
- 머클루트를 헤더에 담아 트랜잭션의 유효성을 보장한다.
- 머클 경로(Merkle path)를 제공받아 특정한 트랜잭션이 블록에 유효하게 있는 효율적인 검사가 가능하다.
- 머클트리는 모든 정보를 압축하여 간단하게 표현한 데이터로서 머클트리를 통해 데이터의 간편하고 확실한 인증이 가능하다
- 머클트리 프로토콜은 비트코인 네트워크를 장기간 지속가능하게 만드는 기초가 된다
- 모든 블록 전체를 저장하고 처리하는 비트코인 네트워크의 "풀 노드"는 2014년 4월 비트코인 네트워크에서 약 15GB의 디스크 공간을 차지하며 매월 1기가바이트 이상 커짐
- 가벼운 노드는 블록헤더를 다운로드하고 그 블록헤더에서 작업증명을 검증한다.
- 그리고 관 련 트랜잭션들에 대한 "곁가지들(branches)"만을 다운로드 한다.
- 이렇게 전체 블록체인의 매우 작은 비율만을 다운로드 함에도 불구하고 강한 안전성을 보장하면서도, 임의의 트랜잭션의 상태 및 잔고 상태를 알아낼 수 있게 한다.
구성요소
- 머클루트
- 블록이 보유하고 있는 거래 내역들의 해시값을 가장 가까운 거래내역끼리 쌍을 지어 해시화하고 쌍을 지을 수 없을 때까지 이 과정을 반복했을 때 얻게 되는 값이다.
- 이는 블록에 저장되어 있는 모든 거래의 요약본으로 해당 블록에 포함된 거래로부터 생성된 머클트리의 루트에 대한 해시정보가 담겨있다.
- 아무리가 거래가 많이 발생하여도 하나로 압축된 머클 루트의 용량은 항상 32 바이트이다
- 머클 경로
- 머클 경로(Merkle path)는 어떤 거래의 진위를 따질 때 이를 검증하는 과정이다.
- 머클루트가 주어진다면, 좀 더 쉽게 검증이 가능하다.
블록 헤더
- 블록의 "해시"는 블록 헤더의 해시이다
- 블록 헤더의 구성 요소
- 블록 내의 모든 트랜잭션을 저장하는 Merkle 트리라고 불리는 데이터 구조의 루트 해시
- 타임스탬프
- nonce
- 이전 블록의 해시
SPV
- SPV(Simple Payment Verification)
- SPV는 모든 블록체인을 다운로드 하지 않고 거래를 검증하는 간이 결제 확인 방법이다
- 라이트노드는 개별 거래에 대한 트랜잭션을 확인하 기 위한 SPV(Simple Payment Verify, 단순 지불 검증)를 사용한다.
- SPV는 라이트노드에서 거래를 검증하기 위해 풀노드에게 블록정보를 요청하여 머클트리를 통해 이 거래가 검증된 거래인지를 확인하는 방법이다.
문제점
- SPV는 풀 노드들에 정보를 요청해야만 거래를 진행할 수 있기 때문에 풀 노드에 대한 정보의 의존도가 높다.
- 풀 노드의 경우 처음부터 블록체인을 저장해왔고 최종적으로 돈이 들어 있는 계좌(UTXO)를 블록체인이 아닌 데이터베이스에 저장하기 때문에 더 빠른 속도로 처음부터 자신의 잔고를 확인할 수 있지만, SPV의 경우 다른 풀 노드에 의지하기 때문에 처음부터 제대로 된 정보를 주느냐가 문제이다.
- 악의적 노드가 끼어들게 되면 SPV로써는 구분할 수 없기 때문에 큰 문제로 이어질 수 있으며 다른 노드들이 거래를 취소를 시켜버림으로써 거래지연이 발생하게 된다
Light node
- 라이트노드는 블록체인 거래내역 중 일종의 핵심본만 저장하는 노드이다.
- 모든 블록 정보를 가지고 있지 않고, 필요한 부분만 저장한다는 특징이 있다.
- 즉 블록헤더에 있는 중요한 데이터만 보유하고 있다.
- 모든 블록정보를 가지고 있지 않기 때문에 어떤 새로운 거래 정보를 수신받았을 경우 이 거래가 정상적인지 검증할 수 없다.
- 라이트노드는 블록체인에 참여하여 거래를 수행하는 노드로, 풀노드에 거래 데이터를 요청하여 개별 거래를 검증하는 기능을 수행한다.
Scripting
- 별도의 확장없이도 비트코인 프로토콜은 낮은 수준의 "스마트 계약"의 개념을 가능하게 할 수 있다.
비트코인 Scripting의 한계
- 튜링불완전성
- 비트코인 스크립트 언어로 할 수 있는 작업이 많긴 하지만, 모든 경우의 프로그래밍을 다 지원하지는 않는다.
- 특히 while 이나 for 와 같은 순환(loop) 명령 카테고리가 빠져 있다.
- 순환 명령어를 없앤 이유는 거래 증명을 할 때 무한 순환에 빠지는 것을 막기 위해서였다
- 어떤 순환 명령이든 단순히 하위 코드를 여러 차례 if 구문과 함께 반복함으로써 구현이 가능하나 공간 비효율적
- 금액 해독 불가(VALUE-BLINDNESS)
- UTXO 스크립트만으로는 인출 액수를 세밀하게 통제할 방법이 없다.
- UTXO는 인출액 전부가 송금되거나 말거나 밖에 선택할 수가 없다.
- 상태 표현 제한
- UTXO 가 표현할 수 있는 상태는 사용되었거나 안 되거나 둘 뿐이다.
- 그렇기 때문에 이 두가지 상태 이외에 다른 어떤 내부적 상태를 가지는 다중 단계 계약이나 스크립트를 만들 수가 없다.
- 블록체인 해독 불가(BLOCKCHAIN-BLINDNESS)
2 Ethereum
- 이더리움은 스마트 컨트랙트라는 프로그램을 실행하는 오픈 소스에 기반을 둔 전 세계에 걸쳐 탈중앙화된 컴퓨팅 인프라스트럭쳐이다
- 분산 애플리케이션을 위한 플랫폼 제공
- 빠른 개발 시간
- DNS와 같은 앱은 두 줄 정도의 코드, 통화나 평판 시스템 관련 프로토콜은 스무 줄 내외의 코드로 작성 가능
- 튜링 완전 언어
- 누구든지 이 언어를 사용하여 스마트 컨트랙트, 분산 어플리케이션을 작성하여 소유권에 대한 임의의 규칙만들 수 있다.
- 트랜잭션 형식(transaction format), 상태변환 함수(state transition function) 등
- 보안
- 작고 드물게 사용되는 어플리케이션을 위한 보안을 제공
- 앱들이 이더리움이라는 하나의 거대한 플랫폼을 공유.
- 빠른 개발 시간
2.1 Account
- 이더리움에서 state는
account
라고 불리는 객체로 구성된다 - account는 20바이트 주소를 가진다
- Keccak-256을 사용하여 공개키의 해시를 계산 마지막 20바이트가 주소가된다.
- state 전환은 account 간의 직접적인 value 및 information 전송으로 이루어진다.
Account Fields
- account의 state는 4가지의 필드로 구성된다.
- nonce
- 각 트랜잭션이 한 번만 처리될 수 있도록 하기 위해 사용되는 카운터
- 외부 소유 계정 계정인 경우
이 주소에서 보낸 트랜잭션의 수
- [컨트랙트 계정](#contract account)인 경우
이 계정으로 만든 컨트랙트 생성 수
- balance
- 이 주소에 의해 소유된 Wei의 수
- codeHash(optional)
- 외부 소유 계정은 코드를 가지고 있지 않다.