Solidity는 블록체인 smart contract에 쓰이는 전용 언어이다.
이더리움을 기준으로, 이더를 보낼 수 있는 기능들을 제공하며, 튜링 완전한 언어이기 때문에 송금 외에도 다양한 기능들을 smart contract에 구현할 수 있다.
이번 장에서는, solidity 문법을 공부하고 직접 smart contract를 작성해본다.
먼저, 솔리디티 언어로 작성된 프로그램이 이더리움 네트워크에서 작동하는 원리를 살펴보자.
- 솔리디티로 스마트컨트랙트를 작성한다. 인간이 읽고 이해할 수 있는 형태의 소스코드이다.
- 스마트 컨트랙트를 Ethereum Bytecode로 컴파일한다. 컴퓨터가 이해할 수 있는 형태이며, EVM 기반의 블록체인에서 사용할 수 있다.
- 배포의 과정을 통해 EVM 블록체인에 배포되면, 작성한 스마트컨트랙트가 사용가능한 서비스 상태가 된다. 블록체인 네트워크 위에 올라가서, 모두가 사용가능한 상태가 된다고 볼 수 있다.
이제 스마트컨트랙트를 작성해보자.
solidity 코드를 작성해보기 위해 IDE를 이용한다. 아래 링크를 통해 접속 가능하며 데스크탑 버전과 웹브라우저버전을 모두 지원하는데, 이 장에서는 웹브라우저 버전 IDE를 이용해 실습한다.
https://remix-project.org/?lang=ko
Remix - Ethereum IDE & community
remix-project.org
좌측 workspace에서 파일을 클릭하여 VendingMachine이라는 이름의 새 파일을 만든다.
좌측 메뉴바 중 solidity compiler 아이콘을 누르고 들어가, Auto compile 항목에 체크해준다. 체크를 하면 왼쪽 화면과 같이 2개의 warning messages를 볼 수 있는데, license에 관한 명시를 하지 않아 발생하는 경고이다. 에러가 아니라 워닝이기 때문에 꼭 해결해야 하는 문제는 아니지만, 오른쪽 화면과 같이 license와 compiler version을 명시해줌으로써 해결할 수 있다.
메뉴바의 solidity compiler 아이콘에 초록색 체크가 표시되면, 자동으로 compile 될 수 있는 상태라는 것을 확인할 수 있다.
이제, contract를 만들고 내용을 채워보자.
위 코드를 추가함으로써 VendingMachine이라는 이름의 contract를 정의할 수 있다. contract의 이름은 파일명과 같이 않아도 된다.
이 상태로도 autocompile 후 배포할 수 있지만, 아무런 내용이 없기 때문에 당연히 아무 일도 하지 못 한다. solidity 파일은 하나 이상의 contract를 포함할 수 있는데, 배포할 때에는 하나씩 배포해야 한다.
VendingMachine의 상태변수를 선언한다. solidity는 컴파일 시점에 각 변수(상태변수와 지역변수)의 타입이 명시되어야하는 (또는 최소한 추론가능해야하는) 정적 타입 언어이기 때문에 변수의 타입을 명시해주어야 한다.
owner는 이 계약을 배포한 사람의 주소를 저장하는 address type 변수로, public 키워드는 이 변수가 공개적으로 읽힐 수 있음을 의미한다. cupcakeBalances는 주소에서 정수로 매핑하는 자료구조로, 각 주소가 보유한 컵케이크의 수량을 저장합니다. 이 변수도 public으로 선언되어 있어, 누구나 읽을 수 있다.
Address
address : 20바이트(이더리움 address의 크기)를 담을 수 있다. address 타입에는 멤버가 있으며 모든 컨트랙트의 기반이 된다.
연산자 : <=, <, ==, !=, >= and >
address의 대표적 members
• balance : address의 잔고를 조회
• transfer : 다른 address에 Ether를 (wei 단위로) 전송
Mapping
mapping : key type에서 value type으로 매핑하는 자료구조. mapping(_KeyType => _ValueType) 와 같이 선언된다.
_KeyType 은 매핑, 동적 크기 배열, 컨트랙트, 열거형, 구조체를 제외한 거의 모든 유형이 될 수 있으며, _ValueType 은 매핑 타입을 포함한 어떤 타입이든 될 수 있다.
매핑은 길이 또는 집합(set)을 이루는 키나 값의 개념을 가지고 있지 않으며, 상태변수(또는 내부 함수에서의 스토리지 참조 타입)에만 허용된다.
이외에 다른 언어들과 같이 string, int 타입 등도 지원하는데, 다른 자료구조는 아래 공식문서에서 확인할 수 있다.
https://solidity-kr.readthedocs.io/ko/latest/types.html
Constructor(생성자 함수)를 선언한다. constructor()는 컨트랙트가 배포될 때 한 번 실행되는 특별한 함수로,
계약이 배포되는 순간 배포한 사람의 주소(msg.sender)를 owner 변수에 저장하고 이 계약 자체의 주소에 100개의 컵케이크를 할당한다.
msg
msg는 솔리디티에서 내장된 전역 객체로, 현재 실행 중인 트랜잭션과 관련된 정보를 포함한다.
msg의 주요 properties
• msg.sender: 현재 함수 또는 트랜잭션을 호출한 주체의 주소를 나타낸다. 이는 보통 트랜잭션을 발생시킨 사용자 또는 스마트 계약의 주소인데, 예를 들어 누군가가 스마트 계약의 purchase 함수를 호출하면, msg.sender는 그 사용자의 주소를 나타낸다.
• msg.value: 현재 트랜잭션과 함께 전송된 이더(ETH)의 양을 나타낸다. 예를 들어, 사용자가 스마트 계약의 purchase 함수를 호출하면서 2 ETH를 보냈다면, msg.value는 2 ETH를 나타낸다.
VendingMachine의 함수를 선언한다. 자판기에 컵케이크를 보충하기 위한 refill() 함수와, 구매자가 컵케이크를 구매할 수 있도록 하는 purchase() 함수를 추가한다. 각 함수 내에 있는 require 함수는 해당 거래를 실행하기 위해 만족해야 하는 조건을 명시한다.
누구나 호출할 수 있는 refill 함수는 amount만큼 컵케이크를 추가한다. 누군가에 의해 호출되면, require(msg.sender == owner, "Only the owner can refill.") 함수를 통해 함수 호출자가 owner인지 확인하고 owner가 아닐 경우 에러 메시지를 반환한다. 만약 owner라면, 현재 계약의 컵케이크 수량을 amount만큼 증가시킨다. 이를 통해 자판기의 컵케이크 수량은 오직 owner, 즉 이 컨트랙트 자체만이 관리할 수 있도록 보장한다.
누구나 호출할 수 있는 purchase 함수는 amount만큼 컵케이크를 구매할 때 사용된다. 이 함수는 payable로 선언되어 있어 이더(ETH)를 전송받을 수 있다. 컵케이크 하나의 가격을 1 ether일 때, require(msg.value >= amount * 1 ether, "You must pay at least 1 ETH per cupcake")를 통해 전송된 이더가 amount * 1 이더 이상인지 확인하고 그렇지 않을 경우 에러 메시지를 반환한다. 또한, require(cupcakeBalances[address(this)] >= amount, "Not enough cupcakes in stock to complete this purchase")를 통해 계약이 충분한 컵케이크를 보유하고 있는지 확인한다. 두 조건 모두 만족하면, 계약의 컵케이크 수량을 amount만큼 감소시키고 구매자의 주소에 해당하는 컵케이크 수량을 amount만큼 증가시킨다.
이렇게 솔리디티 언어를 사용해 스마트 컨트랙트를 작성해보았다. 다음 장에서는 이 sol 파일을 배포하는 과정에 대해 다룬다.
'Study > Blockchain' 카테고리의 다른 글
[Ethereum] #01_Ethereum Intro 이더리움 (2) | 2024.07.19 |
---|---|
[Blockchain] #07_Smart Contract & Solidity 스마트 컨트랙트 배포 (0) | 2024.07.18 |
[Blockchain] #05_Smart Contract Introduction 스마트 컨트랙트 개념 (0) | 2024.07.18 |
[Blockchain] #04_Wallet & MetaMask 블록체인지갑과 메타마스크 (0) | 2024.07.18 |
[Blockchain] #03_Merkle Tree in Blockchain 머클트리&트랜잭션 (0) | 2024.07.18 |