---
title: "Solidity에서 mapping이란?"
description: "Solidity에서 mapping이 작동하는 방식 알아보기"
---

# Solidity에서 mapping이란?

[Solidity](https://www.alchemy.com/overviews/solidity)의 매핑(Mapping)은 키-값 쌍으로 데이터를 저장하는 해시 테이블로, 여기서 키는 Ethereum이 지원하는 내장 데이터 타입 중 어떤 것이든 될 수 있습니다. 매핑은 [Solidity 개발을 학습](https://www.alchemy.com/overviews/learn-solidity)할 때 이해해야 할 핵심 개념입니다.

이 글에서는 매핑이 무엇인지, 매핑이 어떻게 작동하는지, 매핑과 배열의 차이점을 설명하고, Ethereum 및 Optimism, Arbitrum과 같은 Solidity 호환 블록체인에서 최상의 스마트 컨트랙트를 개발할 수 있도록 매핑의 예시를 제공합니다.

## **해시 테이블이란?**

해시 테이블은 데이터를 연관 방식으로 저장하는 자료구조입니다. 해시 테이블에서 데이터는 배열 형태로 유지되며, 각 데이터 값은 고유한 인덱스 값을 가집니다. 해시 테이블은 배열을 저장 매체로 사용하고, 해시 기법을 이용해 요소를 삽입하거나 찾을 인덱스를 결정합니다.

<ImageBlock
  src="https://media.alchemy.com/1703922693-mapping-in-solidity.png"
  alt="Doug Crescenzi가 설명하는 Solidity의 Mappings"
  width={429}
  height={329}
  caption="출처: Doug Crescenzi가 설명하는 Solidity의 Mappings"
/>

필요한 데이터의 인덱스를 알고 있으면 매우 빠르게 값을 반환받을 수 있습니다. 이 때문에 해시 테이블은 데이터의 양과 관계없이 삽입과 검색 연산이 매우 빠른 자료구조입니다.

## **Solidity의 매핑이란?**

매핑은 Solidity의 해시 테이블로, 키-값 쌍으로 데이터를 저장하며, 키는 참조 타입을 제외한 내장 데이터 타입 중 하나가 될 수 있고, 값의 데이터 타입은 어떤 타입이든 가능합니다.

매핑은 주로 Solidity와 Ethereum 블록체인에서 고유한 Ethereum 주소를 해당하는 값 타입과 연결하는 데 사용됩니다.

다른 프로그래밍 언어에서 매핑은 딕셔너리(dictionary)에 해당합니다.

### 해시 테이블과 Solidity 매핑의 차이는 무엇인가요?

매핑은 키 타입과 그에 대응하는 값 타입 쌍을 가진 해시 테이블처럼 작동하며, 다수의 **\_KeyType**을 **\_ValueType**에 대응시킬 수 있다는 점에서 유용합니다. 매핑에는 길이 개념이 없으며, 키나 값이 "설정되어 있다"는 개념도 없습니다. 매핑은 저장소 참조 타입 역할을 하는 상태 변수(state variable)에만 적용할 수 있습니다. 매핑이 초기화되면 가능한 모든 키를 포함하며, 이 키들은 바이트 표현이 모두 0인 값에 매핑됩니다.

Solidity에서 매핑은 다른 변수 타입과 동일한 방식으로 정의됩니다:

### Solidity 배열과 매핑의 차이는 무엇인가요?

[**Solidity 배열**](https://www.alchemy.com/overviews/solidity-arrays)은 (예를 들어 for 루프를 사용해) 데이터 그룹을 순회하는 데 더 적합한 반면, 매핑은 알려진 키를 기준으로 값을 가져올 수 있을 때(즉 데이터를 순회할 필요가 없을 때) 더 적합합니다.

Solidity에서 배열을 순회하는 것은 매핑에서 데이터를 가져오는 것보다 비용이 많이 들 수 있고, 개발자가 스마트 컨트랙트 내에 값과 그 키를 함께 저장하고 싶어할 수 있기 때문에, 개발자들은 종종 매핑 안에서 가져올 수 있는 데이터를 참조하는 키 배열을 만들기도 합니다.

큰 배열을 순회하면 트랜잭션 자체의 가치보다 더 많은 Solidity 가스 비용이 들 수 있으므로, 개발자는 Solidity 배열을 지나치게 크게 키우지 않아야 하며, 이 때문에 매핑이 더 [가스 효율적인 스마트 컨트랙트 구현](https://www.alchemy.com/overviews/solidity-gas-optimization) 방법이 됩니다.

**매핑의 추가적인 특성은 다음과 같습니다:**

- 매핑에는 길이가 없습니다.
- 매핑은 키나 값이 설정되어 있다는 개념도 이해하지 못합니다.
- 매핑은 저장소 참조 타입 역할을 하는 상태 변수에만 사용할 수 있습니다.

## **중첩 매핑(Nested Mapping)이란?**

중첩 매핑은 하나의 매핑에서 다른 매핑으로의 매핑입니다. 예를 들어 사용자 이름과 나이가 있고 이 정보를 특정 ID를 통해서만 다른 사람이 조회할 수 있도록 저장하고 싶다면, 이를 Solidity에서 이중 매핑(double mapping)이라고 합니다.

다음은 중첩 매핑의 예시입니다:

이 컨트랙트에서는 User라고 불리는 하나의 중첩 매핑을 구성했습니다. 이 매핑 안에는 두 개의 매핑을 연결했습니다:

1. 특정 사용자의 id 정보를 기록하는 매핑
1. 특정 사용자의 이름과 나이를 저장하는 매핑

아래 코드 블록은 사용자 정보를 반환하는 간단한 getter 함수입니다.

## **Solidity에서 매핑을 사용하는 방법**

다음은 Solidity에서 매핑을 사용하는 예시입니다. 아래 코드 스니펫의 기능은 다음과 같습니다:

- address를 uint에 매핑하고, 매핑이 항상 값을 반환하도록 보장
- 값이 한 번도 설정된 적이 없다면 기본값을 반환
- 매핑된 주소의 값 업데이트
- 값을 기본값으로 재설정
- address를 다른 매핑에 매핑하는 중첩 매핑 생성
- 초기화되지 않은 경우에도 중첩 매핑에서 값을 가져오기

## **Solidity 매핑 예시**

다음은 Solidity 매핑의 세 가지 예시입니다:

1. ERC20 토큰 잔액
1. 불리언 로직 사용
1. DAO 멤버 조회

### **1. ERC20 사용자 잔액**

이 코드 스니펫은 사용자 주소를 해당 주소의 ERC20 잔액과 매핑합니다.

### **2. Solidity 매핑 bool 예시**

이 코드 스니펫은 후보자 이름을 목록에 나열하고 각 후보자가 받은 투표 수를 반환하도록 설계되었습니다. 이 예시는 멤버들이 조직의 의사결정에 투표하는 [DAO](https://www.alchemy.com/dapps/top/daos)에서 활용 사례를 가집니다.

### **3. 멤버 여부 확인 \(DAO\)**

이 예시는 _raisedProposals_, _stakeholderVotes_, _votedOn_, _contributors_, _stakeholders_를 매핑하는 Dominion DAO 스마트 컨트랙트에서 가져온 것입니다.

이 코드 예시는 두 개의 [Solidity 구조체](https://www.alchemy.com/overviews/solidity-struct)인 _ProposalStruct_와 _VotedStruct_의 필드를 나열합니다.

## **문자열의 Solidity 매핑**

더 나은 이해를 위해 매핑을 만드는 과정에서 값을 추가해 보겠습니다. 다음 예시에서 우리는:

- 컨트랙트를 생성하고
- 구조체를 정의하고
- 서로 다른 구조체 요소를 선언하고
- 매핑을 생성하고
- 매핑에 값을 추가합니다

## **Solidity 매핑 FAQ**

다음은 Solidity 매핑에 관해 자주 묻는 질문 몇 가지입니다:

1. Solidity 매핑의 길이는 무엇인가요?
1. Solidity 매핑의 기본값은 무엇인가요?
1. Solidity 매핑을 어떻게 공개적으로 볼 수 있나요?

### **Solidity 매핑의 길이는 무엇인가요?**

**매핑에는 길이가 없습니다. 키의 데이터는 매핑에 저장되지 않고, 대신 키가 참조하는 값을 저장하기 위해 해당 키의 keccak256 해시**가 사용됩니다. 키와 값이 "그 자체로" 존재한다는 개념은 없습니다.

### **Solidity 매핑 기본값 타입은 무엇인가요?**

다음은 Solidity 매핑의 기본값 타입입니다:

- **int/uint** - 키 타입 = 가능; 값 타입 = 가능
- **string** - 키 타입 = 가능; 값 타입 = 가능
- **byte/bytes** - 키 타입 = 가능; 값 타입 = 가능
- **address** - 키 타입 = 가능; 값 타입 = 가능
- **struct** - 키 타입 = 불가능; 값 타입 = 가능
- **mapping** - 키 타입 = 불가능; 값 타입 = 가능
- **enum** - 키 타입 = 불가능; 값 타입 = 가능
- **contract** - 키 타입 = 불가능; 값 타입 = 가능
- **fixed-sized array** - 키 타입 = 가능; 값 타입 = 가능
- **dynamic-sized array** - 키 타입 = 불가능; 값 타입 = 가능
- **multi-dimensional array** - 키 타입 = 불가능; 값 타입 = 가능
- **variable** - 키 타입 = 불가능; 값 타입 = 불가능

### **Solidity 매핑을 어떻게 공개적으로 볼 수 있나요?**

[해당 속성이 public이므로](https://www.alchemy.com/overviews/solidity-function-visibility), **Solidity 컴파일러**가 생성하는 getter 함수를 사용하여 접근할 수 있습니다.
