본문 바로가기
Blockchain

[Solidity] 4. 제어 구조 & 연산자 (조건문, 반복문, 오류 처리)

by clolee 2025. 4. 17.

✅ 4. 제어 구조 & 연산자 (조건문, 반복문, 오류 처리)

스마트컨트랙트의 흐름 제어조건 검사, 오류 처리에 필수적인 기능들인 제어 구조(Control Flow) & 연산자
비즈니스 로직 검증, 보안 취약점 방지, 오류 발생 최소화에 매우 중요


📌 1. 조건문: if, else, require, revert, assert

if, else

if (balance[msg.sender] >= 1 ether) {
    // 처리 로직
} else {
    revert("Insufficient balance");
}
  • 일반적인 조건 분기
  • Solidity는 elseif 대신 else if 사용

📌 2. 입력 검증 및 오류 처리

구문 사용 용도 특징
require(condition, "error") 입력값, 권한 등 조건 검사 조건이 false면 트랜잭션 revert + 남은 가스 환불
revert("message") 명시적 에러 반환 더 복잡한 조건 처리 가능
assert(condition) 내부 논리 오류 체크 (절대 false면 안됨) 실패 시 전체 가스 소모 (개발자 실수 검출용)

🧠 실무 팁:

  • require: 사용자 잘못 방지 (권한, 입력값)
  • assert: 절대 발생하면 안 되는 경우 (내부 버그 탐지)
  • revert: 커스텀 에러와 함께 사용 가능 (0.8.0 이상)

✅ 예제

function withdraw(uint amount) public {
    require(amount <= balance[msg.sender], "Not enough funds");
    balance[msg.sender] -= amount;
    payable(msg.sender).transfer(amount);
}

📌 3. 반복문: for, while

for

for (uint i = 0; i < users.length; i++) {
    total += balances[users[i]];
}
  • EVM에서 반복문은 가스 소비량이 매우 높음
  • 반복 횟수가 고정되거나 작을 경우만 사용

while

uint i = 0;
while (i < users.length) {
    // 반복 처리
    i++;
}

🧠 실무 주의:

  • 반복문이 길어지면 Out of Gas (OOG) 발생
  • 대규모 반복은 off-chain 처리 후 결과만 on-chain 기록하는 구조 권장

📌 4. 논리 연산자 & 조건 비교 연산자

연산자 설명
==, != 같음, 다름
<, <=, >, >= 비교
&&, `  
! NOT
+=, -=, *= 축약 연산자

✅ 예제

function isValid(uint a, uint b) public pure returns (bool) {
    return (a > 0 && b < 100);
}

📌 5. 커스텀 에러 (0.8.4 이상)

error NotOwner(address caller);

function update() public {
    if (msg.sender != owner) {
        revert NotOwner(msg.sender);
    }
}

✅ 장점

  • 에러 메시지 대신 바이트코드로 인코딩가스 절감
  • 반환값에 주소 등 동적 정보 포함 가능

✅ 실전 예제

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;

contract Voting {
    address public owner;
    mapping(address => bool) public voted;

    constructor() {
        owner = msg.sender;
    }

    function vote() public {
        require(!voted[msg.sender], "Already voted");
        voted[msg.sender] = true;
    }

    function adminReset(address user) public {
        require(msg.sender == owner, "Only owner");
        voted[user] = false;
    }
}

🧠 실무 최적화 요약

항목 전략
require 입력값, 권한 체크에 필수
assert 논리적 불변 조건 검증 (오용 주의!)
반복문 반드시 제한된 크기에서만 사용. 가변 반복은 피할 것
커스텀 에러 에러 메시지 대신 가스 절약 목적 사용 권장
복잡한 조건 괄호 ( )로 묶어서 가독성 확보

✅ [4단계 요약]

키워드 설명
if, else, for, while 기본 제어문
require 조건 실패 시 예외 + 가스 환불
revert, assert 명시적 예외 처리, 내부 검증
논리/비교 연산자 조건 분기에 필수
커스텀 에러 가스 절약 + 의미 있는 예외 전달 (0.8.4+)

댓글