Estimate Gas
Tổng quan
Trước khi submit một Transaction lên Ethereum Blockchain, ta có thể đo lường trước lượng gas hao phí (Gas Limit).
Lưu ý:
Gas Limit được ước lượng bởi Estimate Gas là không chính xác, tuy nhiên nó vẫn mang giá trị tham khảo và cho ra con số gần đúng
Trên thực tế Gas Limit cần để thực hiện thường cao hơn, vì thế sau khi estimate gas nên thêm một khoảng 10% hoặc cao hơn
Cùng một Transaction với nội dung như nhau thì Gas Limit được Estimate ở Mainnet hay Testnet là đều như nhau
So với các Transaction thực hiện những việc cơ bản như chuyển Eth trên blockchain thì các Transaction tương tác với SmartContract thường bị Estimate sai lệch nhiều hơn
Tuy nhiên đôi lúc khó tránh khỏi trường hợp cho dẫu đã Estimate Gas và thêm một khoảng hơn 10% vào nhưng Transaction vẫn fail do không đủ Gas. Trong trường hợp này thì cách duy nhất là phải tiếp tục thiết lập lại Gas Limit và submit lại Transaction.
Cách thực hiện:
Để estimate một Transaction tương tác với một Smart Contract, ta tạo một request tới Ethereum Node với method là eth_estimateGas cùng với các params như sau
from: địa chỉ của account thực hiện Transaction
to: địa chỉ của Smart Contract
data: chứa các thông tin về fuction, params, ... cần tương tác
Tất cả các param đều phải ở dạng Hex.
{
"jsonrpc": "2.0",
"method": "eth_estimateGas",
"params": [
{
"from": "0xb60e8dd61c5d32be8058bb8eb970870f07233155", //sender
"to": "0xd46e8dd67c5d32be8058bb8eb970870f07244567", //receiver
"gas": "0x76c0", //optional
"gasPrice": "0x9184e72a000", //optional
"value": "0x0", //optional
"data": "0xd46e8dd67c5d32be8d46e8dd67c5d32be8058bb8eb970870f072445675058bb8eb970870f072445675"
}
],
"id": 1
}Xác định data
Data được xác định bởi function và các tham số được truyền vào nó. Ví dụ Smart Contract sau:
Nếu muốn gọi function baz với parameter là 69 và true thì data bao gồm:
0xcdcd77c0: Method ID, là 4 bytes đầu tiên của Keccak Hash của function dưới định dạng ASCII là
baz(uint32,bool)0x0000000000000000000000000000000000000000000000000000000000000045: đối số đầu tiên với giá trị
69đã được padded đến 32 bytes0x0000000000000000000000000000000000000000000000000000000000000001: đối số thứ hai với giá trị
trueđã được padded đến 32 bytes
Nối lại các giá trị trên, ta có data như sau:
Nếu muốn gọi function barvới parameter là "even" (string là non-fixed-size type) thì data bao gồm:
0x74030531: Method ID, là 4 bytes đầu tiên của Keccak Hash của function dưới định dạng ASCII là
bar(string)0000000000000000000000000000000000000000000000000000000000000020: pointer chỉ định số lượng 32 bytes
0000000000000000000000000000000000000000000000000000000000000004: Length của param này,
"even"có 4 ký tự nên sử dụng 4 bytes, khai báo giá trị 4 dưới dạng byte sau đó padded đến 32 bytes6576656e00000000000000000000000000000000000000000000000000000000:
Giá trị của param này, thể hiện giá trị string là "even" dưới dạng bytes, sau đó được padded đến 32 bytes
Tuy function bar chỉ có 1 param nhưng khai báo lại rắc rối hơn rất nhiều.
Nối lại các giá trị trên, ta có data như sau:
Lưu ý về kiểu dữ liệu của parameter
Do hạn chế khi khai báo data với kiểu dữ liệu dạng fixed-size array type và non-fixed-size types nên ta hạn chế tối đa việc sử dụng các kiểu dữ liệu này.
Khuyến khích sử dụng elementary type hết mức có thể.
Trong ví dụ trên hướng dẫn cách gọi 1 function sử dụng elementary types và 1 function sử dụng non-fixed-size types, có thể thấy rằng việc khai báo một param kiểu non-fixed-size types (và cả fixed-size array type cũng như thế) là phức tạp và rắc rối hơn.
Tuy nhiên sẽ còn phức tạp hơn nếu như param có lẫn lộn các kiểu dữ liệu với nhau, ví dụ như sử dụng int (elementary types) và string (non-fixed-size types) cùng một lúc. Khi đó sẽ phải chỉ pointer và length cho cả tất cả param (không phải từng param), và thứ tự param được truyền vào cũng sẽ thay đổi.
Do đó, việc khai báo data sẽ trở nên cực kỳ phức tạp và ngay cả một số các thư viện lớn cũng không hỗ trợ Estimate Gas nếu sử dụng lẫn lộn các kiểu dữ liệu.
Trong hình bên dưới, pointer giờ đây phải chỉ định size là 64 bytes vì dùng cho cả hai param là string và uint. Tiếp theo đó là uint256 mặc dù được khai báo sau string trong function nhưng lại truyền vào trước. Còn string được khai báo đầu tiên trong function nhưng lại truyền vào cuối cùng khi tạo data và kèm theo trước đó là length

Thực hiện bằng thư viện của các ngôn ngữ lập trình khác nhau
Tuỳ theo các thư viện của từng ngôn ngữ lập trình khác nhau có cách thực thi Estimate Gas khác nhau, nhưng đều thực hiện một cùng nguyên tắc chung.
Last updated
Was this helpful?