1 Solidity
스마트 컨트랙트를 작성하는데에는 부작용(side-effect) 이 없는 선언형 프로그래밍 언어가 더 적당합니다. 하지만 많은 수의 개발자들이 명령형 프로그래밍 언어를 사용하고 있는 현실을 무시하기는 쉽지 않습니다. 현실을 반영하듯이 대표적인 이더리움 스마트 컨트랙트 프로그래밍 언어인 솔리디티 또한 명령형 프로그래밍 언어입니다.
- 프로그래밍 언어를 저차원(Low-Level)과 고차원으로 구분했을 때 비트코인 스크립트 언어와 달리 고차원 언어.
- C++, Python, 자바스크립트 등 기존에 널리 사용되고 있던 언어에 영향을 받았기에 어렵지 않게 학습이 가능.
- 스마트 계약 작성을 위해 탄생한 언어로써 언어의 모든 요소가 스마트 계약을 쉽게 작성할 수 있도록 설계됨.
- 튜링 완전성으로 인해 표현의 제약없이 자유롭게 어떠한 형태의 경제 활동이든 프로그래밍이 가능.
1.1 solc
- 솔리디티 언어로 작성된 프로그램을 EVM 바이트 코드로 변환하는 솔리디티 컴파일러이다.
설치(mac)
brew update
brew upgrade
brew tap ethereum/ethereum
brew install solidity
1.2 solc 버전 선택
- 솔리디티 프로그램에는 호환 가능한 솔리디티 최소 및 최대 버전을 지정하고 컨트랙트를 컴파일 하는데 사용할 수 있는
pragma
지시문이 포함될 수 있다. - 솔리디티 컴파일러는 버전
pragma
를 읽고 컴파일러 버전이 저번 pragma와 호환되지 않으면 오류가 발생 - pragma 지시문은 비이트코드로 컴파일되지 않는다
- 호환성 검사를 위해 컴파일러에서만 사용됨
2 단순한 솔리디티 프로그램 작성
pragma solidity 0.4.19;
contract Faucet {
function () public payable {}
function withdraw(uint withdraw_amount) public {
require(withdraw_amount <= 100000000000000000);
msg.sender.transfer(withdraw_amount);
}
}
2.1 컴파일
- 솔리디티로 작성한 스마트 컨트랙트는 EVM에서 사용되는 바이트 코드로 컴파일되어야 한다.
- 16진수로 시리얼라이즈된 바이너리 결과물
$ solc --optimize --bin Faucet.sol
======= Faucet.sol:Faucet =======
Binary:
608060405234801561001057600080fd5b5060cc8061001f6000396000f3fe6080604052600436106
01f5760003560e01c80632e1a7d4d14602a576025565b36602557005b600080fd5b34801560355760
0080fd5b50605060048036036020811015604a57600080fd5b50356052565b005b67016345785d8a0
000811115606657600080fd5b604051339082156108fc029083906000818181858888f19350505050
1580156092573d6000803e3d6000fd5b505056fea26469706673582212205cf23994b22f7ba19eee5
6c77b5fb127bceec1276b6f76ca71b5f95330ce598564736f6c63430006040033
2.2 이더리움 컨트랙트 ABI
-
ABI(Application Binary Interface)는 두 프로그램 모듈 간의 인터페이스다
- 주로 운영체제와 사용자 프로그램 사이
-
데이터 구조와 함수가 어떻게 기계 코드에서 사용되는지 그 방법을 정의한다.
-
ABI는 기계 코드와 데이터를 교환하기 위해 인코딩 및 디코딩하는 기본 방법이다.
-
ABI는 함수 설명 및 이벤트의 JSON 배열로 지정된다.
- 함수의 필드: type, name, inputs, outputs, constant, payable
- 이벤트의 필드: type, name, inputs, anonymous
ABI의 목적
- 컨트랙트에서 호출할 수 있는 함수를 정의하고 각 함수가 인수를 받아들이고 결과를 반환하는 방법을 설명하는 것
- 지갑이나 디앱 브라우저와 같은 애플리케이션은 올바른 인수와 인수 타입으로 컨트랙트의 함수들을 호출하는 트랜잭션을 구성할 수 있다.
Faucet.sol의 ABI
- 이 json은 일단 배포되면 Faucet 컨트랙트에 접근하는 모든 애플리케이션에서 사용할 수 있다.
$ solc --abi Faucet.sol
======= Faucet.sol:Faucet =======
Contract JSON ABI
[{"inputs":[{"internalType":"uint256","name":"withdraw_amount","type":"uint256"}], \
"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"}, \
{"stateMutability":"payable","type":"receive"}]
[
{
"constant": false,
"inputs": [
{
"name": "withdraw_amount",
"type": "uint256"
}
],
"name": "withdraw",
"outputs": [],
"payable": false,
"stateMutability": "nonpayable",
"type": "function"
},
{
"payable": true,
"stateMutability": "payable",
"type": "fallback"
}
]
3 데이터 타입
4 사전 정의된 글로벌 변수 및 함수
- 컨트랙트가 EVM에서 실행되면 몇개의 글로벌 객체에 접근할 수 있다.
- 또한 사전 정의된 함수로 다수의 EVM 연산 코드가 제공된다.
- 아래는 컨트랙트 내에서 접근할 수 있는 변수와 함수이다.