forked from svanas/delphereum
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathweb3.eth.gas.pas
135 lines (121 loc) · 3.68 KB
/
web3.eth.gas.pas
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
{******************************************************************************}
{ }
{ Delphereum }
{ }
{ Copyright(c) 2018 Stefan van As <[email protected]> }
{ Github Repository <https://github.com/svanas/delphereum> }
{ }
{ Distributed under Creative Commons NonCommercial (aka CC BY-NC) license. }
{ }
{******************************************************************************}
unit web3.eth.gas;
{$I web3.inc}
interface
uses
// Delphi
System.JSON,
System.SysUtils,
// web3
web3,
web3.eth,
web3.eth.abi,
web3.eth.gas.station,
web3.eth.types,
web3.json,
web3.json.rpc;
procedure getGasPrice(client: TWeb3; callback: TAsyncQuantity);
procedure estimateGas(
client : TWeb3;
from, &to : TAddress;
const func: string;
args : array of const;
default : TWei;
callback : TAsyncQuantity); overload;
procedure estimateGas(
client : TWeb3;
from, &to : TAddress;
const data: string;
default : TWei;
callback : TAsyncQuantity); overload;
implementation
procedure getGasPrice(client: TWeb3; callback: TAsyncQuantity);
var
info: TGasStationInfo;
begin
info := client.GetGasStationInfo;
if info.Custom > 0 then
begin
callback(info.Custom, nil);
EXIT;
end;
if (info.apiKey = '') and (info.Speed = Average) then
begin
client.JsonRpc.Send(client.URL, client.Security, 'eth_gasPrice', [], procedure(resp: TJsonObject; err: IError)
begin
if Assigned(err) then
callback(0, err)
else
callback(web3.json.getPropAsStr(resp, 'result'), nil);
end);
EXIT;
end;
web3.eth.gas.station.getGasPrice(info.apiKey, procedure(price: IGasPrice; err: IError)
begin
if Assigned(err) then
callback(0, err)
else
case info.Speed of
Outbid : callback(price.Outbid, nil);
Fastest: callback(price.Fastest, nil);
Fast : callback(price.Fast, nil);
Average: callback(price.Average, nil);
SafeLow: callback(price.SafeLow, nil);
end;
end);
end;
procedure estimateGas(
client : TWeb3;
from, &to : TAddress;
const func: string;
args : array of const;
default : TWei;
callback : TAsyncQuantity);
begin
estimateGas(client, from, &to, web3.eth.abi.encode(func, args), default, callback);
end;
procedure estimateGas(
client : TWeb3;
from, &to : TAddress;
const data: string;
default : TWei;
callback : TAsyncQuantity);
var
obj: TJsonObject;
begin
// construct the transaction call object
obj := web3.json.unmarshal(Format(
'{"from": %s, "to": %s, "data": %s}', [
web3.json.quoteString(string(from), '"'),
web3.json.quoteString(string(&to), '"'),
web3.json.quoteString(data, '"')
]
)) as TJsonObject;
try
// estimate how much gas is necessary for the transaction to complete (without creating a transaction on the blockchain)
client.JsonRpc.Send(client.URL, client.Security, 'eth_estimateGas', [obj], procedure(resp: TJsonObject; err: IError)
begin
if Assigned(err) then
begin
if err.Message.Contains('gas required exceeds allowance') and (default > 0) then
callback(default, nil)
else
callback(0, err);
EXIT;
end;
callback(web3.json.getPropAsStr(resp, 'result'), nil);
end);
finally
obj.Free;
end;
end;
end.