반응형

가스란? 


이더리움 DApp이 사용하는 연료를 의미한다.

솔리디티에서는 user가 DApp에 있는 함수를 실행 할 때마다 가스를 지불해야 한다.

이때 사용자들은 가스를 이더리움으로 사야하기에 어떠한 이더리움 기반 DApp의 함수를 실행하려면 사용자들은 ETH를 내야 한다.


함수를 실행하기 위해 가스를 쓴다고 앞서 말했는데 하나의 함수 당 요구되는 가스 비용은 함수 로직에 따라 다르게 결정된다.

즉, 각 연산마다 연산의 크기가 다르기에 그 연산을 수행하는데 소모되는 컴퓨팅 자원 양이 비용을 결정하게 된다.


결국 하나의 함수에 대한 가스 비용은 함수 내부에 있는 각 연산의 함수 비용의 총합과 같게 된다.

따라서 DApp에서만큼은 특정 함수를 작성할 때는 흔히 알고리즘을 공부할 때 생각하던 시간 복잡도보다는 가스 복잡도를 더 중요하게 생각해서 코딩을 해야한다. (왜냐면 가스는 실제 돈이 지출되는 과정이기 때문이다.)





가스는 왜 필요한가 ?


이더리움은 크고 느린, 하지만 굉장히 안전한 컴퓨터와 같다고 할 수 있는데 이더리움 네트워크를 방해할 누군가가 무한 반복문을 써서 네트워크를 방해하거나, 자원 소모가 큰 연산을 써서 네트워크 자원을 모두 사용하지 못하도록 한다면 이더리움 네트워크에는 큰 타격이 오게 된다. 


따라서 연산 처리에 비용이 들도록 만들었고, 사용자들은 저장 공간 뿐만 아니라 연산 사용 시간에 따라서도 비용을 지불해야 한다.



** 이제 가스가 왜 필요한지 생각됐다면 다음을 한번 고려해볼 수 있다.


내가 특정 RPG게임을 만드는데 맵을 이동하기 위해 포탈을 타거나, 무기를 사용하는 행위에서 계속해서 함수를 콜하게되면 가스 비용이 무지막지하게 계속 나갈 것이다. 


이러한 것들을 생각하며 DApp를 프로그래밍 할 때, 이더리움 메인넷에 올릴지 사이드 체인에 올릴지 잘 고려해야한다.





가스 절약 방법


1. 가스를 아끼기 위한 구조체 압축


솔리디티에서는 uint의 크기에 상관없이 256비트의 저장 공간을 미리 잡아놓기 때문에 가스를 줄일 방법이 없다.

즉, uint 대신에 uint8를 써봣자 둘다 256비트이기에 방법이 없다는 것이다.


하지만 솔리디티는 struct 내부에서는 그 변수들을 더 적은 공간을 차지하도록 압축해준다.


1
2
3
4
5
6
7
8
9
10
11
12
// 'smallOne'는 구조체 압축을 했기 때문에 'bigOne'보다 가스를 조금 사용하게 된다.
struct bigOne {
    uint a;
    uint b;
    uint c;
}
 
struct smallOne {
    uint32 a;
    uint32 b;
    uint c;
}
cs


또한 동일한 데이터 타입은 하나로 묶어놓는 것이 좋다.

uint c; uint32 a; uint32 b; (O)

uint32 a; uint c; uint32 b; (X)




2. 'View' 함수를 사용해 가스 절약하기


특정 함수가 블록체인 네트워크 상에서 데이터를 읽기만 하면 되는 함수라면 view 함수로 바꾸어 줄 수 있다.


* view 함수는 가스를 소모하지 않는다 *


view 함수는 사용자에 의해 외부에서 호출되었을 때 가스를 전혀 소모하지 않는다.


그 이유는 view 함수가 블록체인 상에서 실제로 어떤 것도 수정하지 않고 데이터를 읽기만 하기 떄문이다. 


그러므로 DApp의 가스를 최적하 하기위해 가능한 읽기 전용으로 만들어도 되는 함수는 external view로 설정한다.



external view


만약 view 함수가 동일 컨트랙트 내에 있는, view 함수가 아닌 다른 함수에서 내부적으로 호출될 경우, 여전히 가스를 소모하게 된다.


왜냐면 다른 함수가 이더리움에 트랜잭션을 생성하고, 이는 모든 개별 노드에서 검증되어야 하기 때문이다.


그러므로 view 함수는 external view로 호출됐을 때에만 무료이다.





3. 비싼 Storage를 view로


솔리디티에서 비싼 연산 중 하나는 storage를 쓰는 것이다.


storage를 이용하면 블록체인에 기록을 하는 행위이므로 결국 연산이 들게되고 이더리움 메인넷을 접근하는 것이니 가스 비용이 들게 된다.


이러한 비용을 최소화하기 위해서, 진짜 필요한 경우가 아니면 storage에 데이터를 쓰는 것을 지양하자.


대부분의 프로그래밍 언어는 큰 데이터 집합에서 특정한 데이터를 찾기위해 시간 복잡도를 고려하기 나름이다. 이 시간 복잡도 비용이 작으면 작을수록 좋다.


하지만 DApp에서는 시간 복잡도 보다 가스를 얼마나 효율적으로 쓸 수 있냐가 더 중요할 때가 많다. 


따라서 이러한 과정을 external view로 바꾸어 storage를 직접 사용하는 것보다 비용이 저렴해질 수 있다.






반응형