1 Gas
-
가스란 이더리움의 연료이다
- EVM의 각 명령어는 가스 단위로 미리 정해진 비용이 있다.
- 거래 데이터의 1바이트당 5가스의 수수료가 발생한다.
-
가스는 이더가 아니라 이더에 대한 자체 환율을 가진 가상 화폐이다
가스의 용도
- 가스는 트랜잭션이 사용할 수 있는 자원의 양을 제어한다.
- 튜링 완전 개발 모델이 DoS 공격이나 실수로 막대한 자원을 소모하는 트랜잭션을 피하기 위해 미터링이 필요하다.
- 이더 가치의 변동성으로 부터 시스템을 보호한다.
- 가스는 네트워크의 과부하를 막으며, 이더리움 플랫폼이 계속 운영되도록 하는 인센티브 역할을 한다
2 Gas Price
- 트랜잭션의 필드
- 하나의 연산 단계에 부여할 이더의 양(WEI 단위).
2.1 Gas Price 설정하기
-
트랜잭션 생성자는 원하는 가스 가격을 지정할 수 있다.
- 예를 들어 ‘가스 당 3Gwei를 지불할 용의가 있다.’라고 설정했을 때, 트랜잭션이 1,000,000가스를 소비하고 가스 가격을 3Gwei로 설정하면 해당 트랜잭션에 대한 수수료로 3,000,000Gwei를 지불하게 된다.
-
대부분의 채굴자들은 가스 가격이 높은 트랜잭션을 선택하여 블록에 포함시키기 때문에 설정한 가스 가격이 높을수록 트랜잭션은 더 빨리 처리된다.
-
가격을 낮게 책정해 도 결국 트랜잭션이 블록에 포함되기는 하지만 그 대기 시간이 상당히 길어질 가능성도 있다.
2.2 Gas Price 얻기
- 가스 가격은 일반 사람들에 의하여 무작위로 책정되지는 않고 가스 가격을 측정해주는 사이트가 있다.
- 이더리움 가스스테이션이라는 사이트인데, 이곳에서 적당한 가스 가격을 선택할 수 있다.
- 사용되는 가스의 평균값이라고 보면 된다.
- 빠른 처리를 원할 경우 여기 나온 금액보다 높은 가격을 측정하면 된다.
네트워크에서 가스 가격 얻기
- 최근 몇개의 블록의 중앙값를 반환함
web3.eth.getGasPrice().then(console.log);
> "20000000000"
3 Gas Limit
- 트랜잭션의 필드
- 해당 트랜잭션이 수행될 때 사용할 수 있는 최대 연산 단계의 수
- 즉 하나의 거래에서 사용될 수 있는 최대 가스 양은 Gas Limit * Gas Price 이고 이 중 사용되지 않은 가스는 반환된다.
- 가스 한도는 작업 중단 시점을 보장함으로써 무제한으로 이더를 사용하는 것을 방지할 수 있다.
- 사용자는 트랜잭션을 실행하기 위해 사용할 가스의 최대 금액을 나타내는 가스 한도(Gas Limit)를 설정한다.
- 가스 한도는 요청하는 작업량의 추측이다. 하지만 추측은 쉬운 일이 아니다.
- 일반적으 로 21,000가스의 한도는 대부분의 거래를 만족한다고 알려져 있다.
- 한도가 낮으면 작업이 완료되지 않고 거래는 실패하며 그 시점까지 사용된 이더가 손실된다.
- 한도를 너무 높게 설정하여 한도 전에 작업이 끝나더라도 작업에 사용되지 않은 모든 이더는 다시 되돌려 받을 수 있다
3.1 Gas Limit 측정
- 트랜잭션은 크게 2가지 종류로 단순한 이더리움 송금(transactions)과 Contract를 실행시키는 트랜잭션(contract internal transactions)이 있다.
- EOA간의 Value transfer(Standard transaction)는 21,000개의 가스가 소모됨
- Contract 실행은 코드의 복잡성에 따라 천차만별이다.
- 어떻게 이걸 예측해서 Gas Limit을 결정할 수 있을까?
- 답은 간단하게도 실제로 계산을 해보는 것이다.
- 명령어별로 이미 Gas Fee는 공개가 되어있으며 개발자는 자신의 Solidity 코드가 어느 정도의 Gas가 들지 예측할 수 있다.
컨트랙트 메소드를 실행하는 데 필요한 가스 추정
- estimateGas 대분분의 경우 상당히 정확한 예상치를 제공한다.
var contract = web3.eth.contract(abi).at(address);
var gasEstimate = contract.myAweSomeMethod.estimateGas(arg1, arg2, {from: account});
// 네트워크에서 가스 가격 얻기
var gasPrice = web3.eth.getGasPrice();
// GasLimit 예상치와 GasPrice를 곱하여 지불할 가스 비용 구하기
var gasCostInEther = web3.fromWei((gasEstimate * gasPrice), 'ether');
3.2 Gas Limit 초과
- 계산하는 동안 가스 한계를 초과하면 아래와 같은 종류의 이벤트가 발생
- 가스 부족 예외가 발생
- 실행 전의 컨트랙트 상태가 복원
- 가스를 지급하는 데 사용되는 모든 이더는 트랜잭션 수수료로 간주되고 환불되지 않는다
3.3 Gas Limit 줄이기
- 가스는 트랜잭션을 시작한 사용자가 지급하기 떄문에 가스 비용이 높은 함수를 호출하지 않는 것이 좋다
- 따라서 프로그래머는 컨트랙트 함수들의 가스 비용을 최소화하도록 해야 한다.
동적 크기 배열 피하기
다른 컨트랙트 호출 피하기
- 다른 컨트랙트의 가스 비용이 알려져 있지 않을 때는 가스 고갈 위험이 있다.
- 잘 테스트되지 않고 광범위하게 사용되지 않는 라이브러리는 사용하지 말자