> For the complete documentation index, see [llms.txt](https://whs3-doge5k.gitbook.io/smartcontract-security-docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://whs3-doge5k.gitbook.io/smartcontract-security-docs/basics/3.-evm/evm-2/undefined/struct.md).

# struct

struct 타입은 하나의 타입이지만, 내부에 여러 변수 타입이 저장될 수 있다. 따라서 슬롯 저장 방식은 단순히 “슬롯 하나 차지”가 아니라, 내부 필드별로 **개별적으로 슬롯이 할당**되거나, **packing**이 적용된다. 또한, 내부 필드 순서에 따라 저장 구조가 크게 달라질 수 있다.

### **특징**

| 항목        | 내용                                                                                      |
| --------- | --------------------------------------------------------------------------------------- |
| **타입명**   | 정적 타입 (내부적으로 여러 필드로 구성됨)                                                                |
| **크기**    | 내부 필드 크기의 합 (단, packing 적용 여부에 따라 슬롯 수 달라짐)                                             |
| **패킹 가능** | O (내부에 작은 타입이 연속될 경우 packing 최적화됨)                                                      |
| **저장 조건** | <ul><li>선언 순서 기준으로 저장됨</li><li>작은 타입 연속 선언 시 packing + 중간에 큰 타입이 있으면 슬롯 분리 발생</li></ul> |

***

### **예시 1**

```solidity
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

contract Example9 {
    struct Info {
        uint8 a;
        bool b;
        uint16 c;
    }

    Info public info;

    constructor() {
        info = Info(1, true, 999);
    }
}
```

<figure><img src="https://2462457462-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FLf9vwRuaws92ULgGvzTi%2Fuploads%2FwlPieV0j6Ik3kIQrlXwb%2Fimage.png?alt=media&amp;token=cda41feb-7420-4ea1-b8a5-6b55196abb0c" alt=""><figcaption></figcaption></figure>

```
// 스토리지

address: 0x0000000000000000000000000000000000000000000000000000000000000000
0x0000000000000000000000000000000000000000000000000000000003e70101
```

슬롯 하나에 uint8, bool, uint16 값이 packing 되었다.

* a = 0x01
* b = 0x01
* c = 0x03e7

a(1 byte) + b(1 byte) + c(2 bytes)으로 총 4바이트가 하위 바이트부터 차례대로 슬롯 하나에 저장되었다. struct 타입 내에 위치한 변수가 32바이트보다 작기 때문에 하나의 슬롯으로 패킹되었다.

***

### **예시 2**

```solidity
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

contract Example10 {
    struct Info {
        uint8 a;
        uint256 big;
        bool b;
    }

    Info public info;

    constructor() {
        info = Info(1, 999, true);
    }
}
```

<figure><img src="https://2462457462-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FLf9vwRuaws92ULgGvzTi%2Fuploads%2FaoRE6M3kr8958ezEIVEB%2Fimage.png?alt=media&amp;token=da1bd512-9a7a-4938-a799-e8ebc35e16b9" alt=""><figcaption></figcaption></figure>

```
// 스토리지

address: 0x0000000000000000000000000000000000000000000000000000000000000000
0x0000000000000000000000000000000000000000000000000000000000000001

address: 0x0000000000000000000000000000000000000000000000000000000000000001
0x00000000000000000000000000000000000000000000000000000000000003e7

address: 0x0000000000000000000000000000000000000000000000000000000000000002
0x0000000000000000000000000000000000000000000000000000000000000001
```

개별 슬롯에 uint8, uint256, bool 타입이 하위 바이트부터 저장되었다.

***

### **최적화**

예시 2의 코드는 슬롯에 담긴 변수가 직관적이라는 장점이 있다. 그러나 대규모 컨트랙트를 작성할 때는 불필요한 gas 사용량이 증가할 수 있으므로,필드 순서를 조정한 효율적인 packing이 요구된다.

```solidity
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

contract Example10 {
    struct Info {
        uint8 a;
        bool b;
        uint256 big;
    }

    Info public info;

    constructor() {
        info = Info(1, true, 999);
    }
}
```
