Web3 완벽 마스터
Web3의 핵심 개념과 실전 활용법
학습 항목
이미지 로딩 중...
Solidity 핵심 개념 완벽 정리
스마트 컨트랙트 개발을 위한 Solidity의 핵심 개념을 실전 예제와 함께 학습합니다. 상태 변수, 함수, 제어자, 이벤트 등 중급 개발자가 꼭 알아야 할 내용을 다룹니다.
들어가며
이 글에서는 Solidity 핵심 개념 완벽 정리에 대해 상세히 알아보겠습니다. 총 12가지 주요 개념을 다루며, 각각의 개념에 대한 설명과 실제 코드 예제를 함께 제공합니다.
목차
- 상태_변수와_가시성
- 함수_제어자_Modifier
- 이벤트_Event_로깅
- Mapping_데이터_구조
- Payable_함수와_이더_전송
- Constructor_초기화
- Require_Assert_Revert
- Struct_사용자_정의_타입
- View와_Pure_함수
- Storage와_Memory_데이터_위치
- Inheritance_상속
- Fallback과_Receive_함수
1. 상태_변수와_가시성
개요
스마트 컨트랙트의 상태를 저장하는 변수와 접근 제어자(public, private, internal)의 사용법을 배웁니다.
코드 예제
contract Storage {
uint256 public publicData = 100;
uint256 private privateData = 200;
uint256 internal internalData = 300;
function getPrivateData() public view returns (uint256) {
return privateData;
}
}
설명
public은 자동으로 getter 함수가 생성되고, private는 컨트랙트 내부에서만 접근 가능하며, internal은 상속받은 컨트랙트에서도 접근할 수 있습니다.
2. 함수_제어자_Modifier
개요
함수 실행 전/후에 조건을 검사하거나 로직을 추가하는 modifier를 사용하여 코드 재사용성을 높입니다.
코드 예제
contract Ownable {
address public owner;
modifier onlyOwner() {
require(msg.sender == owner, "Not owner");
_;
}
function changeOwner(address newOwner) public onlyOwner {
owner = newOwner;
}
}
설명
onlyOwner modifier는 함수 실행 전 호출자가 owner인지 검증하며, _는 실제 함수 본문이 실행되는 위치를 나타냅니다.
3. 이벤트_Event_로깅
개요
블록체인에 로그를 기록하고 외부 애플리케이션에서 감지할 수 있는 이벤트를 정의하고 발생시킵니다.
코드 예제
contract TokenTransfer {
event Transfer(address indexed from, address indexed to, uint256 amount);
function transfer(address to, uint256 amount) public {
// 전송 로직
emit Transfer(msg.sender, to, amount);
}
}
설명
indexed 키워드를 사용하면 해당 파라미터로 필터링이 가능하며, emit으로 이벤트를 발생시켜 프론트엔드에서 감지할 수 있습니다.
4. Mapping_데이터_구조
개요
키-값 쌍으로 데이터를 저장하는 mapping은 Solidity에서 가장 많이 사용되는 자료구조입니다.
코드 예제
contract UserRegistry {
mapping(address => uint256) public balances;
mapping(address => mapping(uint256 => bool)) public permissions;
function deposit() public payable {
balances[msg.sender] += msg.value;
}
}
설명
mapping은 해시테이블과 유사하며, 중첩 mapping을 사용하여 복잡한 권한 관리도 가능합니다. 모든 키는 초기값을 가집니다.
5. Payable_함수와_이더_전송
개요
이더를 받을 수 있는 payable 함수와 안전한 이더 전송 방법을 학습합니다.
코드 예제
contract Payment {
function deposit() public payable {
require(msg.value > 0, "Must send ETH");
}
function withdraw(uint256 amount) public {
payable(msg.sender).transfer(amount);
}
}
설명
payable 키워드가 있어야 이더를 받을 수 있으며, transfer 함수는 2300 gas 제한으로 재진입 공격을 방지합니다.
6. Constructor_초기화
개요
컨트랙트 배포 시 한 번만 실행되는 생성자로 초기 상태를 설정합니다.
코드 예제
contract Token {
address public owner;
uint256 public totalSupply;
constructor(uint256 _initialSupply) {
owner = msg.sender;
totalSupply = _initialSupply;
}
}
설명
constructor는 배포 시 한 번만 호출되어 owner와 초기 공급량을 설정하며, 배포 후에는 변경할 수 없습니다.
7. Require_Assert_Revert
개요
조건 검증과 에러 처리를 위한 세 가지 주요 함수의 차이점과 사용법을 이해합니다.
코드 예제
contract Validation {
function withdraw(uint256 amount) public {
require(amount > 0, "Amount must be positive");
assert(address(this).balance >= amount);
if (msg.sender == address(0)) {
revert("Invalid address");
}
}
}
설명
require는 입력 검증에 사용하고 가스를 환불하며, assert는 내부 오류 체크용이고, revert는 복잡한 조건에서 명시적으로 되돌립니다.
8. Struct_사용자_정의_타입
개요
여러 데이터를 하나로 묶는 구조체를 정의하여 복잡한 데이터를 효율적으로 관리합니다.
코드 예제
contract UserManagement {
struct User {
string name;
uint256 age;
bool isActive;
}
mapping(address => User) public users;
function createUser(string memory _name, uint256 _age) public {
users[msg.sender] = User(_name, _age, true);
}
}
설명
struct로 관련 데이터를 그룹화하고, mapping과 함께 사용하여 각 주소마다 사용자 정보를 저장할 수 있습니다.
9. View와_Pure_함수
개요
상태를 변경하지 않는 읽기 전용 함수와 상태를 읽지도 않는 순수 함수를 구분하여 가스 효율을 높입니다.
코드 예제
contract Calculator {
uint256 public value = 10;
function getValue() public view returns (uint256) {
return value;
}
function add(uint256 a, uint256 b) public pure returns (uint256) {
return a + b;
}
}
설명
view는 상태 변수를 읽을 수 있고, pure는 상태 변수에 접근하지 않습니다. 외부 호출 시 가스가 들지 않습니다.
10. Storage와_Memory_데이터_위치
개요
데이터가 저장되는 위치를 명시하여 가스 비용을 최적화하고 의도하지 않은 데이터 변경을 방지합니다.
코드 예제
contract DataLocation {
uint256[] public numbers;
function addNumber(uint256 num) public {
numbers.push(num);
}
function getNumbers() public view returns (uint256[] memory) {
return numbers;
}
}
설명
storage는 블록체인에 영구 저장되고 비용이 높으며, memory는 함수 실행 중에만 존재하여 비용이 낮습니다.
11. Inheritance_상속
개요
기존 컨트랙트의 기능을 재사용하고 확장하는 상속을 통해 코드 중복을 줄입니다.
코드 예제
contract Base {
uint256 public value;
function setValue(uint256 _value) public virtual {
value = _value;
}
}
contract Derived is Base {
function setValue(uint256 _value) public override {
value = _value * 2;
}
}
설명
is 키워드로 상속하고, virtual/override로 함수를 재정의합니다. Derived는 Base의 모든 기능을 물려받아 확장합니다.
12. Fallback과_Receive_함수
개요
존재하지 않는 함수 호출이나 이더 전송을 처리하는 특수 함수들을 이해합니다.
코드 예제
contract FallbackExample {
event Received(address sender, uint256 amount);
receive() external payable {
emit Received(msg.sender, msg.value);
}
fallback() external payable {
// 알 수 없는 함수 호출 처리
}
}
설명
receive는 순수 이더 전송 시 호출되고, fallback은 매칭되는 함수가 없거나 데이터가 포함된 경우 호출됩니다.
마치며
이번 글에서는 Solidity 핵심 개념 완벽 정리에 대해 알아보았습니다. 총 12가지 개념을 다루었으며, 각각의 사용법과 예제를 살펴보았습니다.
관련 태그
#Solidity #SmartContract #Ethereum #Blockchain #Web3