[블록체인] 09. Ethereum - Accounts and Transactions
Bitcoin (2008) vs Ethereum (2013)
Dr.Gavin Wood ; "Ethereum is WORLD COMPUTER!!"
Bitcoin vs Ethereum Transaction
- Bitcoin Transaction
: UTXO(Unspent Transaction Output)-based Model
잔액 개념이 없음.
- Ethereum Transaction
: Account-based Model
비트코인보다 우리에게 익숙한 시스템
Ethereum : A Transaction-based State Machine
Ethereum nodes 는 simple payment(트랜잭션 검증, 트랜잭션 포함한 block 채굴)보다 더 많은 일들을 할 수 있음.
Ethereum nodes 도 full node(EVM설치, smart contract 실행)와 light node로 나뉨.
* Bitcoin nodes
- full node : miner
- light node : SPU(Simple Payment Verification). 검증은 하지않고 단순히 bitcoin network 참여해서 관심 분야만 봄.
smart contract를 저장해달라고 요청하는 transaction을 만들어서 이더리움 블록체인에 저장시킬 수 있음.
코드가 영구히 남아있게 되고 누구든 가져다 쓸 수 있음.
이더리움(DApp을 개발하고 실행하는 플랫폼)의 목적은 DApp(smart contract + 적절한 user interface) 운영임.
이더리움은 transaction-based state machine 이며 여기서 state는 single global truth를 의미함.
여러 노드들이 트랜잭션 실행을 요청하고, 트랜잭션 실행 결과가 반영된 상태가 모든 노드들 사이에서 합의가 이루어져야 함.
How to run smart contracts?
Ethereum Virtual Machine(EVM)이 smart contract를 실행시킬 수 있음.
EVM은 실제 물리적으로 존재하는 것이 아님.
이더리움 상의 full node에 전부 들어가있는 가상의 머신인데, full node들이 EVM을 통해서 smart contract 코드를 실행할 수 있음. 실행 결과가 새로운 상태를 만들어서 블록체인에 반영되는 과정이 반복됨.
이더리움 채굴(P2P network 참여)을 시작하려면 가장 먼저, 이더리움 프로토콜을 구현해놓은
프로그램(EVM을 포함하고 있음)을 다운받아야 함. ex) Geth(Go), Parity(Rust)
-> full node들이 EVM을 통해서 smart contract를 실행할 수 있도록 해주는 역할을 함.
gas : miner(트랜잭션 실행시켜줌)에게 지불함.
mining fee(miner가 가져가는 fee) = gas price * gas consumed(<= gas limit)
* gas price : 내가 제시하는 리터당 휘발유 가격 ex) 리터당 얼마를 지불할 지
* gas limit : ether로 지불할 용의가 있는 양 ex) 10리터까지는 책임지고 지불할게!
* solidity : smart contract를 프로그래밍할 때 주로 사용하는 프로그래밍 언어
* smart contract 예시
Ethereum Accounts
accounts ≒ address
2 types of accounts
① externally owned accounts
: storing ETH(bitcoin의 address에 해당),
코드 없음. private key로 컨트롤 됨.
② contract accounts
: containing smart contracts(계좌가 코드를 포함하고 있음),
스스로 동작하지 않음. 누군가가 내 코드를 실행시켜달라는 요청을 보내야 실행됨. 독자적 실행X
유형①의 account를 통해서 transaction을 유발시켜서 유형②로 ETH를 보내면, 유형②의 코드가 activate됨.
smart contract가 업로드될 때 이 smart contract를 위한 account(②)가 생성되고 그 account에 코드가 들어감.
각각의 account는 *20byte의 주소를 가짐.
* 20byte (≒ address)
: ID 역할.
public key를 hash(SHA-256)해서 만듦.(32byte 중 뒤의 20byte)
* global state machine (≒ account attribute)
: 수많은 account들과 그 account들의 state로 이더리움의 global state를 표현할 수 있음.
account의 state는 transaction이 다른 account로 ETH를 보내서 바뀌거나,
다른 account로 smart contract 실행 요청을 해서 코드의 실행 결과로 인해 바뀜.
즉, message passing으로 인해 바뀐 state를 반영한 것이 global state.
① externally owned account (EOA)
transaction을 만들고 서명해서 보냄으로써 메세지 전달 가능
i) 다른 EOA에 메세지 전송 가능(=송금, 계좌이체)
ii) 다른 contract account에 메세지 전송 가능(=코드 실행)
② contract account
스스로 transaction 구동 불가.
EOA의 명령을 받거나 다른 contract account가 호출한 경우(≒ function call)에만 실행됨.
account state
- nonce(≒ count역할)
: ①에서는 이 account에서 보내진 transaction의 개수를 의미하고
②에서는 이 account에 의해서 만들어진 contract의 수(해당 account의 인기)를 의미함.
* 만약 nonce가 없다면?
- balance(≒ 잔액)
단위는 wei를 사용함. (ETH가 너무 커서 잘게 쪼갬; 10^8 wei = 1 ether)
- storageRoot
contract account : Merkle Patricia tree의 루트노드의 해시값을 저장.
EOA : empty (코드가 없으니까 storageRoot가 필요 없음)
- codeHash
contract account : 해당 account의 EVM코드의 해시값을 저장.
(high level언어로 작성된 코드를 EVM에 적용될 수 있는 byte코드로 바꾼 결과를 저장)
EOA : empty string에 대한 해시값을 저장.
world state (Ethereum's global state)
수많은 account들의 상태를 다 합쳐놓은 것. account 상태의 조합.
account address와 account states의 mapping을 Merkle Patricia tree에 저장.
Merkle Patricia Tree
Ethereum이 global한 컴퓨터이고 global한 상태를 가지고 있음. Ethereum의 상태에는 Ethereum상의 모든 account의 상태가 다 들어가야 함.
그런데 Ethereum의 모든 account의 상태가 수시로 빠르게 바뀌지 않음. 인기없는 smart contract는 일년에 한 번정도 호출될 수 도 있음. 그러면 그 smart contract에 해당하는 account는 state가 일년동안 안바뀔 것임.
따라서 Ethereum의 수많은 account중에 상태가 바뀌지 않고 한동안 계속 유지되는 account는 굳이 copy & paste 하지 않음. 그리고 공통되는 부분을 최대한 살림!
공통되는 부분을 최대한 적게 써서 space 절약하자.
Ethereum의 global state를 저장하기 위해 efficient한 storage management가 필요해서
Merkle Patricia Tree를 채택하였음.
Ethereum Gas and Payment
gas를 ether로 지불하긴 하지만 gas != ether임.
miner에게 지불하기 위한 또다른 형태의 currency임.
transaction이 computation을 유발하기때문에 이를 감내해야하는 miner의 비용에 대한 보상.(fee의 용도)
=> 채굴자는 block reward + gas payment를 가져감.(채굴자가 감내한 비용보다 많음)
gas payment에 gas price를 설정해놓고 (gas price) * (실제 사용한 gas) 만큼의 wei(ether)를 받음.
=> gas price를 높게 설정한 transaction을 위주로 먼저 채굴하면 채굴자가 받는 보상이 커짐.
sender는 transaction마다 gas limit과 gas price를 설정.
* gas limit
: 내 transaction을 처리할 때 채굴자들이 operation을 실행할 때마다 gas limit을 차감함.
gas limit이 0이 되는 순간 실행을 멈춤.(halting problem을 피하기 위한 방법).
* gas price
: gas당 얼마의 gwei(giga wei; 10^9 wei)를 지불할건지.
내 transaction의 우선 처리를 원하면 높게 설정.
채굴자는 gas price * gas consumed를 wei로 환산하여 가져감.
최대 gas price * gas limit 만큼 가져갈 가능성이 있음.(sender가 그 이상 가지고있어야 채굴자가 채굴 시작. 후불제 느낌.)
사용하지 않은 gas는 환불됨.
실행 중 exception이 일어나서 정상종료되지 못했더라도 에러발생 시점에서 남아있는 gas limit만큼 환불.
사용한건 되돌려주지 않음.
* gas 도입한 이유?
transaction 유발자가 수수료를 지불할 때 (법정화폐로 ether를 사기때문에) 결국은 법정화폐로 지불함.
법정화폐와 ether사이의 교환가치가 변동이 심할 수 있기 때문에 ether만으로는 수수료 책정 조절 쉽지않음.
(수수료를 0.0001ether로 책정한다고 할 때, 1 ether의 가격이 200만원->1000만원이 된다면 사람들이 지불할 원화 가격이 엄청나게 올라감. 따라서 중간단계로 gas 도입하여 수수료 측정. gas와 ether사이의 환산은 gas price를 통해 사용자가 설정. ether가격 올라가면 gas price를 낮게 설정하는 추세가 됨.)
트랜잭션의 out of gas 발생 시 프로세스는 즉시 종료되며,
중간 단계에서 state가 변했다면 실행 이전으로 원상 복구됨.(사용한 gas를 환불해주지는 않음)
computation 뿐만아니라 storage에 대한 fee도 받음.
* fee의 목적?
사용자가 네트워크 리소스를 과다사용(overtax)하지 않도록 제어하는 장치.
Turing-complete언어로 작성한 Ethereum의 smart contract코드가 infinite loop 돌리는 것을 막음.
Ethereum Transactions and Messages
* transaction
: sender의 private key로 서명이 된 instruction.
EOA에서 transaction이 유발될 때 서명이 일어남.
(contract account는 EOA의 invoke에 의해서 작동하고 독자적 시작 불가능하므로)
2 types of transaction
① message calls
: 이미 만들어진 contract account에 해당 코드를 실행시키기 위한 목적
② contract creations
: 기존에 존재하지 않았던 코드를 만들어서 이더리움 블록체인 상에 올리기 위한 목적
contract는 message를 통해서 다른 contract와 상호 소통함.(internal transaction)
- nonce(≒ count역할)
: sender(이 트랜잭션을 시작한 account)에 의해서 보내진 transaction의 개수를 의미
- gas limit
: 내가 최대로 허용할 수 있는 gas 사용량
- gas price
: 내가 임의로 설정할 수 있는 gas당 가격
gas limit * gas price 이상의 ether가 내 account에 들어있어야 실행 시작됨.
- to
: 목적지 address (zero for a contract-creating transaction; 아무도 사용하지 않는 주소 0)
- value
: 해당 transaction의 목적지(to) account에 보낼 wei(ether)의 양
- v, r, s
: signature 생성 및 검증 관련.
- init
: contract-creating할 때 data부분.
딱 한번만 실행되며 실제 smart contract의 byte코드가 새롭게 만들어진 contract account에 연결됨.
- data
: message call할 때 data(parameters)부분.
- message call
: 기존에 존재하는 contract account의 data를 보내는 것
(기존에 존재하는 주소에 들어있는 코드의 function중 하나를 지정하고 호출해서 smart contract를 invoke)
Ethereum Transaction Execution
transaction 유발시키는 sender는 transaction 실행 전에 gas 계산을 미리 해야함. (out of gas 방지)
- Intrinsic gas : 필요한 gas 양
- Predefined gas fee : 기본 요금(transaction 시작 시 지불)
- Storage fee : 데이터 전송(네트워크 대역폭 사용)에 대한 요금. data==0이면 4, 아니면 68
- Contract creation : contract 생성 시 기본 요금.
contract creation
내가 처음으로 만들어질 contract를 준비해서 이더리움에 보냄.
- to : 목적지는 zero
- contract address : 어떤 account에 들어갈지 sender는 모름.
sender의 주소와 그 주소로부터 보내진 트랜잭션의 수로부터 알아서 계산됨.
- nonce : zero(새로 생성된 contract는 invoke된 횟수가 0이므로)
- account balance : contract를 처음 생성하면서 보낸 wei의 양.(보낼 수 있지만 안보내도 됨)
- storage : empty
- codeHash : empty
- init code : 새로운 contract가 포함됨!
message call
이미 존재하는 contract를 invoke.
해당 smart contract의 function 중에 어떤 걸 호출할지에 대한 data와 파라미터로 넘길 값 필요.
output이 또다른 contract를 호출할 수도 있음.
out of gas로 인해 execution이 exit하더라도 refund는 해주지 않으며
out of gas를 유발한 시작점으로 undo함(state 원상복구).
invalid instruction(ex. value<0)로 인해 exception발생 시
그때까지 사용한 gas는 refund해주지 않지만 남은 gas는 돌려받을 수 있으며 state를 undo함.