스마트 컨트랙트에 대한 신뢰를 높이고, 저작권과 같은 문제를 해소하기 위해 솔리디티 코드의 최상단에 SPDX 라이센스를 명시한다.
* SPDX 라이센스는 주석으로 표시
// SPDX-License-Identifier: MIT
pragma는 특정 컴파일러의 버전을 표기할 때 사용한다.
* pragma는 일반적으로 파일의 최상단에 위치한다.
pragma solidity 0.8.7;
다른 언어들 처럼 필요한 파일들을 임포트 할 때 사용
import "파일이름";
// 임포트하는 파일을 symbolName이라는 이름으로 사용
import * as symbolName from "파일이름";
import "파일이름" as symbolName;
// 파일의 일부분만 임포트 하는 경우
import {symbol1 as alias, symbol2} from "파일이름";
상태 변수는 값이 컨트랙트 스토리지에 영구적으로 저장되는 변수이다.
{데이터타입} {변수명}; // 변수명으로 선언
{데이터타입} {변수명} = {초기화할 값}; // 선언 및 초기화
--- example ---
pragma solidity ^0.8.7;
contract SimpleStorage {
uint storedData; // 상태 변수 선언
uint storedData = 20; // 상태 변수 선언 및 초기화
}
constant
constant를 통해 상태 변수를 상수로 선언하는 것도 가능하다.
pragma solidity ^0.8.7;
contract exmapleC {
unit256 public constant maxLimit = 1000;
}
bool isOpen = true;
bool isSold = false;
부호(양수, 음수)가 있는 경우는 int,
0 이상의 값만 존재하는 경우 uint
int, uint 둘 다 뒤에 8의 배수를 붙여 크기를 비트 단위로 지정할 수도 있다.
int8 seoulTemp = -20
uint16 myAge = 30
bytes1에서 bytes32까지의 고정된 크기의 배열을 선언할 수 있다.
bytes3 alphabets = 'abc'
alphabets[0] // 'a'
alphabets[1] // 'b'
alphabets[2] // 'c'
주소(address) 객체는 0x로 시작하고 최대 40자리의 16진수로 구성되는 문자열로 20바이트의 크기를 가진다.
주로 계정의 잔액을 반환하는 balance() 함수와 이더를 계정으로 전송하는 transfer() 함수에서 사용된다.
address yourAddress = 0x10abb5efEcdc01234f7b2384912398798E089Ab2;
0.8버전부터 단순 address 형식은 송금이 불가능한 주소값이다. 송금을 위해서는 뒤에 payable을 추가하여 지불이 일어날 수 있다는 점을 명시해줘야 한다.
address payable 형식에는 이더 송금을 위한 transfer()와 send() 함수 등이 내장되어 있다.
address addr1;
address payable p_addr1 = payable(addr1);
컨트랙트를 adress payable로 변환할 수도 있다.
만약 컨트랙트가 이더를 받을 수 있는 컨트랙트인 경우, address(컨트랙트)를 수행했을 때 address payable 형식의 주소값을 반환한다.
contract C { // 이더를 받을 수 있는 컨트랙트
constructor () payable { }
}
contract D { // 이더를 받지 않는 컨트랙트
constructor () { }
}
address payable addrC = address(C); // address(C)는 adress payable 형식의 주소값을 반환한다
address addrD = address(D); // address(D)는 adress 형식의 주소값을 반환한다
address payable addrD_p = payable(addrD); // payable()을 사용해 address payable 형식의 주소값을 만들 수 있다.
// 해당 값들은 순서에 따라 0,1,2와 같이 0부터 1씩 올라가는 정수도 값으로 가짐
//0 : Bad 1 : Soso 2 : Great
enum EvalLevel { Bad, Soso, Great}
EvalLevel kimcoding = EvalLevel.Bad
주소를 값으로 가지는 변수 타입
저장하고자 하는 데이터 형식에 []를 붙여 선언. uint8 형식의 배열을 만드는 경우 uint8[] 처럼 작성.
동적 배열 : uint[] {배열명} // 크기가 가변적
정적 배열 : uint[4] {배열명} // 크기가 고정
string name = 'tom';
contract exmapleC {
struct UserInfo {
address account;
string lastName;
string firstName;
}
//구조체 추가하는 함수
function newUser (address newAddress, string newLastName, string newFirstName){
UserInfo memory newOne = UserInfo({account: newAddress, lastName: newLastName, firstName: newFirstName})
}
}
mapping(address => int) public userAddress;
솔리디티 언어 자체에 내장되어 있는 변수이다.
블록에 대한 정보를 가진 변수
컨트랙트를 시작한 트랜잭션 콜이나 메시지 콜에 대한 정보를 가지고 있다
트랜잭션 데이터를 가진 변수
현재 컨트랙트를 참조하는 변수로 컨트랙트의 주소로 암시적으로 변환
솔리디티에서는 다음과 같이 함수를 선언한다.
function 함수이름(파라미터형식1 파라미터1, 파라미터형식2 파라미터2, ...) { ... }
//함수가 값을 반환하는 경우 아래와 같이 선언
function 함수이름(파라미터,...) returns (반환 형식) { ... }
view - 읽기 전용 함수. 스토리지의 자료를 읽을 수는 있지만 수정은 불가
pure - 스토리지의 변수를 읽거나 쓰지 않는 순수함수.
pragma solidity ^0.8.7;
contract exmapleC {
unit256 public constant maxLimit = 1000;
mapping(address => bool) public frozenAccount;
function checkGas(uint256 amount) private pure returns (bool) {
if (amount < maxLimit) return true;
return false;
}
function validateAccount(address account) internal view returns (bool) {
if (frozenAccount[account]) return true;
return false;
}
}
컨트랙트가 생성될 때 생성자 함수가 실행되어 컨트랙트의 상태를 초기화
pragma solidity ^0.8.7;
contract exmapleC {
address public account;
constructor(address _account) internal {
account = _account
}
}
selfdestruct 함수를 사용하여 컨트랙트를 소멸할 수 있다.
selfdestruct(컨트랙트 생성자의 주소);
함수를 선언할 때 modifier를 추가하여 함수가 실행되기 전, 요구 조건을 만족하는지 확인할 수 있다.
변경자를 작성할 때는 _; 를 사용하여 _; 를 기준으로
앞 부분은 함수 실행 전, 뒷 부분은 함수가 실행된 후에 적용되는 코드이다.
int public num = 0;
modifier changeNum {
num++; // 함수 실행 전 실행됨
_; // 함수 실행
num--; // 함수 실행 후 실행됨
}
function func() public changeNum {
if (num == 1) {
// do something
}
}
솔리디티에서 에러를 처리할 때는 assert, require, revert 함수를 사용한다.
솔리디티의 contract 객체는 상속을 지원하며 다중 상속도 가능하다.
contract ChildContract is ParentContract1, ParentContract2, ParentContract3 {
// ...
}
이벤트는 어떤 결과가 발생했을 때 해당 컨트랙트에서 dApp 클라이언트, 또는 다른 컨트랙트에게 전달하는 역할을 한다. 이벤트가 실행된 경우 트랜잭션에 기록된다.
event 키워드를 사용해 이벤트를 설정할 수 있으며,
emit 키워드를 사용해 이벤트를 실행한다.
contract coinTransfer {
// event 이벤트명(파라미터유형1 파라미터1, 파라미터유형2 파라미터2, ...);
event Transfer(address from, address to, uint256 value);
function transfer(address to, address amount) {
//...
// emit 이벤트명(인자1, 인자2 ...)
emit Transfer(msg.sender, to, amount);
}
}