-
구조체(struct)와 가스(gas) 관계Solidity 2022. 5. 11. 22:17
크립토 좀비를 하면서 구조체와 가스 관계에 대해 새롭게 알게 된 점이 있어 이에 대해 공유하고자 글을 씁니다.
Solidity를 하다 보면 가스를 지나칠 수 없을 겁니다.
왜냐하면 우리와 사용자들의 돈과 바로 직결되는 문제이기 때문입니다.
우선 스마트 컨트랙트에 가스가 왜 필요한 것인지와 어떻게 하면 그 비용을 줄일 수 있을지에 대해 얘기해보고자 합니다.
제가 이해하고 있는 것은 아래와 같습니다.
블록체인을 분산형 컴퓨팅 이라고도 하는데 함수가 실행되면 각각의 노드가 함수의 출력 값을 검증하기 위해 해당 함수를 실행해야 하고 이를 통해 검증이 되면 모든 노드의 블록체인에 해당 데이터가 반영되는 것입니다.
그렇기 때문에 로직이 복잡할수록 많은 컴퓨팅 리소스를 필요로 할 것이고 이것이 비용으로 반영되는 것입니다.
그렇다면 가스라는 비용을 없애면 되지 않을까라는 생각도 했었습니다.
만약 비용이 들지 않는다면 누군가 악의적으로 무한 반복문을 사용하여 부하가 생기도록 할 수도 있을 것입니다.
혹은 어떤 의도를 가지고 네트워크 자원을 모두 사용할 수 없도록 만들 수도 있을 것입니다.
그렇기에 보안적인 측면에서 가스가 필요한 것입니다.
제가 이해한 구조체는 스키마와 같습니다.
여기에서 데이터 규격(데이터의 타입과 변수명 등 설정)을 설정합니다.
마치 Django에서 models.py에 테이블명과 컬럼명과 타입을 작성하는 것처럼 말입니다.
서론이 길었기에 이제 결론을 바로 얘기하자면
구조체 외부에서도 데이터 타입을 매번 명시하는데 이때 uint8, uint16처럼 하위 타입들을 사용해도 가스 소모에는 아무런 영향을 끼치지 않는다고 합니다. 왜냐하면 구조체 외부의 uint는 기본적으로 256의 공간을 미리 할당해두기 때문입니다.
그렇지만 구조체 내부에서는 해당 타입으로 고정시켜 두기 때문에 가능하면 작은(하위) 타입의 uint를 사용하면 불필요한 가스 소모를 방지할 수 있습니다.
그리고 같은 타입끼리는 아래의 예시처럼 함께 모아서 선언하면 그렇지 않을 때보다 저장 공간을 적게 사용할 수 있고 저장 공간을 적게 사용할수록 가스 비용은 훨씬 적어질 것입니다.
// 같은 타입끼리 두지 않아서 덜 효율적이다. contract GasTest { struct Test1 { uint8 a; uint16 b; uint8 c; } } // 같은 타입끼리 두어서 위의 경우보다 더 효율적이다. contract GasTest { struct Test1 { uint8 a; uint8 c; uint16 b; } }
< 가스 비용 >
메모리 저장 < 스토리지 저장
- 메모리는 함수의 외부 호출이 일어날 때마다 초기화된다. (램)
- 스토리지는 블록체인에 영구 저장된다. (하드디스크)
< 결론 >
- 무한 반복문을 통한 악의적인 공격을 방지하기 위해서 가스는 필수적이다.
- 복잡한 로직일수록 많은 컴퓨팅 리소스를 필요로 하기에 많은 가스가 소모된다.
- 불필요한 가스 낭비를 줄이는 것이 핵심인데 구조체에서 가능한 작은 크기의 정수 타입을 사용하면 구조체 외부에서와 달리 해당 타입으로 고정되어 가스 낭비를 줄일 수 있다.
'Solidity' 카테고리의 다른 글
접근 제한자와 생성자 (0) 2022.05.11 Struct (구조체) - Mapping & Array (0) 2022.04.24 Solidity의 Array (배열) 사용법과 주의사항 (0) 2022.04.23