Notice
Recent Posts
Recent Comments
관리 메뉴

즐겁게, 코드

솔리디티 - 08. 가스 (Gas), 가스 최적화 기법 본문

💬 언어/Solidity

솔리디티 - 08. 가스 (Gas), 가스 최적화 기법

Chamming2 2021. 4. 19. 16:20

1. 가스 - 이더리움 DApp이 사용하는 연료

솔리디티에서는 DApp의 함수를 실행할 때마다 가스라고 불리는 화폐를 지불해야 하는데요, 사용자는 이더(ETH, 이더리움의 화폐)를 이용해서 가스를 사기 때문에 결국 이더를 소모해야만 합니다.

 

함수를 실행하는 데에 얼마나 많은 가스가 필요한지는 함수가 얼마나 복잡한지에 따라 달라집니다.

각각의 연산은 소모되는 가스 비용(gas cost)이 있고 그 연산을 수행하는 데에 소모되는 컴퓨팅 자원의 양이 비용을 결정하는데요, 예를 들어 storage에 값을 쓰는 것은 두 개의 정수를 더하는 것보다 비용이 높으며 함수의 전체 가스 비용은 함수를 구성하는 개별 연산들의 가스 비용을 모두 합친 것과 같습니다.

 

이더리움에서 함수를 실행하는 것은 사용자들에게 실제 돈을 쓰게 하기 때문에 다른 프로그래밍 언어들에 비해 최적화가 더 중요합니다.

만약 코드가 비효율적이라면 사용자들은 함수를 실행하기 위해 일종의 할증료를 더 내야 할 것이고, 만약 수천 명의 사용자가 이런 불필요한 비용을 낸다면 할증료가 수십 억 원까지 쌓일 수 있습니다.

2. 가스는 왜 필요한가?

이더리움은 크고 느리지만 굉장히 안전한 컴퓨터라고 할 수 있습니다.

어떤 함수를 실행하면 네트워크 상의 모든 노드가 함수의 출력값을 검증하기 위해 그 함수를 실행해야 하는데요, 함수의 실행을 검증하는 수천 개의 노드가 바로 이더리움을 분산화하고 데이터를 보존하는 주체가 됩니다.

 

이더리움의 개발자들은 누군가가 무한 반복문을 써서 네트워크를 방해하거나, 자원 소모(CPU나 메모리)가 큰 연산을 통해 네트워크 자원을 모두 사용하지 못하도록 만들길 원했습니다. 그래서 그들은 연산 처리에 비용이 들도록 만들었고, 사용자들은 저장 공간 뿐만 아니라 연산 사용 시간에 따라서도 비용을 지불하도록 설계된 것입니다.

3. 가스 소모 최적화 - 구조체 최적화

위에서 잠깐 언급했듯 솔리디티는 최적화가 아주 중요한데요, 최적화를 적용할 수 있는 요소중 하나가 바로 자료형입니다.

uint형은 기본적으로 256비트 자료형으로, uint8, uint32 등 보다 크기가 작은 자료형들도 존재합니다.

contract checkGas {
  uint256 a = 256;
  // uint32은 부호 없는 32비트 정수형까지만 보관할 수 있지만, 메모리에는 256비트가 할당됩니다.
  uint32 b = 32;
}

다만 일반적인 변수를 사용할 때는 작은 자료형으로 선언하는 것이 최적화에 영향을 미치지 않습니다.

대신, 구조체를 사용할 때는 작은 자료형으로 선언하는 것이 최적화에 도움을 줍니다.

contract checkGas {
  struct NormalStruct {
    uint a;
    uint b;
    uint c;
  }

  struct OptimizedStruct {
    uint32 a;
    uint32 b;
    uint c;
  }
}

이렇게 구조체 내에서는 사용할 만큼만 자료형을 선언하면, 그만큼 가스 사용을 절약할 수 있습니다!

4. storage 활용 최소화하기

storage와 memory를 다루는 파트에서 storage는 블록체인에 영원히 기록되는 정보임을 알 수 있었습니다.

따라서 배열을 함수 내부에서만 사용할 예정이라면 다음과 같이 memory를 활용해 배열을 선언하는 것이 보다 효율적입니다.

function getArray() external view returns(uint[]) {
    // new 키워드를 활용해 배열을 생성할 때는 반드시 길이 인자를 뒤에 붙여 생성해야 합니다.
    uint[] memory result = new uint[](100);
    return result;
}

5. external view(pure) 함수 활용하기

솔리디티의 모든 함수 실행은 가스가 소모된다고 했지만, 외부에서 호출되는 viewpure 함수만큼은 무료로 실행할 수 있습니다.

만약 단순히 외부로부터 컨트랙트의 데이터를 읽기만 하는 함수가 있다면 반드시 external view 선언을 통해 수수료를 절감해야만 합니다.

 

반응형
Comments
소소한 팁 : 광고를 눌러주시면, 제가 뮤지컬을 마음껏 보러다닐 수 있어요!
와!! 바로 눌러야겠네요! 😆