* Blockchain in Action(블록체인 인 액션) 책의 실습을 바탕으로 작성하였음.
스마트 컨트랙트로 해결해야 할 문제 설정에서부터 코드의 배포에 이르기까지 전 과정을 살펴볼 수 있는 간단한 예제를 통해 스마트 컨트랙트 설계를 탐구한다. 설계 과정의 목표는 스마트 컨트랙트의 내용을 정의하는 것이다.
설계를 하는 데에는 UML(Unified Modeling Language)을 사용한다. draw.io를 통해 UML 다이어그램을 그릴 수 있다.
UML 유스 케이스(use case) 다이어그램은 해결해야 할 문제과 스마트 컨트랙트의 함수들을 어떻게 사용해야 할지에 대해 숙고할 수 있도록 해준다. 다음은 탈중앙화 카운터의 유스 케이스 다이어그램이다. 이 다이어그램이 설계 과정의 출발점이다.
탈중앙화 카운터에서 문제 해결을 위한 블록체인 기반 컴포넌트들의 여러 속성을 설정한다. get() 함수는 읽기 전용 함수로, 이 함수의 호출을 블록체인에 기록할 필요는 없다.
카운터 문제 해결 설계를 위해 UML 컨트랙트 다이어그램을 설정한다. 이전의 두 단계에서 나온 아이템들을 바탕으로 그린다. 탈중앙화 카운터는 단순하기 때문에, 조건이나 규칙을 사용하지 않는다.
constructor() 함수는 스마트 컨트랙트가 블록체인 인프라에서 작동하는 VM 샌드박스에 처음 배포되었을 때 한 번만 작동한다. 컨트랙트의 초기값을 설정할 수 있다.
컨트랙트 다이어그램은 설계 논의 시 사용할 수 있는 편리한 자료이다.
Solidity는 이더리움 재단이 처음 도입했는데, 블록체인 오퍼레이션에 특화된 전용 언어이다. 스마트 컨트랙트 코드는 여러 블록체인 노드에서 실행될 때 일관성을 유지하기 위해, 제한된(restricted) 샌드박스 환경에서 실행된다. 또한 블록체인에 특화된 특정 기능이 언어에 내장되어 있어야 한다.
시뮬레이트된 블록체인 위에 스마트 컨트랙트 코드를 작성, 수정, 컴파일하고, 이를 배포하고 테스트하기 위해 리믹스IDE를 사용한다.
솔리디티 언어는 스마트 컨트랙트를 코딩하기 위한 객체제향 고수준 언어이다. 정적 타입 언어이고, 상속/라이브러리/사용자 정의 타입 등을 지원한다.
pragma solidity ^0.8.1;
contract Counter {
uint value;
function initialize(uint x) public {
value = x;
}
function get() view public returns (uint) {
return value;
}
function increment(uint n) public {
value = value + n;
// return (optional)
}
function decrement(uint n) public {
value = value - n;
}
}
JavaScript VM 위에서 작성한 Counter.sol 코드를 컴파일(Compile) 후 배포(Deploy)한다. 배포된 컨트랙트를 테스트하며, 출력 콘솔 내용과 트랜잭션을 확인한다. 다른 사용자를 표현하는 어카운트 번호를 넣어서, 다른 참여자를 시뮬레이션해 볼 수 있다.
아래는 increment(11)을 호출한 트랜잭션이다.
스마트 컨트랙트 코드를 블록체인에 배포하였을 때, 참여자가 어카운트를 가지고있고 동일한 블록체인 네트워크에 접속해 있으면 누구나 이 컨트랙트를 사용할 수 있다. 블록체인은 여기에 변조 불가능한 분산 장부를 사용한다. 변조 불가능한 분산 장부는 서로 알지 못하는 탈중앙화 참여 노드 간에 신뢰를 구축한다.