slot → contract의 변수를 저장하는 공간
slot 하나의 크기는 256bit = 32byte, 전체 슬롯의 개수는 2^256
EX0. address
contract slot {
address a = 0xd9145CCE52D386f254917e481eB44e9943F39138;
address b = 0xaE036c65C649172b43ef7156b009c6221B596B8b;
address c = msg.sender;
}
address는 20byte이다.

EX1. uint256
contract slot {
uint256 a = 0x1;
uint256 b = 0x2;
uint256 c = 0x3;
}
a, b, c가 각각 하나의 슬롯을 차지

EX2. bool, uint?
contract slot {
bool a = true;
uint256 b = 0x2;
uint8 c = 0x3;
}
마찬가지로 a, b, c 각각 slot 1개씩 차지

EX3. string
contract slot {
string a = 'helloworld!';
string b = 'Blockchain Valley';
}
string은 어떻게 저장될까? 문자는 모두 ASCII CODE로 변환되어 저장됨. 문자 하나당 1 byte.
value의 높은 주소에서부터 낮은 주소로 문자열을 저장하고, 제일 낮은 주소에 (문자열의 byte * 2)를 16진수로 저장
만약 문자열이 슬롯의 크기 (32byte)를 넘는다면? 이따가 설명.
ASCII CODE 표


EX4. 최적화
contract slot {
bool a = true;
uint8 b = 0x2;
uint256 c = 0x3;
}
이번에는 a, b가 하나의 슬롯에 함께, 다른 슬롯에 c가 저장됨.
Why? bool은 1byte, uint8도 1byte이므로 1+1<32여서 한 슬롯에 저장됨.

데이터 최적화를 위해서는 변수를 선언하는 순서, 변수 크기를 잘 생각하자!
EX5. struct
contract slot {
struct exampleStruct{
uint256 firstValue;
uint16 secondValue;
bool thirdValue;
}
bool a = true;
uint256 b = 0x1234;
uint8 c = 0x3;
exampleStruct tmp = exampleStruct (
0x5678, 0x10, true
);
}
struct를 만드는 거 자체로 slot에 저장될까? X
exampleStruct 변수인 tmp를 선언하면 안의 요소가 순서대로 저장됨. 마찬가지로 슬롯 크기 고려하여 최적화.

EX6-1. statically-sized array1
contract slot {
bool a = true;
uint256 b = 0x1234;
uint256[3] c = [0x56, 0x78, 0x9A];
}
배열은 순서대로 저장됨.

EX6-2. statically-sized array2
contract slot {
bool a = true;
uint256 b = 0x1234;
uint16[3] c = [0x56, 0x78, 0x9A];
}
uint16은 2byte이므로 배열 요소 모두 하나의 슬롯에 저장됨.

EX7. dynamically-sized array
contract slot {
bool a = true;
uint256 b = 0x1234;
uint256[] c;
uint256 d = 0x5678;
constructor() {
c.push(0xAA);
c.push(0xBB);
c.push(0xCC);
}
}
→배열을 선언할 때 값을 넣어주지 않고 동적으로 할당하는 경우
= keccak256(배열 슬롯 위치) + n (n=배열 요소 순서)
배열 slot에는 동적으로 할당된 배열의 크기 저장


EX8. string 심화
contract slot {
string a = 'helloworld!';
string b = 'Blockchain Valley';
string c = 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa';
}
문자열의 길이가 32를 넘는다면, 배열의 동적 할당과 같은 원리로 저장됨.
위에서 c의 경우 keccak256(2)에 순서대로 저장되고, slot 2에는 문자열 길이 저장됨.

EX9. mapping
contract slot {
bool a = true;
uint256 b = 0x1234;
mapping (uint => uint) c;
uint256 d = 0x5678;
constructor() {
c[10] = 0xDD;
c[25] = 0xEE;
}
}
매핑의 경우 p ⇒ X라면 keccak256(h(p) . k) (k=mapping이 저장된 slot) 번째 slot에 저장

#Reference
연습문제
#1
contract slot {
bool a = true;
uint8 b = 0x12;
uint16 c = 0x3456;
uint32 d = 0x789abcde;
uint256 e = 0x4;
}
answer

#2
contract slot {
bool a = false;
uint256 b = 0xAAA;
string c = 'hello';
uint8 d = 0xFF;
uint128[3] e = [0x1234,0x5678,0x9abc];
}
answer

#3
contract slot {
struct exampleStruct{
uint128 first;
uint64 second;
uint32 third;
uint16 fourth;
uint8 fifth;
bool sixth;
bool seventh;
}
uint128 a = 0x1212;
uint128 b = 0x3434;
uint32[5] c = [0x1, 0x2, 0x3, 0x4, 0x5];
exampleStruct d = exampleStruct(
0x12, 0x34, 0x56, 0x78, 0x9A, false, true
);
uint64[] e;
constructor() {
e.push(0x123);
e.push(0x456);
e.push(0x789);
e.push(0xABC);
e.push(0xDEF);
}
}
answer

#4
contract slot {
struct exampleStruct{
uint64 first;
address second;
uint128 third;
address fourth;
}
uint8 a = 0xCC;
string b = 'Charlie Puth';
string c = 'I Don't Think That I Like Her';
exampleStruct d = exampleStruct(
0x12,
0xd9145CCE52D386f254917e481eB44e9943F39138,
0x567,
0xd8b934580fcE35a11B58C6D73aDeE468a2833fa8
);
string e = 'I don't think that I like her anymore Girls are all the same All they wanna do is break my heart, my heart, ah-ah';
}
answer
