Blockchain
[Solidity] 6.매핑(Mapping)과 배열(Array)
clolee
2025. 4. 17. 23:26
✅ 6. 매핑(Mapping)과 배열(Array)
Solidity의 데이터 저장 구조의 핵심
📌 1. 매핑 (Mapping)
✅ 정의
Solidity의 핵심 자료구조.
Key → Value 쌍으로 데이터를 저장하며, 해시테이블처럼 작동합니다.
mapping(address => uint) public balances;
balances[0x123...] = 100;
처럼 사용- 기본값 자동 초기화 (해당 키가 없으면 0 반환)
✅ 특징
특징 | 설명 |
---|---|
검색 빠름 | 해시 기반으로 즉시 접근 |
전체 순회 불가 | 키 목록을 직접 저장하지 않으면 전체 조회 불가 |
기본값 존재 | 존재하지 않는 키에 접근 시에도 오류 발생하지 않음 (기본값 반환) |
중첩 가능 | mapping(address => mapping(uint => bool)) 가능 |
✅ 실무 예시
mapping(address => bool) public hasVoted;
mapping(address => mapping(uint => uint)) public stakeByPool;
📌 2. 배열 (Array)
✅ 정의
같은 타입의 요소들을 순차적으로 나열하는 자료구조
uint[] public numbers;
✅ 동적 배열 vs 정적 배열
유형 | 예시 | 특징 |
---|---|---|
동적 배열 | uint[] |
길이 가변적 (push , pop 사용 가능) |
정적 배열 | uint[10] |
고정 크기, 길이 변경 불가 |
✅ 배열 함수
함수 | 설명 |
---|---|
.length |
배열 길이 반환 |
.push(val) |
끝에 요소 추가 (동적만 가능) |
.pop() |
마지막 요소 제거 |
arr[i] |
인덱스 접근 |
delete arr[i] |
값 제거 (단, 배열 크기는 유지됨) |
✅ 예시
uint[] public values;
function addValue(uint _val) public {
values.push(_val);
}
function getValue(uint index) public view returns (uint) {
return values[index];
}
📌 3. 매핑 + 배열 조합 패턴 (실무 핵심)
전체 사용자 데이터를 순회하거나 삭제할 수 없기 때문에
매핑으로 빠른 접근 + 배열로 인덱스 관리 패턴이 매우 자주 사용됩니다.
mapping(address => uint) public balances;
address[] public holders;
function deposit() public payable {
if (balances[msg.sender] == 0) {
holders.push(msg.sender); // 최초 입금자만 등록
}
balances[msg.sender] += msg.value;
}
📌 4. 매핑 + Struct 조합
struct User {
string name;
uint score;
}
mapping(address => User) public users;
- 필드 접근:
users[msg.sender].name
📌 5. 배열 삭제의 주의점
delete arr[1]; // 해당 인덱스의 값은 초기화되지만
// 배열 길이는 그대로! → arr.length 그대로 유지됨
→ 정렬, 재배치 필요 시 for
반복문으로 수동 처리
✅ 실전 예제
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
contract Registry {
struct Info {
string name;
uint age;
}
mapping(address => Info) public infoMap;
address[] public registeredUsers;
function register(string memory _name, uint _age) public {
if (bytes(infoMap[msg.sender].name).length == 0) {
registeredUsers.push(msg.sender);
}
infoMap[msg.sender] = Info(_name, _age);
}
function getUserCount() public view returns (uint) {
return registeredUsers.length;
}
}
🧠 실무 팁 정리
항목 | 설명 |
---|---|
매핑은 개별 접근에 적합 | 반복 불가, 전체 조회하려면 배열 필요 |
배열은 순회에 적합 | 특정 값 찾기는 비효율적 (O(n) ) |
매핑 + 배열 | 보편적인 실무 패턴 |
delete는 요소만 제거 | 길이는 그대로, 재배치 필요 |
mapping + struct | 모델링할 때 가장 흔히 쓰임 |
✅ [6단계 요약]
항목 | 설명 |
---|---|
mapping(key => value) |
주소 → 값, 토큰ID → 소유자 등 |
uint[] , address[] |
순서가 중요한 데이터 |
조합 사용 | mapping + array , mapping + struct |
반복문으로 배열 탐색 | 가스 비용 높으니 꼭 필요할 때만 |