Allow contract calls to override the block tag
This commit is contained in:
parent
3c12a65769
commit
1ca90d0b3c
|
@ -16,13 +16,15 @@ type
|
||||||
provider: Provider
|
provider: Provider
|
||||||
signer: ?Signer
|
signer: ?Signer
|
||||||
address: Address
|
address: Address
|
||||||
TransactionOverrides* = object
|
TransactionOverrides* = ref object of RootObj
|
||||||
nonce*: ?UInt256
|
nonce*: ?UInt256
|
||||||
chainId*: ?UInt256
|
chainId*: ?UInt256
|
||||||
gasPrice*: ?UInt256
|
gasPrice*: ?UInt256
|
||||||
maxFee*: ?UInt256
|
maxFee*: ?UInt256
|
||||||
maxPriorityFee*: ?UInt256
|
maxPriorityFee*: ?UInt256
|
||||||
gasLimit*: ?UInt256
|
gasLimit*: ?UInt256
|
||||||
|
CallOverrides* = ref object of TransactionOverrides
|
||||||
|
blockTag*: ?BlockTag
|
||||||
|
|
||||||
ContractError* = object of EthersError
|
ContractError* = object of EthersError
|
||||||
Confirmable* = ?TransactionResponse
|
Confirmable* = ?TransactionResponse
|
||||||
|
@ -56,7 +58,7 @@ template raiseContractError(message: string) =
|
||||||
proc createTransaction(contract: Contract,
|
proc createTransaction(contract: Contract,
|
||||||
function: string,
|
function: string,
|
||||||
parameters: tuple,
|
parameters: tuple,
|
||||||
overrides = TransactionOverrides.default): Transaction =
|
overrides = TransactionOverrides()): Transaction =
|
||||||
let selector = selector(function, typeof parameters).toArray
|
let selector = selector(function, typeof parameters).toArray
|
||||||
let data = @selector & AbiEncoder.encode(parameters)
|
let data = @selector & AbiEncoder.encode(parameters)
|
||||||
Transaction(
|
Transaction(
|
||||||
|
@ -78,27 +80,36 @@ proc decodeResponse(T: type, multiple: static bool, bytes: seq[byte]): T =
|
||||||
else:
|
else:
|
||||||
return decodeResponse((T,), true, bytes)[0]
|
return decodeResponse((T,), true, bytes)[0]
|
||||||
|
|
||||||
|
proc call(provider: Provider,
|
||||||
|
transaction: Transaction,
|
||||||
|
overrides: TransactionOverrides): Future[seq[byte]] =
|
||||||
|
if overrides of CallOverrides and
|
||||||
|
blockTag =? CallOverrides(overrides).blockTag:
|
||||||
|
provider.call(transaction, blockTag)
|
||||||
|
else:
|
||||||
|
provider.call(transaction)
|
||||||
|
|
||||||
proc call(contract: Contract,
|
proc call(contract: Contract,
|
||||||
function: string,
|
function: string,
|
||||||
parameters: tuple,
|
parameters: tuple,
|
||||||
blockTag = BlockTag.latest) {.async.} =
|
overrides = TransactionOverrides()) {.async.} =
|
||||||
let transaction = createTransaction(contract, function, parameters)
|
let transaction = createTransaction(contract, function, parameters, overrides)
|
||||||
discard await contract.provider.call(transaction, blockTag)
|
discard await contract.provider.call(transaction, overrides)
|
||||||
|
|
||||||
proc call(contract: Contract,
|
proc call(contract: Contract,
|
||||||
function: string,
|
function: string,
|
||||||
parameters: tuple,
|
parameters: tuple,
|
||||||
ReturnType: type,
|
ReturnType: type,
|
||||||
returnMultiple: static bool,
|
returnMultiple: static bool,
|
||||||
blockTag = BlockTag.latest): Future[ReturnType] {.async.} =
|
overrides = TransactionOverrides()): Future[ReturnType] {.async.} =
|
||||||
let transaction = createTransaction(contract, function, parameters)
|
let transaction = createTransaction(contract, function, parameters, overrides)
|
||||||
let response = await contract.provider.call(transaction, blockTag)
|
let response = await contract.provider.call(transaction, overrides)
|
||||||
return decodeResponse(ReturnType, returnMultiple, response)
|
return decodeResponse(ReturnType, returnMultiple, response)
|
||||||
|
|
||||||
proc send(contract: Contract,
|
proc send(contract: Contract,
|
||||||
function: string,
|
function: string,
|
||||||
parameters: tuple,
|
parameters: tuple,
|
||||||
overrides = TransactionOverrides.default):
|
overrides = TransactionOverrides()):
|
||||||
Future[?TransactionResponse] {.async.} =
|
Future[?TransactionResponse] {.async.} =
|
||||||
if signer =? contract.signer:
|
if signer =? contract.signer:
|
||||||
let transaction = createTransaction(contract, function, parameters, overrides)
|
let transaction = createTransaction(contract, function, parameters, overrides)
|
||||||
|
@ -136,7 +147,7 @@ func addOverrides(procedure: var NimNode) =
|
||||||
newIdentDefs(
|
newIdentDefs(
|
||||||
ident("overrides"),
|
ident("overrides"),
|
||||||
newEmptyNode(),
|
newEmptyNode(),
|
||||||
quote do: TransactionOverrides.default
|
quote do: TransactionOverrides()
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -152,11 +163,11 @@ func addContractCall(procedure: var NimNode) =
|
||||||
func call: NimNode =
|
func call: NimNode =
|
||||||
if returnType.kind == nnkEmpty:
|
if returnType.kind == nnkEmpty:
|
||||||
quote:
|
quote:
|
||||||
await call(`contract`, `function`, `parameters`)
|
await call(`contract`, `function`, `parameters`, overrides)
|
||||||
else:
|
else:
|
||||||
quote:
|
quote:
|
||||||
return await call(
|
return await call(
|
||||||
`contract`, `function`, `parameters`, `returnType`, `returnMultiple`)
|
`contract`, `function`, `parameters`, `returnType`, `returnMultiple`, overrides)
|
||||||
|
|
||||||
func send: NimNode =
|
func send: NimNode =
|
||||||
if returnType.kind == nnkEmpty:
|
if returnType.kind == nnkEmpty:
|
||||||
|
|
|
@ -116,6 +116,18 @@ suite "Contracts":
|
||||||
check signer.transactions[0].gasPrice == overrides.gasPrice
|
check signer.transactions[0].gasPrice == overrides.gasPrice
|
||||||
check signer.transactions[0].gasLimit == overrides.gasLimit
|
check signer.transactions[0].gasLimit == overrides.gasLimit
|
||||||
|
|
||||||
|
test "can call functions for different block heights":
|
||||||
|
let block1 = await provider.getBlockNumber()
|
||||||
|
let signer = provider.getSigner(accounts[0])
|
||||||
|
discard await token.connect(signer).mint(accounts[0], 100.u256)
|
||||||
|
let block2 = await provider.getBlockNumber()
|
||||||
|
|
||||||
|
let beforeMint = CallOverrides(blockTag: some BlockTag.init(block1))
|
||||||
|
let afterMint = CallOverrides(blockTag: some BlockTag.init(block2))
|
||||||
|
|
||||||
|
check (await token.balanceOf(accounts[0], beforeMint)) == 0
|
||||||
|
check (await token.balanceOf(accounts[0], afterMint)) == 100
|
||||||
|
|
||||||
test "receives events when subscribed":
|
test "receives events when subscribed":
|
||||||
var transfers: seq[Transfer]
|
var transfers: seq[Transfer]
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue