mirror of
https://github.com/logos-storage/nim-ethers.git
synced 2026-01-04 06:33:07 +00:00
Allow for gas estimation of contract calls
This commit is contained in:
parent
def12bfdc1
commit
e37f454761
@ -5,6 +5,7 @@ import ./contracts/confirmation
|
|||||||
import ./contracts/events
|
import ./contracts/events
|
||||||
import ./contracts/filters
|
import ./contracts/filters
|
||||||
import ./contracts/syntax
|
import ./contracts/syntax
|
||||||
|
import ./contracts/gas
|
||||||
import ./contracts/function
|
import ./contracts/function
|
||||||
|
|
||||||
export contract
|
export contract
|
||||||
@ -16,6 +17,7 @@ export syntax.view
|
|||||||
export syntax.pure
|
export syntax.pure
|
||||||
export syntax.getter
|
export syntax.getter
|
||||||
export syntax.errors
|
export syntax.errors
|
||||||
|
export gas.estimateGas
|
||||||
|
|
||||||
{.push raises: [].}
|
{.push raises: [].}
|
||||||
|
|
||||||
@ -23,4 +25,7 @@ macro contract*(procedure: untyped{nkProcDef | nkMethodDef}): untyped =
|
|||||||
procedure.params.expectMinLen(2) # at least return type and contract instance
|
procedure.params.expectMinLen(2) # at least return type and contract instance
|
||||||
procedure.body.expectKind(nnkEmpty)
|
procedure.body.expectKind(nnkEmpty)
|
||||||
|
|
||||||
createContractFunction(procedure)
|
newStmtList(
|
||||||
|
createContractFunction(procedure),
|
||||||
|
createGasEstimationCall(procedure)
|
||||||
|
)
|
||||||
|
|||||||
45
ethers/contracts/gas.nim
Normal file
45
ethers/contracts/gas.nim
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
import std/macros
|
||||||
|
import ../basics
|
||||||
|
import ../provider
|
||||||
|
import ../signer
|
||||||
|
import ./contract
|
||||||
|
import ./contractcall
|
||||||
|
import ./transactions
|
||||||
|
import ./syntax
|
||||||
|
|
||||||
|
type ContractGasEstimations[C] = distinct C
|
||||||
|
|
||||||
|
func estimateGas*[C: Contract](contract: C): ContractGasEstimations[C] =
|
||||||
|
ContractGasEstimations[C](contract)
|
||||||
|
|
||||||
|
proc estimateGas(
|
||||||
|
call: ContractCall
|
||||||
|
): Future[UInt256] {.async: (raises: [CancelledError, ProviderError, EthersError]).} =
|
||||||
|
var transaction = createTransaction(call)
|
||||||
|
if signer =? call.contract.signer:
|
||||||
|
await signer.estimateGas(transaction)
|
||||||
|
else:
|
||||||
|
await call.contract.provider.estimateGas(transaction)
|
||||||
|
|
||||||
|
func wrapFirstParameter(procedure: var NimNode) =
|
||||||
|
let contractType = procedure.params[1][1]
|
||||||
|
let gasEstimationsType = quote do: ContractGasEstimations[`contractType`]
|
||||||
|
procedure.params[1][1] = gasEstimationsType
|
||||||
|
|
||||||
|
func setReturnType(procedure: var NimNode) =
|
||||||
|
procedure.params[0] = quote do: Future[UInt256]
|
||||||
|
|
||||||
|
func addEstimateCall(procedure: var NimNode) =
|
||||||
|
let contractCall = getContractCall(procedure)
|
||||||
|
procedure.body = quote do:
|
||||||
|
return await estimateGas(`contractCall`)
|
||||||
|
|
||||||
|
func createGasEstimationCall*(procedure: NimNode): NimNode =
|
||||||
|
result = copyNimTree(procedure)
|
||||||
|
result.wrapFirstParameter()
|
||||||
|
result.addOverridesParameter()
|
||||||
|
result.setReturnType()
|
||||||
|
result.addAsyncPragma()
|
||||||
|
result.addUsedPragma()
|
||||||
|
result.addEstimateCall()
|
||||||
|
|
||||||
@ -64,7 +64,7 @@ for url in ["ws://" & providerUrl, "http://" & providerUrl]:
|
|||||||
test "can call constant functions without a return type":
|
test "can call constant functions without a return type":
|
||||||
token = TestToken.new(token.address, provider.getSigner())
|
token = TestToken.new(token.address, provider.getSigner())
|
||||||
proc mint(token: TestToken, holder: Address, amount: UInt256) {.contract, view.}
|
proc mint(token: TestToken, holder: Address, amount: UInt256) {.contract, view.}
|
||||||
await mint(token, accounts[1], 100.u256)
|
await token.mint(accounts[1], 100.u256)
|
||||||
check (await balanceOf(token, accounts[1])) == 0.u256
|
check (await balanceOf(token, accounts[1])) == 0.u256
|
||||||
|
|
||||||
test "can call non-constant functions without a return type":
|
test "can call non-constant functions without a return type":
|
||||||
@ -74,7 +74,6 @@ for url in ["ws://" & providerUrl, "http://" & providerUrl]:
|
|||||||
check (await balanceOf(token, accounts[1])) == 100.u256
|
check (await balanceOf(token, accounts[1])) == 100.u256
|
||||||
|
|
||||||
test "can call non-constant functions with a Confirmable return type":
|
test "can call non-constant functions with a Confirmable return type":
|
||||||
|
|
||||||
token = TestToken.new(token.address, provider.getSigner())
|
token = TestToken.new(token.address, provider.getSigner())
|
||||||
proc mint(token: TestToken,
|
proc mint(token: TestToken,
|
||||||
holder: Address,
|
holder: Address,
|
||||||
@ -146,6 +145,15 @@ for url in ["ws://" & providerUrl, "http://" & providerUrl]:
|
|||||||
discard await token.transfer(accounts[1], 50.u256, beforeMint)
|
discard await token.transfer(accounts[1], 50.u256, beforeMint)
|
||||||
discard await token.transfer(accounts[1], 50.u256, afterMint)
|
discard await token.transfer(accounts[1], 50.u256, afterMint)
|
||||||
|
|
||||||
|
test "can estimate gas of a function call":
|
||||||
|
proc mint(token: TestToken, holder: Address, amount: UInt256) {.contract.}
|
||||||
|
let estimate = await token.estimateGas.mint(accounts[1], 100.u256)
|
||||||
|
let correctGas = TransactionOverrides(gasLimit: some estimate)
|
||||||
|
await token.mint(accounts[1], 100.u256, correctGas)
|
||||||
|
let invalidGas = TransactionOverrides(gasLimit: some (estimate - 1))
|
||||||
|
expect ProviderError:
|
||||||
|
await token.mint(accounts[1], 100.u256, invalidGas)
|
||||||
|
|
||||||
test "receives events when subscribed":
|
test "receives events when subscribed":
|
||||||
var transfers: seq[Transfer]
|
var transfers: seq[Transfer]
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user