solidity: patterns

Solidity patterns

์†”๋ฆฌ๋””ํ‹ฐ์˜ ๋‹ค์–‘ํ•œ ํŒจํ„ด์— ๋Œ€ํ•ด์„œ ๋‹ค๋ฃจ์–ด๋ณด๋ ค๊ณ  ํ•œ๋‹ค.

์•„๋ž˜ ๋งํฌ๋ฅผ ์ฐธ๊ณ ํ•ด์„œ ์“ฐ์—ฌ์ง„ ๊ธ€์ด๋ฉฐ, ๋ณธ ๊ธ€์—์„œ๋Š” ๋ชจ๋“  ๋‚ด์šฉ์„ ๋‹ด๊ณ  ์žˆ์ง€๋Š” ์•Š๋‹ค.

Guard Check

Guard๋ฅผ ํ†ตํ•ด ์Šค๋งˆํŠธ ์ปจํŠธ๋ž™ํŠธ ๋ฐ ํ•ด๋‹น ์ž…๋ ฅ ๋งค๊ฐœ๋ณ€์ˆ˜์˜ ์œ ํšจ์„ฑ์„ ๊ฒ€์ฆ.

์Šค๋งˆํŠธ ์ปจํŠธ๋ž™ํŠธ์˜ ๋ฐ”๋žŒ์งํ•œ ๋™์ž‘์€ ํ•„์š”ํ•œ ๋ชจ๋“  ์ƒํ™ฉ์„ ํ™•์ธํ•˜๊ณ  ๋ชจ๋“  ๊ฒƒ์ด ์˜๋„ํ•œ ๋Œ€๋กœ์ธ ๊ฒฝ์šฐ์—๋งŒ ์ง„ํ–‰ํ•˜๋Š” ๊ฒƒ์ด๋‹ค.

์ด๋ฅผ Guard Check Pattern์ด๋ผ๊ณ  ํ•œ๋‹ค.

๋‹จ์ˆœ require ๋ฌธ์„ ํ™œ์šฉํ•ด๋„ ์ข‹๊ณ , modifier๋ฅผ ํ™œ์šฉํ•ด๋„ ์ข‹๋‹ค.

// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.0;

contract GuardCheck {
    modifier addressGuard(address addr) {
        require(addr != address(0), "address should be a valid address");

        _;
    }

    modifier valueGuard(uint value) {
        require(msg.value != 0, "msg.value should be a valid value");

        _;
    }

    function donate(
        address addr
    ) public payable addressGuard(addr) valueGuard(msg.value) {
        // ...
    }
}

State Machine

์Šค๋งˆํŠธ ์ปจํŠธ๋ž™ํŠธ์—์„œ ์„œ๋น„์Šค ๋กœ์ง์„ ๊ตฌํ˜„ํ•˜๋Š” ๊ฒฝ์šฐ, ์ƒ์•  ์ฃผ๊ธฐ๋ฅผ ๊ด€๋ฆฌํ•ด์•ผ ํ•˜๋Š” ๊ฒฝ์šฐ๊ฐ€ ์žˆ๋‹ค.

์‹œ๊ฐ„์— ๋”ฐ๋ผ์„œ, ๋‹จ๊ณ„์— ๋”ฐ๋ผ์„œ ๋“ฑ ๋‹ค์–‘ํ•œ ๊ฒฝ์šฐ๊ฐ€ ์žˆ์„ ์ˆ˜ ์žˆ๋‹ค.

๋‹ค์Œ๊ณผ ๊ฐ™์€ ๊ฒฝ์šฐ์— ์ƒํƒœ๋ฅผ ๊ฐ€์ง€๋„๋ก ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ๋‹ค.

  • ์Šค๋งˆํŠธ ์ปจํŠธ๋ž™ํŠธ๋Š” ์ˆ˜๋ช… ์ฃผ๊ธฐ๋™์•ˆ ์—ฌ๋Ÿฌ ๋‹จ๊ณ„๋กœ ์ „ํ™˜ํ•ด์•ผํ•œ๋‹ค.

  • ์Šค๋งˆํŠธ ์ปจํŠธ๋ž™ํŠธ์˜ ๊ธฐ๋Šฅ์€ ํŠน์ • ๋‹จ๊ณ„์—์„œ๋งŒ ์ ‘๊ทผ ๊ฐ€๋Šฅํ•ด์•ผํ•œ๋‹ค.

  • ์‚ฌ์šฉ์ž์˜ ํ–‰๋™์— ๋”ฐ๋ผ์„œ ์Šค๋งˆํŠธ ์ปจํŠธ๋ž™ํŠธ์˜ ์ƒํƒœ๊ฐ€ ๋ณ€๊ฒฝ๋˜์–ด์•ผ ํ•œ๋‹ค.

Solidity ์—์„œ๋Š” ๋‹ค์–‘ํ•œ ๋‹จ๊ณ„๋ฅผ ๋ชจ๋ธ๋งํ•˜๊ธฐ ์œ„ํ•ด enum์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

ํŠน์ • ๋‹จ๊ณ„์— ๋Œ€ํ•œ ๊ธฐ๋Šฅ ์•ก์„ธ์Šค ์ œํ•œ์€ ๋’ค์—์„œ ๋‹ค๋ฃฐ Access Restriction์„ ํ™œ์šฉํ•˜๋ฉด ๋œ๋‹ค.

์œ„์—์„œ ๋‹ค๋ฃฌ Guard Check ํŒจํ„ด๊ณผ ๊ด€๋ จ์ด ์žˆ์œผ๋‚˜ ์ค‘๊ตฌ๋‚œ๋ฐฉ์œผ๋กœ ์ง„ํ–‰ํ•˜๋ฉด ์ •์‹ ์—†์œผ๋‹ˆ ์ผ๋‹จ State Machine์˜ ์ฝ”๋“œ๋ฅผ ๋ณด๊ณ  ๋„˜์–ด๊ฐ€๋ณด์ž.

์œ„์˜ ์˜ˆ์‹œ๋Š” Stage์— ๋”ฐ๋ผ ์ปจํŠธ๋ž™ํŠธ ์ž์ฒด์˜ ์ƒํƒœ๊ฐ€ ๋ฐ”๋€๋‹ค.

Access Restriction

์Šค๋งˆํŠธ ์ปจํŠธ๋ž™ํŠธ๋Š” ๋ธ”๋ก์ฒด์ธ์— ๋ฐฐํฌ๋˜๋ฉด ๋ˆ„๊ตฌ๋‚˜ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋‹ค.

๊ณต๊ฐœ์ ์ธ ํŠน์„ฑ์œผ๋กœ ์ธํ•ด ์Šค๋งˆํŠธ ์ปจํŠธ๋ž™ํŠธ์— ๋Œ€ํ•œ ์™„์ „ํ•œ ์ •๋ณด ๋ณดํ˜ธ๋ฅผ ๋ณด์žฅํ•˜๋Š” ๊ฒƒ์€ ๋ถˆ๊ฐ€๋Šฅ์— ๊ฐ€๊น๋‹ค.

๋ชจ๋“  ์ •๋ณด๊ฐ€ ๋ชจ๋‘์—๊ฒŒ ํ‘œ์‹œ๋˜๊ธฐ๋•Œ๋ฌธ์— ๋ˆ„๊ตฐ๊ฐ€๊ฐ€ ๋ธ”๋ก์ฒด์ธ์—์„œ ์ปจํŠธ๋ž™ํŠธ ์ƒํƒœ๋ฅผ ์ฝ๋Š” ๊ฒƒ์„ ๋ง‰์„์ˆ˜๊ฐ€ ์—†๋‹ค.

ํ•จ์ˆ˜๋ฅผ private์œผ๋กœ ์„ ์–ธํ•˜๋Š” ์„ ํƒ์ง€๋„ ์žˆ์ง€๋งŒ, ๊ทธ๋ ‡๊ฒŒ ํ•˜๋ฉด ๋ชจ๋“  ์‚ฌ๋žŒ์ด ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•  ์ˆ˜ ์—†๊ฒŒ๋œ๋‹ค.

์ด๋Ÿฐ ๊ฒฝ์šฐ, GuardCheck, StateMachine ํŒจํ„ด๊ณผ ํ•จ๊ป˜ ์‚ฌ์šฉํ•˜๋ฉด ์ข‹๋‹ค.

private ์€ smart contract์˜ ์ธํ„ฐํŽ˜์ด์Šค๋กœ ๋น„๊ณต๊ฐœํ•œ๋‹ค.

์ปจํŠธ๋ž™ํŠธ ๋‚ด๋ถ€์—์„œ๋งŒ ์‚ฌ์šฉํ•œ๋‹ค.

์ƒ์† ๋ฐ›์€ ์ปจํŠธ๋ž™ํŠธ์—์„œ๋„ ์‚ฌ์šฉ ๋ถˆ๊ฐ€๋Šฅํ•˜๋‹ค.

external์€ smart contract์˜ ์ธํ„ฐํŽ˜์ด์Šค๋กœ ๊ณต๊ฐœํ•œ๋‹ค.

์ปจํŠธ๋ž™ํŠธ ๋‚ด๋ถ€์—์„œ ํ˜ธ์ถœํ•  ๊ฒฝ์šฐ this๋ฅผ ์‚ฌ์šฉํ•ด์„œ ์ ‘๊ทผํ•ด์•ผ ํ•œ๋‹ค.

internal์€ smart contract์˜ ์ธํ„ฐํŽ˜์ด์Šค๋กœ ๋น„๊ณต๊ฐœํ•œ๋‹ค.

์ปจํŠธ๋ž™ํŠธ ๋‚ด๋ถ€์—์„œ๋งŒ ์‚ฌ์šฉํ•œ๋‹ค.

์ƒ์† ๋ฐ›์€ ์ปจํŠธ๋ž™ํŠธ์—์„œ๋„ ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•˜๋‹ค.

public์€ smart contract์˜ ์ธํ„ฐํŽ˜์ด์Šค๋กœ ๊ณต๊ฐœํ•œ๋‹ค.

์ปจํŠธ๋ž™ํŠธ์˜ ๋‚ด๋ถ€์™€ ์™ธ๋ถ€์—์„œ ๋ชจ๋‘ ํ˜ธ์ถœํ•  ์ˆ˜ ์žˆ๋‹ค.

์ปจํŠธ๋ž™ํŠธ ๋‚ด๋ถ€์—์„œ ํ˜ธ์ถœํ•  ๊ฒฝ์šฐ this๋ฅผ ์‚ฌ์šฉํ•ด์„œ ์ ‘๊ทผํ•ด์•ผ ํ•œ๋‹ค.

OpenZeppelin์˜ Ownable์„ ํ™œ์šฉํ•˜๋ฉด ๋”์šฑ ๊ฐ„๋‹จํ•˜๊ฒŒ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ๋‹ค.

Last updated