eth_estimateGas

eth_estimateGas(callObject, blockTag?) → quantity

주어진 블록에서 트랜잭션을 실행했을 때 필요한 가스 양의 추정치를 반환합니다. 노드가 호출을 시뮬레이션하여 (상태 변경 없이) 사용 가스를 측정합니다. 서명 전에 호출하여 적절한 gas 필드 값을 설정하는 데 사용하며, 시뮬레이션과 실제 블록 포함 사이에 상태가 변할 수 있으므로 프로덕션 트랜잭션에서는 결과에 20~30%의 여유를 더하는 것이 일반적입니다. 이 체인에서는 PCL 정책 평가도 추정치에 포함됩니다. 호출이 실행된 뒤 수행되는 컴플라이언스 검사가 트랜잭션의 가스에서 차감되며, eth_estimateGas도 같은 검사를 수행하므로 반환값에 이미 반영되어 있습니다. 따로 더하지 마시고, 컨트랙트 호출 비용만으로 가스 한도를 정하지 마십시오.

파라미터

이름 타입 필수 설명
callObject object ✓ 트랜잭션 호출 객체입니다. 주요 필드: from(발신자 주소), to(대상 주소 — 컨트랙트 생성 시에는 생략), value(전달할 atokrw 양, 16진수), data(16진수 콜데이터), gasPrice / maxFeePerGas / maxPriorityFeePerGas(선택 — base fee 인식 시뮬레이션에 사용).
blockTag string - 시뮬레이션 기준 블록입니다. latest(기본값), pending, finalized 또는 16진수 블록 번호를 지정합니다. 마루는 CometBFT 합의로 즉시 finality를 제공하므로 pending과 finalized는 가장 최근 커밋 블록으로 해석됩니다. earliest를 넘겨도 오류는 나지 않지만, 첫 블록이 아니라 최신 상태로 시뮬레이션합니다. 이전 블록을 기준으로 하려면 그 블록의 16진수 번호를 넘깁니다. safe는 노드가 -32602로 거부합니다.

반환값

타입: string

추정 가스 양을 0x 접두사가 붙은 16진수로 반환합니다. 마루 테스트넷에서 단순 전송의 추정치는 이더리움의 21,000(0x5208)이 아니라 약 104,000(예: 0x195c1 = 103,873)입니다. 모든 트랜잭션 뒤에 실행되는 컴플라이언스(PCL)·에이전트 검사가 그 트랜잭션의 가스로 계산되기 때문입니다. 이 값은 일반 계정에서 코드가 없는 주소로 보낼 때 적용되며, 받는 쪽이 ERC-8004 에이전트의 EOA 지갑이어도 같습니다. 에이전트 지갑에서 보내면 전역 정책이 그 지갑을 쓰는 각 에이전트의 소유자를 조회하므로 추정치가 더 높습니다. 지갑을 쓰는 에이전트가 하나면 약 283,000, 둘이면 약 461,000~471,000입니다. 스마트 계정 같은 컨트랙트 지갑으로 보낼 때도 그 지갑의 코드가 실행되므로 더 높게 추정됩니다. 고정값 대신 반환값을 그대로 사용합니다.

에러

코드 이름 설명
3 execution reverted 시뮬레이션된 호출이 revert되었습니다(대상 컨트랙트의 throw, PCL 정책 거부 등). revert에 데이터가 있으면 노드는 코드 3으로 응답하고 error.data에 원본 revert 사유가 담기므로, 이를 디코드하면 호출이 실패하는 이유를 알 수 있습니다. 데이터 없이 revert하면 같은 메시지로 data 없이 -32000을 반환합니다.
-32000 gas required exceeds allowance 호출에 필요한 가스가 현재 적용되는 상한을 넘습니다. 그 상한은 직접 넘긴 gas 값이며(이 체인의 단순 전송에는 약 104,000이 필요하므로 gas를 21,000으로 주면 항상 이 오류가 납니다), gas를 넘기지 않았다면 노드의 RPC 가스 상한입니다. 수수료를 지정한 경우에는 잔액 ÷ maxFeePerGas로 다시 제한됩니다. 직접 정한 gas를 빼고 추정치를 따르며, 상한을 정하지 않았는데도 발생한다면 무제한 루프를 확인합니다. 테스트넷의 블록 가스 한도는 사실상 무제한이므로 원인이 아닙니다.
-32602 Invalid params 파라미터 형식이 잘못되었습니다(예: callObject 자체가 없음, 주소 형식 오류, value/data의 16진수 오류). from 누락은 오류가 아니지만, 추정값이 발신자에 따라 달라질 때(잔액, 발신자를 읽는 PCL 정책)는 from을 넘겨야 합니다.

예제

ethers.js v6 — 전송 전 견적

ethers.js는 내부적으로 eth_estimateGas를 호출합니다. 컨트랙트 호출 시에는 iface.encodeFunctionData(...)로 생성한 data를 전달합니다. 반환값을 gas 필드의 기준으로 삼으십시오. 컨트랙트 호출 비용만으로 계산한 한도는 실행 후 정책 검사 도중 소진될 수 있습니다. 그 검사는 한도에 남은 몫을 사용하는데, 추정치에는 이미 포함되어 있고 직접 계산한 숫자에는 없습니다.

import { JsonRpcProvider, parseEther } from "ethers";

const provider = new JsonRpcProvider("https://rpc-testnet.maroo.io");

const gas = await provider.estimateGas({
  from:  "0xSenderAddress",
  to:    "0xRecipientAddress",
  value: parseEther("100"),  // 100 OKRW
});
console.log("Estimated gas:", gas.toString());

// Pad by ~25% for headroom in production.
const safeGas = (gas * 125n) / 100n;

cURL로 직접 호출

0x56BC75E2D63100000은 10^20 atokrw, 즉 100 OKRW입니다. 마루 테스트넷에서는 { jsonrpc, id, result: "0x195c1" }와 비슷한 값, 즉 일반 계정 간 단순 전송에 약 104,000 가스를 반환합니다(보내는 쪽이 에이전트 지갑이거나 받는 쪽이 컨트랙트 지갑이면 더 많습니다). 이더리움에서는 같은 요청이 0x5208(21,000)을 반환합니다.

curl -X POST https://rpc-testnet.maroo.io \
  -H "Content-Type: application/json" \
  -d '{
    "jsonrpc": "2.0",
    "method": "eth_estimateGas",
    "params": [{
      "from":  "0xSenderAddress",
      "to":    "0xRecipientAddress",
      "value": "0x56BC75E2D63100000"
    }, "latest"],
    "id": 1
  }'
ESC
검색어를 입력하세요