Menu
Coddy logo textTech

Solidity 치트시트

컨트랙트 구조

모든 파일은 라이선스와 pragma로 시작합니다. 컨트랙트는 배포의 단위입니다.

문법의미
// SPDX-License-Identifier: MIT컴파일러가 1행에 기대하는 라이선스 주석
pragma solidity ^0.8.0;파일이 대상으로 하는 컴파일러 버전
contract Counter { ... }컨트랙트 선언(상태 + 함수)
constructor(uint start) { count = start; }배포 시 한 번만 실행
import "./Token.sol";다른 파일 가져오기
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";라이브러리 패키지 가져오기
interface IToken { function balanceOf(address a) external view returns (uint); }인터페이스 선언(본문 없음)
library Math { function min(uint a, uint b) internal pure returns (uint) { ... } }재사용 가능한 함수 라이브러리

값 타입

정수는 크기가 고정되어 있고 소수가 없습니다. 0.8은 오버플로 시 revert합니다.

타입담는 값
uint256 / uint부호 없는 정수, 0부터 2^256 - 1까지(uintuint256)
uint8, uint16, ... uint1288비트 단위의 더 작은 부호 없는 정수
int256 / int부호 있는 정수(음수 허용)
booltrue 또는 false
address20바이트 계정 또는 컨트랙트 주소
address payabletransfer/send로 Ether를 받을 수 있는 주소
bytes32, bytes1...고정 크기 바이트 배열
enum Status { Open, Closed }이름 붙은 상수 집합, uint8로 저장
1 ether, 1 gwei, 1 weiEther 단위: 1 ether = 10^18 wei
1 days, 2 hours, 30 minutes시간 단위(초 기준)

참조 타입과 데이터 위치

배열, 문자열, bytes, struct, mapping은 storage, memory, calldata 중 한 곳에 위치합니다.

문법의미
string memory name동적 UTF-8 문자열(임시 복사본)
bytes memory data동적 바이트 배열
uint[] public scores;storage의 동적 배열
uint[3] fixed;크기 3의 고정 배열
uint[] memory tmp = new uint[](5);memory 배열 할당
scores.push(42);storage 배열 끝에 추가
scores.pop();마지막 요소 제거
scores.length요소 개수
storage영구적, 온체인, 쓰기 비용이 높음
memory임시적, 한 번의 호출 동안만 유지
calldata읽기 전용 external 함수 입력, 가장 저렴

mapping과 struct

mapping은 길이도 반복도 없는 해시 테이블이고, struct는 필드를 묶습니다.

문법의미
mapping(address => uint) public balances;키-값 저장소, 모든 키가 존재(기본값 0)
balances[msg.sender] += 1;키로 읽기/쓰기
mapping(address => mapping(address => uint)) allowance;중첩 mapping
struct User { string name; uint age; bool active; }struct 정의
User memory u = User("Ada", 36, true);memory에 struct 생성
User memory u = User({name: "Ada", age: 36, active: true});이름 붙은 필드로 생성
users[msg.sender] = u;struct를 mapping에 저장
users[msg.sender].age = 37;storage의 필드 하나 수정
delete users[msg.sender];기본값으로 초기화

함수와 가시성

모든 함수는 누가 호출할 수 있는지, 상태를 읽는지 쓰는지를 명시합니다.

문법의미
function add(uint a, uint b) public pure returns (uint) { return a + b; }매개변수와 반환값이 있는 함수
public어디서든 호출 가능(내부와 외부)
external컨트랙트 외부에서만 호출 가능
internal이 컨트랙트와 이를 상속하는 컨트랙트
private이 컨트랙트에서만
view상태를 읽되 쓰지 않음
pure상태를 전혀 읽지 않음
payable호출과 함께 Ether를 받을 수 있음
returns (uint sum, bool ok)이름 붙은 여러 반환값
(uint s, bool ok) = f();여러 반환값을 구조 분해
uint public count;public 상태 변수에는 getter count()가 자동 생성됨

modifier, 상수, 상속

modifier로 검사를 재사용하고, constant와 immutable로 값을 고정합니다.

문법의미
modifier onlyOwner() { require(msg.sender == owner, "Not owner"); _; }modifier 정의(_ = 함수 본문 실행)
function withdraw() public onlyOwner { ... }modifier 적용
uint public constant MAX = 100;컴파일 타임 상수
address public immutable owner;생성자에서 한 번 설정한 뒤 고정
contract Token is ERC20, Ownable { ... }다른 컨트랙트 상속
function f() public virtual { ... }오버라이드 허용
function f() public override { ... }부모 함수 오버라이드
super.f();부모 구현 호출
abstract contract Base { function f() public virtual; }구현되지 않은 함수가 있는 컨트랙트

제어 흐름

C 계열 언어의 일반적인 문장입니다. switch는 없고, 루프는 반복마다 가스가 듭니다.

문법의미
if (x > 5) { ... } else if (x > 2) { ... } else { ... }조건 분기
for (uint i = 0; i < n; i++) { ... }카운터 루프
while (x < 10) { x++; }조건이 참인 동안 반복
do { ... } while (cond);최소 한 번 실행
break; / continue;루프 탈출 / 다음 반복으로 건너뛰기
x > 0 ? a : b삼항 표현식
a / b정수 나눗셈(나머지 버림)
a % b나머지
a ** 2거듭제곱
unchecked { x++; }오버플로 검사 생략(가스 절약, 주의해서 사용)

오류: require, revert, assert

검사가 실패하면 트랜잭션 전체가 되돌려지고 사용하지 않은 가스는 환불됩니다.

문법의미
require(amount > 0, "Amount must be positive");입력이나 상태 검증, 메시지와 함께 revert
revert("Not allowed");무조건 중단
error Insufficient(uint available, uint requested);커스텀 오류 선언(문자열보다 저렴)
revert Insufficient(balance, amount);커스텀 오류로 revert
assert(total == a + b);절대 실패해서는 안 되는 불변 조건 검사
try token.transfer(to, amt) returns (bool ok) { ... } catch { ... }실패하는 외부 호출 처리

이벤트

이벤트는 오프체인 앱이 구독할 수 있는 로그를 기록합니다. 컨트랙트에서는 읽을 수 없습니다.

문법의미
event Transfer(address indexed from, address indexed to, uint value);이벤트 선언
emit Transfer(msg.sender, to, amount);이벤트 발생
indexed필터링 가능한 매개변수(이벤트당 최대 3개)
event Log(string message);모든 ABI 타입을 로그로 남길 수 있음

Ether, 주소, 전역 변수

트랜잭션 컨텍스트는 msg, block, tx에서 가져옵니다.

문법의미
msg.sender이 함수를 호출한 주소
msg.value호출과 함께 보낸 wei(payable 필요)
block.timestamp현재 블록 시간(에포크 이후 초)
block.number현재 블록 높이
tx.origin트랜잭션을 시작한 외부 소유 계정(인증에는 사용 금지)
address(this).balance이 컨트랙트의 Ether 잔액
payable(to).transfer(1 ether);Ether 전송, 실패 시 revert
(bool ok, ) = to.call{value: amt}("");저수준 전송, 성공 플래그 반환
receive() external payable {}단순 Ether 전송 시 실행
fallback() external payable {}일치하는 함수가 없을 때 실행
keccak256(abi.encodePacked(a, b))값 해시
abi.encode(x), abi.decode(data, (uint))ABI 데이터 인코딩 / 디코딩

자주 찾는 Solidity 문법을 한 페이지에 모았습니다. 이 Solidity 치트시트는 Ethereum과 모든 EVM 체인의 스마트 컨트랙트 언어를 위한 빠른 참고 자료입니다. 컨트랙트 선언, 타입 선택, mapping과 struct에 데이터 저장, 올바른 가시성과 상태 변경 가능성을 가진 함수 작성, 그리고 require, modifier, 이벤트로 함수를 보호하는 방법까지 다룹니다.

여기서 다루는 문법은 Solidity 0.8입니다. 기본적으로 산술 오버플로를 검사하며 Remix, Hardhat, Foundry에서 동작합니다. 필요한 부분을 복사하거나 Solidity 플레이그라운드에서 바로 실행해 보세요. 컨트랙트를 작성하고 컴파일해 브라우저 속 EVM에서 실행할 수 있습니다.

Solidity cheat sheet FAQ

Is this Solidity cheat sheet free?
Yes. This cheat sheet is free to use, with no sign-up required. Bookmark it and come back any time you need a quick reference.
Is this cheat sheet good for beginners?
Yes. It is organized by topic so you can find what you need at any level, and each entry links back to Coddy's free interactive Solidity course when you want to go deeper.
Coddy programming languages illustration

Coddy로 Solidity 배우기

시작하기