이 글은 '한양대 x 그라운드X'에서 진행한 블록체인 강의 영상을 정리한 것입니다.
참고링크 : https://www.youtube.com/watch?v=imh8z8Mf764&list=PLKqrwxupttYEcJhWAw0E_5RVpDD9LD6Q-&index=8
블록체인의 상태
(어카운트 기반) 블록체인의 상태
블록체인은 트랜잭션으로 변화하는 상태 기계 (State Machine)
상태 기계
- 블록체인은 초기 상태에서 변경사항을 적용하여 최종 상태로 변화하는 상태 기계
- 이전 블록의 최종 상태(final state)는 현재 블록의 초기 상태(initial state)
- Genesis block의 경우 임의의 초기값들이 설정되는데 이것이 genesis block의 초기상태이자 최종상태
- (어카운트 기반) 블록체인의 상태
- TX는 어카운트를 생성하거나 변경
- e.g., Alice가 기존에 존재하지 않던 주소 X에 1 ETH를 전송하면 새로운 EOA가 생성
- e.g., Alice가 새로운 스마트 컨트랙트를 배포 (컨트랙트로 어카운트)
- e.g., Alice가 Bob에게 5 ETH를 전송하는 TX가 체결되면 Alice의 Bob의 잔고가 변경
- 항상 같은 결과를 보장하기 위해 하나의 TX가 반영되는 과정에서 다른 TX의 개입은 제한됨
트랜잭션
Ethereum 어카운트의 종류
- External Account : 사용자(end user)가 사용하는 어카운트(a.k.a. EOA)
- Contract Account : 스마트 컨트랙트를 표현하는 어카운트
- Ethereum은 EOA와 스마트 컨트랙트의 상태를 기록 및 유지
- 스마트 컨트랙트는 특정주소에 존재하는 실행 가능한 프로그램
- 프로그램은 상태를 가지기 때문에 Ethereum/Klayton은 스마트 컨트랙트를 어카운트로 표현
- EOA는 블록에 기록되는 TX를 생성
- 블록에 기록되는 TX들은 명시적인 변경을 일으킴 (e.g., 토큰 전송, 스마트 컨트랙트 배포/실행)
- EOA와 CA의 차이점은 EOA만 트랜잭션을 생성할 수 있다는 점이다. CA는 passive한 존재이다. 항상 누군가가 실행시켜줘야 한다.
트랜잭션(TX)과 가스(Gas)
- TX의 목적은 블록체인의 상태를 변경하는 것
- TX는 보내는 사람(sender, from)과 받는 사람(recipient, to)이 지정되어 있으며
- to가 누구냐에 따라 TX의 목적이 세분화
- Gas: TX를 처리하는데 발생하는 비용
- TX를 처리하는데 필요한 자원(computing power, storage)을 비용으로 전환한 것이 가스(gas)
- Sender는 TX의 처리를 위해 필요한 가스의 총량과 같은 가치의 플랫폼 토큰을 제공해야함
- 이때 지출되는 플랫폼 토큰을 가스비(Gas Fee)라 정의
- 가스비는 블록을 생성한 노드가 수집
트랜잭션과 서명
- 플랫폼은 sender가 TX를 처리하는데 필요한 가스비를 가지고 있는지 확인
- 가스비 확인은 구현에 따라 상이
- Ethereum/Klayton은 노드가 TX를 수신함과 동시에 가스비 이상의 balance가 있는지 확인
- TX의 체결과 동시에 sender의 balance에서 가스비를 차감
- TX는 sender의 서명(v, r, s)이 필요
- 어카운트의 balance를 사용하기 때문
- 서명의 증명은 구현마다 상이
- Ethereum: 서명 → 공개키 도출 → 어카운트 주소 도출 → 어카운트 존재유무 확인
- Klayton: from 주소 확인 → 저장된 공개키 불러오기 → 서명 직접 검증
트랜잭션 예시
{
nonce: 1, (nonce는 account가 몇 번째 트랜잭션을 보내는지를 말해주는 것)
from : ~
to: ~~
value: 10,
// omitted other fields for brevity
// platform specific fields are requried
}
Ethereum 트랜잭션 예시
{
nonce: ‘0x01’,
gasPrice: ‘0x4a817c800’, (gas 1개의 가격)
gas: ‘0x5208’, (지불할 의향이 있는 gas의 개수)
value: ‘0xde0bdc000’
to:
v: ‘0x25’, (식별자)
r: ~~ (서명)
s: ~~ (서명)
}
(v, r, s)는 서명을 의미한다. 엄밀히 말하면 (r, s)가 서명을 의미한다.
Transaction Journey
- Alice는 트랜잭션을 생성해서 특정 노드에게 전달
- 노드는 블록을 생성하기 위해 노력하고, 생성되어 트랜잭션이 체결
- 체결되었다는 Receipt를 Alice에게 전달
Alice와 Node 사이 통신
Alice → Node
- Alice는 TX를 생성, 서명하여 Node에게 전달
- 이때 데이터 구조를 온전하게 전달하고자 RLP 알고리즘으로 TX를 직렬화
- Alice와 Node가 같은 프로토콜로 통신하는 것이 중요
Node → Alice
- 올바른 TX 수신 시 TX 해시를 반환
- TX 채결 시 Receipt를 반환; 소요된 Gas, TX 해시, input 등이 기록
스마트 컨트랙트와 솔리디티
Smart Contract
- 특정 주소에 배포되어 있는 TX로 실행 가능한 코드
- 스마트 컨트랙트 소스코드는 함수와 상태를 표현; 컨트랙트 소스코드는 블록체인에 저장
- 함수는 상태를 변경하는 함수, 상태를 변경하지 않는 함수로 분류
- 사용자(end user, EOA owner)가 스마트 컨트랙트 함수를 실행하거나 상태를 읽을 때 주소가 필요
- 스마트 컨트랙트는 사용자가 실행
- 상태를 변경하는 함수를 실행하려면 그에 맞는 TX를 생성하여 블록에 추가(TX 체결 = 함수의 실행)
- 상태를 변경하지 않는 함수, 상태를 읽는 행위는 TX가 필요 없음(노드에서 실행)
Solidity
- Ethereum/Klaytn에서 지원하는 스마트 컨트랙트 언어
- Klaytn은 Solidity 버전 0.4.24, 0.5.6을 지원
- 일반적인 프로그래밍 언어와 그 문법과 사용이 유사하나 몇가지 제약이 존재(e.g., 포인터의 개념이 없기 때문에 recursive type의 선언이 불가능)
Contract = Code + Data
- Solidity 컨트랙트는 코드(함수)와 데이터(상태)로 구성
- Solidity 함수는 코드 안에 변수로 선언된 상태를 변경하거나 불러옴
- 아래 예시에서 set, get은 함수, storedData는 상태
contract SimpleStorage{
uint storedData;
function set(uint x) public{
storedData = x;
}
function get() public view returns (uint){
return storedData;
}
}