상태 변환함수를 encode하는데 쓰이는 contract를 만드는데 쓰이는 튜링 완전한 프로그래밍 언어로 된 블록체인을 제공하는 것.
● History
● Ethereum
● Applications
● Miscellanea And Concerns
● Putting It All Together: Decentralized Applications
● Conclusion
1998, Wei Dai's b-money: 컴퓨터 계산 문제를 풀면 돈이 지급되는 구조
2005, Hal Finney "reusable proofs of work"
통화는 first-to-file 어플리케이션이기에 트랜잭션의 순서가 제일 중요.
-> 탈중항화된 통화에는 탈중앙화된 consensus가 필요.
Byzantine-fault-tolerant(BFT) multiparty consensus
: 정직한 사용자가 2/3 이상이면 합의에 도달할 수 있다.
-> 공격자가 네트워크 상에서 여러 노드를 제어해 장악하려는 sybil attack의 가능성이 있다.
사토시 나카모토의 비트코인
: 매 10분마다 트랜잭션들을 합쳐 하나의 블록으로 만들어 blockchain을 만드는 노드들을 기반으로 함.
작업 증명 방식을 이용.
비트코인은 state를 변경하는 시스템이다. 이 때 state라 함은 unspent transection outputs(UTXO)을 의미한다.
APPLY(S,TX) -> S'
1. 이전 블록이 존재하고 유효한지 확인
2. 블록의 timestamp가 이전 블록 것보다 크고, 2시간 후보다 작은지 확인
3. 블록에 수행한 작업 증명이 유효한지 확인
4. S[0]가 이전 블록의 마지막 state라 하자.
5. TX = 블록체인의 트랜잭션 리스트
For all i in 0...n-1, S[i+1] = APPLY(S[i],TX[i]) 라고 하자.
If any application returns an error, exit and return false.
6. S[n]을 block의 끝에 등록하자.
작업 증명은 SHA256를 기반으로 한다.
sybil attacker들이 블록체인을 수정하는 것을 어렵게 하기 위함이다.
어떤 공격자가 27000 블록에서 100BTC를 상인에게 보내고 또다른 100BTC를 본인에게 보내는 트랜잭션을 만들려고 하면
채굴자들은 state에 없는 UTXO를 사용하려 했다는 것을 눈치챌 것이다.
따라서 공격자는 블록체인을 fork한 다음에 다른 버전의 27000번 블록을 생성해야 한다.
그런데 이 때 오리지널 블록체인의 27001번 이상의 블록들은 이 변조된 27000번을 가리키고 있지 않기에 이 블록들도 따라잡아 가장 긴 블록을 생성해야 하는데 이는 현실적으로 쉽지 않다.
leaf node에는 실제 데이터가 저장되고 parent에는 해당 데이터의 hash가 저장된다.
만약 어떤 사용자가 트랜잭션을 바꿔치기 하면 root도 바뀌게 되어 block의 hash가 바뀌어 작업 증명에 실패하게 된다.
머클 트리가 필요한 이유는 풀노드를 다운하는 것을 피하기 위함이다.
simplified payment verification(SPV)는 전체 노드를 다운할 필요 없이 블록 헤더만 다운로드하고
작업 증명을 실행하므로 데이터 저장을 효율적으로 할 수 있다.
Alternative blockchain applications
독립적인 블록체인 기반 프로토콜 vs 비트코인 기반 프로토콜
scripting
비트코인 프로토콜은 low level의 스마트 컨트랙트가 이용 가능하다.
UTXO는 public key 뿐만 아니라 script로도 획득할 수 있다.
비트코인에 구현된 스크립트 언어의 한계
이더리움의 목적은 확장성, 표준화, feature-completeness, 개발 용이성, 상호 운용성을 갖춘 합의 기반 어플리케이션을 만드는 환경을 제공하는 것.
이 목적은 이더리움 블록체인은 내장 튜링 완전 프로그래밍 언어를 제공하기 때문이다.
20바이트 주소를 가지고 있음.
account 종류
: EOA는 별도의 코드를 지니고 있지 않다.
새로운 메세지를 보내기 위해서 트랜잭션을 만들고 서명해야 한다.
이더리움에서의 메세지 는 비트코인의 트랜잭션과 유사하지만 다른 점이 3가지 있다.
이더리움 트랜잭션: EOA로부터 보내는 서명된 데이터 패키지.
STARTGAS, GASPRICE도 포함이 되어 있는데 가스비는 무한 반복 등의 오류를 예방하기 위함이다.
가스비가 떨어지면 트랜잭션은 revert된다. 가스비는 revert되지 않는다.
APPLY(S,TX) -> S' 과정
트랜잭션이 잘 작성됐고, 서명은 유효하고 nonce가 sender의 account와 일치하는지 확인하라.
STARTGAS * GASPRICE 로 트랜잭션 수수료를 계산한다. sender의 잔고에서 fee를 뺀다.
GAS=STARTGAS로 초기화하고 gas per byte의 양만큼 gas를 차감한다.
sender의 계정에서 수신자로 트랜잭션 value를 전송한다. 수신자가 contract라면 code를 돌리거나, gas가 떨어질 때까지 실행할 것이다.
만약 전송이 실해한다면, fee 빼고 나머지 state를 revert한다.
남은 모든 gas에 대한 수수료를 sender에게 돌려주고, 소모된 gas에 지불된 수수료를 채굴자에게 보낸다.
이더리움 컨트랙트는 low-level의 stack-based 바이트드 언어로 EVM code라고 부른다.
대체로 코드는 무한 루프이고 STOP이나 RETURN이라는 명령어가 있으면 counter를 증가시킨다.
데이터 저장 구조
코드 실행은 tuple(block_state, transaction, message, code, memory, stack, pc, gas) 에 의해 결정된다.
이더리움 블록체인에는 비트코인 블록체인과 달리 transection list에 더불어 최근의 state도 포함하고 있다.
block의 timestamp가 이전 블록의 그것보다는 크고, 지금 기준으로 15분 전보다는 작은지 확인
모든 상태를 저장해야 하기 때문에 비효율적으로 보일 수도 있지만 트리구조로 state가 저장되어 있어 일부만 바꾸면 되므로 효율 측면에서 크게 뒤쳐지지 않늗다.
예시
달러화, 금 등의 자산, 주식 등의 스마트 자산, 위조 불가능한 자산, 기존의 가치와 독립된 토큰 등 여러 유형의 응용이 가능하다.
토큰 시스템은 A의 토큰을 X만큼 차감하고 B에게 전달하는 한 가지의 기능만 하는 DB이다.
from = msg.sender
to = msg.data[0]
value = msg.data[1]
if contract.storage[from] >= value:
contract.storage[from] = contract.storage[from] - value
contract.storage[to] = contract.storage[to] + value
이더리움은 거래시 사용한 화폐로 거래비용을 직접 지불할 수 있다.
보통은 가격 변동성이 심한 리스크를 해결하기 위해서 자산 발행자가 보증을 서는 방식을 택한다.
그러나 이런 경우에는 자산 발행자의 신뢰도가 생각보다 낮다는 문제를 지니는데 자산 발행자 대신, 암호화 담보자산의 가치가 오를 것이라고 예상한 투자자들의 탈중앙화된 시장이 그 역할을 대신하는 것이다.
이 때 시세는 여전히 제3기관이 제공하므로 완전한 탈중앙화 시장이라고 보기에는 무리가 있다.
가장 최초의 이름 등록 시스템을 제공하려 시도한 건 namecoin이었다.
예) DNS (도메인 이름)
if !contract.storage[tx.data[0]]:
contract.storage[tx.data[0]] = tx.data[1]
제일 단순한 코드는 이름을 이더리움 네트워크 속 DB에 저장하고 영구 보존하는 건데,
이외에도 이름 등록에 요구되는 함수조건이나, 이름의 owner를 판별해 수정 기능 등을 넣는 것도 가능할 것이다.
드롭박스 등의 웹 파일 저장 서비스는 비효율적이다. 전체 하드 드라이브보다 월정액으로 이용하는 서비스의 가격이 더 비싸다.
이더리움은 분산형 파일 저장 시스템을 제공할 수 있다. 개별 유저는 그들의 하드 드라이브 공간을 대여해주는 대가로 약간의 돈을 받을 수 있다.
이러한 '탈중앙화된 드롭박스 컨트랙트'는 다음과 같은 과정을 따른다.
N개의 블록마다 랜덤하게 머클트리에 인덱스를 뽑고 유저가 올린 파일에 해당하는 트리의 특정 인덱스에 대하여 이 데이터를 저장해주겠다는 주체에게 X이더를 제공한다.
이 방식은 분산 저장을 통해 제3자에 의하 도용 위험성을 0에 가깝게 낮춘다.
탈중앙화된 자율조직의 기본개념은 구성원 또는 의사결정권을 가진 주주 중 다수의 동의 하에 단체의 기금을 사용하거나 코드를 수정하는 것을 일컫는다. 기본적으로 이건 통상적인 기업이나 비영리단체에서 사용하는 법적인 장치를 그대로 따르는 것이지만, 강제화를 위해 블록체인 기술을 사용하는 것이다.
"Greedy Heaviest Observed Subtree" (GHOST)
stale 이슈로 인한 보안성 저하 문제.
블록이 생성된 후 전파되는 데 시간이 걸리기에 다른 채굴자는 시간과 자원을 낭비하는 결과를 낳을 수 있다.
hashpower가 더 클 수록 채굴과정에서 더 높은 효율성을 가져 중앙화가 될 수 있다.
GHOST는 어느 체인이 가장 긴 지 계산할 때 stale block도 포함한다.
이더리움에서는 하나의 블록을 지정하여 그 이상으 uncle을 지정해야 한다.
무제한 GHOST가 아닌 이유
비트코인은 market-base로 수수료를 자발적으로 채굴자와 송신자들 간의 수요와 공급에 의해 책정된다고 여겼다.
문제는 트랜잭션 처리는 시장에서 이일어나는 게 아니라는 점이다.
k개의 작업에 대해서 개별 작업마다 R의 보상과 C만큼의 처리 비용이 들고, N개의 채굴파워가 같은 채굴노드가 있으면
kR/N > kC 또는 R > NC일 경우에 트랜잭션을 포함하려 할 것이다.
문제점
1. 현실에서는 검증시간에 의한 블록전파 지연으로 stale block이 될 확률이 증가한다.
2. 비채굴 full node가 존재한다
3. 채굴 파워의 분포는 실제로 심각하게 불평등하게 될 수 있다.
4. 네트워크에 피해를 주는 존재들이 있고, 그들은 다른 검증노드가 지불하는 비용보다 훨씬 적은 비용이 들게 될 그런 컨트랙트들을 교묘하게 만들 수 있다.
3, 4를 해결하기 위해 floating cap을 도입한다.
blk.oplimit = floor((blk.parent.oplimit * (EMAFACTOR - 1) + floor(parent.opcount * BLK_LIMIT_FACTOR)) / EMA_FACTOR)
튜링 완전성이 무한순환에 빠뜨리는 방법으로 채굴자와 풀 노드를 마비시킬 수 있는가?
한 트랜잭션에서 최대 계산할 수 있는 단계 수를 설정함으로써 해답을 얻을 수 있다.
C0: call(C1); call(C1);
C1: call(C2); call(C2);
C2: call(C3); call(C3);
...
C49: call(C50); call(C50);
C50: (프로그램의 한 단계를 실행한 후 그 변화를 저장소에 기록한다.)
튜링 불완전성은 순환 문제에 대한 해답이 아니다.
위 코드를 누군가에게 트랜잭션을 보내면 51번 트랜잭션에서 2^50에 해당하는 contract를 보내게 된다.
이더는 가상자산들간의 효율적인 교환을 가능케 하는 매개물이고, 단위에 대한 명칭은 정해져 있다.
영구적으로 신규 발행되는 모델을 채택한 이더리움은 비트코인이 겪고 있는 '부의 집중현상'을 완화시킬 수 있다.
비트코인 채굴방식은 블록헤더에 대한 sha256 작업을 반복하는 것이다.
문제점
1. 채굴 생태계가 ASIC라는 채굴에 특화된 컴퓨터 칩에 의해 잠식 되어서, 일반 GPU로는 채굴 생태계에 참여할 수 없다.
2. 여러 지역에서 참여자들이 블록생성에 참여하는 게 아니라 중앙화된 mining pool이 제공하는 block header에 의존하게 된다.
이더리움은 1000 nonce마다 랜덤하게 생성하는 hash function에 기반으로 하여 하드웨어에 의한 이점을 없앴다.
모든 노드가 전체 블록체인을 보관해야 한다면 시간이 지날 수록 블록체인의 크기가 커져 중앙화되는 문제가 발생. 일반 사용자들은 light SPV 노드만을 사용할 것이다.
채굴자는 full node를 사용해야 한다. 중앙화 문제는 검증 프로토콜로 해결할 수 있을 것이다.
cli는 mainstream이 되기 어려우므로 "Decentralized Applications"를 만들어야 한다.