코인 스토리: 비탈릭 부테린의 이더리움 백서 연구 - ⑤부; Ethereum White Paper By Vitalik Buterin
안녕하세요 오늘은 ♛ 코인 스토리, 이더리움 백서 번역 5부입니다 36 페이지 중 13-19 페이지의 내용입니다 어려운 용어들이 많이 등장하지만, 오늘 꽤 많은 분량을 번역했습니다 코드를 배우면 내용을 더 잘 이해할 거 같은 생각이 작업을 하면 할수록 드네요 많은 코인들이 신저가를 기록하고 있지만 배울수록 이 기술에 대한 신뢰가 쌓이는 거 같습니다 완전히 죽지 않는 이상 암호 세계는 하루하루 강해지고 있습니다 감사합니다 ~ ฿
- Ethereum
- Ethereum Accounts
- Messages and Transactions
- Ethereum State Transition Function
- Code Execution
- Blockchain and Mining
A NEXT GENERATION SMART CONTRACT & DECENTRALIZED
APPLICATION PLATFORM
By Vitalik Buterin
번역: @phuzion7
Ethereum Accounts
이더리움 계정
이더리움에서, 상태(state)는 “계정”이라 부르는 대상들로 구성되고, 각 계정은 20-byte 주소와 계정들 사이의 가치와 정보를 바로 전달하는 상태 변환(state transition)을 갖는다 하나의 이더리움 계정은 4개의 영역을 포함한다
- 난스(nonce),각 트랜잭션이 한 번만 처리될 수 있도록 하는 데 사용되는 카운터
- 계정의 현재 이더 잔고(ether balance)
- 계정의 컨트랙트 코드(contract code), 존재한다면
- 계정의 스토리지(storage)(기본적으로 비어 있음)
“Ether”는 이더리움의 중요한 내부 암호화-연료(crypto-fuel)이며, 트랜잭션 수수료를 지불하기 위해 사용된다 일반적으로, 두 가지 형태의 계정이 있다: 즉 외부 소유 계정(EOA: 이더리움 지갑을 만들 때 실제 사용자가 소유함)으로, 개인 키로 통제된다, 그리고 컨트랙트 계정(contract account)으로, 컨트랙트 코드로 제어된다 외부 소유 계정(externally owned account)은 코드를 갖지 않으며, 누구나 외부 소유 계정으로부터 트랜잭션을 생성하고 서명함으로써 메시지를 보낼 수 있다; 컨트랙트 계정에서는, 컨트랙트 계정이 메시지를 받을 때마다 코드가 활성화되어, 컨트랙트 계정이 내부 스토리지에서 읽고 쓸 수 있고 다른 메시지를 보내거나 또는 차례로 컨트랙트를 생성할 수 있다
Messages and Transactions
메시지와 트랜잭션
이더리움에서 “메시지”는 비트코인에서 ”트랜잭션”과 다소 비슷하지만, 세 가지 중요한 차이점이 있다 첫째, 이더리움 메시지는 외부의 존재 또는 컨트랙트에 의해서 생성될 수 있는 반면에 비트코인 트랜잭션은 외부 계정만 생성할 수 있다 둘째, 이더리움 메시지는 데이터를 포함하기 위한 분명한 옵션이 있다 마지막으로, 이더리움 메시지의 수취인은, 그것이 컨트랙트 계정이라면, 응답을 반환할 옵션을 가진다; 이것은 또한 이더리움 메시지가 함수들의 개념을 포괄함을 의미한다
이더리움에서 사용되는 용어 “트랜잭션”은 외부 소유 계정이 보낸 메시지를 저장하는 서명된 데이터 패키지를 말한다 트랜잭션은 메시지의 수신자, 발신자를 식별하는 서명, 이더(ether)의 양과 보낸 데이터, 그뿐만 아니라 STARTGAS
및 GASPRICE
라고 부르는 두 개의 가치를 포함한다 지수함수 공격과 코드로 무한 루프를 방지하기 위해서, 각 트랜잭션은 리미트 설정이 필요하다 실행 중에 발생하는 초기 메시지와 모든 추가 메시지를 둘 다 포함해서 허용된 코드 실행의 계산 단계의 수를 제한하기 위함이다 STARTGAS
는 이런 제한이며 GASPRICE
는 계산 단계 당 마이너(miner)에게 지불하는 수수료이다 만약 트랜잭션 실행이 “가스를 다 써버리면”, 모든 상태(state)는 수수료 지급을 제외하고 원래 상태로 돌아간다, 그리고 만약 트랜잭션 실행이 일부 남아있는 gas로 중단되면 그 수수료의 남은 부분은 발신자에게 반환된다 또한 컨트랙트를 생성하기 위한 별도의 트랜잭션 형식, 그리고 유사한 메시지 형식이 있다; 그 컨트랙트의 주소는 계정 nonce와 트랜잭션 데이터의 hash를 기초로 계산된다
메시지 메커니즘의 중요한 영향력은 이더리움의 “일급 시민(first class citizen)” 속성이다 - 컨트랙트는 외부 계정과 상응하는 영향력(power)을 가진다는 개념으로, 메시지를 보내고 다른 컨트랙트를 생성하는 능력을 포함한다 이것은 컨트랙트가 동시에 다른 많은 역할을 수행할 수 있게 한다: 예를 들어, 누군가 분산화된 조직의 일원이(1계약, a contract) 에스크로 계정(escrow account)이 될 수 있는데 (2계약, another contract), 즉 맞춤형 다수-증명 랜포트 서명(quantum-proof Lamport signatures)에 심취한 편집증이 있는 개인(3계약, a third contract)과 보안을 위해 5가지 키를 가진 계정을 사용하는 공동 서명 존재(co-signing entity)(4계약, a fourth contract) 사이에서 에스크로 계정이 될 수 있다 이더리움 플랫폼의 힘은 분산화된 조직과 에스크로 컨트랙트가 그 계약 각 당사자들이 어떤 종류의 계정인지 신경 쓸 필요가 없다는 것이다
❐ 랜포트 서명: 계산하기는 쉽지만 역을 구하는 것은 어려운 일방향 함수를 사용하는 디지털 서명 생성 기법
Ethereum State Transition Function
이더리움 상태 변환 함수, APPLY(S,TX) -> S’
은 다음과 같이 정의될 수 있다
- 트랜잭션이 형식에 잘 맞는지 (ie. 정확한 값의 수치를 가졌나), 서명이 유효하고, nonce가 발송자 계정 안의 nonce와 일치하는지 확인하라 맞지 않다면, 에러를 반환한다 (return an error)
- 트랜잭션 수수료를
STARTGAS*GASPRICE
로 계산하고, 서명으로부터 발송 주소를 판별한다 발송자의 계정 잔고에서 수수료를 차감하고 발송자의 nonce를 증가시킨다 지불을 위해 충분한 잔고가 없다면, 에러를 반환한다 GAS = STARTGAS
로 초기화하고, 트랜잭션 안의 bytes를 지불하기 위해 byte 당 gas의 특정 양을 뺀다- 발송자의 계정에서 수취하는 계정으로 트랜잭션 값을 전송한다 수취하는 계정이 아직 존재하지 않으면, 그것을 생성한다 수취 계정이 하나의 컨트랙트라면, 완성하거나 혹은 실행으로 가스를 다 소비할 때까지 그 컨트랙트 코드를 실행한다
- 만약 가치 전송이 발송인의 돈이 모자라서 실패하거나, 또는 코드 실행으로 가스를 다 써버리면, 수수료의 지불을 제외한 모든 상태 변화를 원래대로 되돌리고, 마이너의 계정에 그 수수료를 더한다
- 그렇지 않으면, 남은 모든 가스를 발송자에게 되돌려주고, 마이너에게 소비된 가스에 대한 수수료를 보낸다
예를 들어, 컨트랙트 코드를 가정해보자:
if !contract.storage[msg.data[0]]:
contract.storage[msg.data[0]] = msg.data[1]
사실 컨트랙트 코드는 낮은 EVM code로 작성된다는 것에 유리하라; 이 샘플은 Serpent, 분명함을 위해 우리의 고레벨 언어로 작성됐으며, EVM code에 컴파일 될 수 있다 컨트랙트 스토리지(contract’s storage)가 비어있는 상태에서 시작했으며, 한 트랜잭션이 10 ether value, 2000 gas, 0.001 ether gasprice, 그리고 두 개의 데이터 필드로 보내졌다고 가정해보자: [ 2, ‘CHARLIE’ ]
(64 바이트의 데이터(0-31 바이트까지는 숫자 2를 나타내고, 32-63 바이트는 CHARLIE 라는 문자열) 이 경우에 상태 변환 함수를 위한 처리는 다음과 같다:
- 트랜잭션이 유효하고 형식에 잘 맞는지 확인한다
- 트랜잭션 발송자가 적어도 2000 * 0.001 = 2 ether를 가졌는지 확인한다 만약 그렇다면, 2 ether를 발송자의 계정에서 뺀다
- gas = 2000 초기화; 트랜잭션 길이가 170 bytes long이고 바이트 수수료(byte-fee)가 5라고 가정하면, 850을 빼고 1150이 남는다 (170 * 5 = 850)
- 발송자의 계정에서 10 ether를 추가적으로 빼내고, 그것을 컨트랙트 계정에 추가한다
- 코드를 실행한다 이 경우에, 이것은 간단하다: index 2 컨트랙트 스토리지가 사용되었는지 확인하고, 사용되지 않은 것을 확인하면, index 2의 스토리지를
CHARLIE
값으로 설정한다 이것에 187 gas가 소비되었다고 가정하면, 가스의 남은 양은 1150 - 187 = 963이다 - 963 * 0.001 = 0.963 ether를 발송자의 계정으로 돌려보내 추가하고, 결과 상태를 반환한다
만약 트랜잭션의 수신 말미에 아무런 컨트랙트가 없다면, 총 트랜잭션 수수료는 제공된 GASPRICE
에 그 트랜잭션의 바이트 길이를 곱한 것과 단순히 같을 것이고, 트랜잭션과 함께 전송된 데이터는 관련이 없다 또한, 계약이 시작된 메시지는 그것들이 발생시킨 계산에 대한 가스 한도(gas limit)를 정할 수 있으며, 만약 하위 계산(sub-computation)으로 가스를 다 소비하면 메시지 요청 시점 상태로 되돌린다는 것에 유의하라 따라서, 트랜잭션과 같이, 컨트랙트는 그것들이 발생시킨 하위-계산에 대한 정확한 한도를 설정함으로써 제한된 계산 리소스를 확보할 수 있다
Code Execution
코드 실행
이더리움 컨트랙트 안의 코드는 낮은 수준의, 스택-기반 바이트코드(stack-based bytecode) 언어로서, “이더리움 가상 머신 코드” 또는 “EVM code”로도 부른다 이 코드는 연속된 바이트로 구성되며, 각 바이트는 하나의 연산을 나타낸다 일반적으로, 코드 실행은 zero에서 시작하는 현재 프로그램 카운터(counter)에서 그 연산의 반복적인 실행으로 구성된 무한 루프(infinite loop)이며 프로그램 카운터(counter)는 코드가 끝에 도달하거나 또는 error, STOP, RETURN 명령이 발견될 때까지 하나씩 증가한다 이 연산들은 데이터를 저장하는 세 가지 형태의 공간(space)에 대한 접속 권한을 가진다:
- 스택(stack), 32-byte 값을 넣고 빼낼 수 있는 후입선출(last-in-first-out) 방식의 컨테이너
- 메모리(memory), 무한 확장 가능한 바이트 배열(byte array)
- 컨트랙트의 장기 저장(storage), 키와 값들이 둘 다 32 byte인 key/value 저장소이다 계산이 끝나면 리셋되는 스택과 메모리와 달리, 스토리지는 장기간 지속된다
또한 코드는 블록 헤더(block header) 데이터뿐만 아니라, 들어온 메시지의 값, 보낸 사람 및 데이터에 액세스할 수 있으며, 코드는 출력으로 바이트 배열의 데이터를 반환할 수도 있다
EVM code의 공식 실행 모델은 놀랍도록 단순하다 이더리움 가상 머신이 실행되는 동안, 그 전체 계산 상태는 튜플(tuple) - (block_state, transaction, message, code, memory, stack, pc, gas)
로 정의될 수 있다, 블록 상태(block_state)
는 모든 계정을 포함하는 전체적인 상태이고 잔액(balances)과 스토리지(storage)을 포함한다 실행의 매 라운드마다, 현재 명령은 코드의 pc-th
(program counter-번째) 코드의 바이트를 가져옴으로써 찾으며, 각 명령은 튜플에 미치는 영향에 대한 자체 정의가 있다 예를 들어, ADD
는 스택에서 아이템 두 개를 꺼내서 그것들의 합을 다시 넣고, gas를 1 줄이고 pc를 1 증가시킨다, 그리고 SSTORE
는 스택에서 아이템 두 개를 꺼내서 두 번째 아이템을 첫 번째 아이템이 특정한 index에 컨트랙트 스토리지에 넣고, 또한 gas를 200까지 줄이고 pc를 1 증가시킨다 비록 JIT 컴파일(just-in-time compilation)을 통해서 이더리움을 최적화하는 많은 방법이 있지만, 이더리움의 기본 구현은 몇 백 줄의 코드로 구현될 수 있다
Blockchain and Mining
블록체인과 마이닝
이더리움 블록체인은 여러 면에서 비트코인 블록체인과 유사하지만, 몇 가지 차이점을 가진다 블록체인 설계(architecture) 관련해서 이더리움과 비트코인 간의 주요 차이점은, 비트코인과 달리 이더리움 블록은 트랜잭션 목록과 가장 최신 상태에 대한 복사본이 포함되는 것이다 그 외에도, 두 개의 다른 값, 블록 번호와 난이도(difficulty)가 블록에 저장된다 이더리움의 블록 유효성 검증 알고리즘은 다음과 같다:
- 참조된 이전 블록이 존재하고 유효한지 확인한다
- 블록의 타임스탬프(timestamp)가 참조된 이전 블록의 것보다 더 크고 15분 미래보다 작은 것을 확인하라
- Block number, difficulty, transaction root, uncle root 그리고 gas limit (다양한 낮은-수준의 이더리움-특정 개념들) 가 유효한지 확인하라
- 블록의 작업 증명(proof of work)이 유효한 지 확인하라
S[0]
을 이전 블록의STATE_ROOT
라고 하자n
transactions을 사용하여,TX
를 블록의 트랜잭션 목록이라고 하자0...n-1
사이의 모든 경우의 수에 대해, 집합setS[i+1] = APPLY(S[i],TX[i])
를 만족한다 만약 어떤 애플리케이션이 error를 반환하거나, 또는 총 gas가 블록 안에서 가스 한도(GASLIMIT)
지점을 초과할 때까지 소비되면, 에러를 반환한다S_FINAL
을S[n]
이라 하고, 마이너에게 지불되는 블록 보상을 추가한다S_FINAL
이STATE_ROOT
와 같은지 확인하라 만약 그렇다면, 그 블록은 유효하다; 그렇지 않으면, 그것은 유효하지 않다
일견 이 접근법은 매우 비효율적으로 보일 수도 있다, 각 블록에 전체 상태를 저장해야 하기 때문이다 그러나 사실 효율성은 비트코인의 그것과 비교되어야 한다 그 이유는 상태(state)는 트리 구조로 저장되고, 매 블록 이후에 트리의 작은 부분만 변경될 필요가 있기 때문이다 그러므로, 일반적으로, 두 개의 인접한 블록 사이에서 트리의 대부분은 동일하게 된다, 따라서 데이터는 한 번 저장되고 pointers를 사용해서 (ie. 하위 트리의 해시) 두 번 참조된다 ”패트리샤 트리(Patricia tree)”로 알려진 특별한 종류의 트리가 이것을 구현하기 위해 사용되며, 단순 변경이 아니라 효율적으로 노드들을 삽입하고 삭제할 수 있도록 하는 머클 트리(Merkle tree) 컨셉의 수정을 포함한다 또한, 모든 상태 정보가 마지막 블록의 일부이기 때문에, 전체 블록체인 히스토리를 저장할 필요가 없다 - 이것은, 만약 비트코인에 적용될 수 있다면, 5-20 배 공간을 절약을 할 수 있는 전략이다
최근글 ✏️
- 오늘의 차트: 비트코인과 스팀 차트; 뉴스 브리핑: ICE 실물인수도 BTC 선물 거래
- 코인 스토리: 비탈릭 부테린의 이더리움 백서 연구 - ④부; Ethereum White Paper
- 차트의 기술: 가격 갭 분석; Price Gap analysis
- 코인 스토리: 비탈릭 부테린의 이더리움 백서 연구 - ③부; Ethereum White Paper
- 비트코인 차트 분석과 유산소 운동; BTC, WorkOut
- 투자의 역사: 미국 운송 수단의 발달 ①; 운하 시대 ; STEEM 차트 분석
- 코인스토리: 해킹으로부터 지갑을 안전하게 보호하는 6가지 방법; 해커들의 코인 탈취 수단
#264
8.13
잘보고갑니다^^
꾹꾹~
감사합니다~