web3 7.6.0__py3-none-any.whl → 7.6.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- web3/_utils/contract_sources/contract_data/ambiguous_function_contract.py +42 -0
- web3/_utils/contracts.py +1 -1
- web3/contract/async_contract.py +123 -76
- web3/contract/base_contract.py +70 -40
- web3/contract/contract.py +140 -84
- web3/contract/utils.py +4 -1
- web3/providers/ipc.py +1 -1
- web3/providers/persistent/async_ipc.py +1 -1
- web3/utils/abi.py +39 -56
- web3/utils/address.py +8 -0
- {web3-7.6.0.dist-info → web3-7.6.1.dist-info}/METADATA +7 -7
- {web3-7.6.0.dist-info → web3-7.6.1.dist-info}/RECORD +15 -14
- {web3-7.6.0.dist-info → web3-7.6.1.dist-info}/LICENSE +0 -0
- {web3-7.6.0.dist-info → web3-7.6.1.dist-info}/WHEEL +0 -0
- {web3-7.6.0.dist-info → web3-7.6.1.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Generated by `compile_contracts.py` script.
|
|
3
|
+
Compiled with Solidity v0.8.28.
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
# source: web3/_utils/contract_sources/AmbiguousFunctionContract.sol:AmbiguousFunctionContract # noqa: E501
|
|
7
|
+
AMBIGUOUS_FUNCTION_CONTRACT_BYTECODE = "0x6080604052348015600e575f5ffd5b5061044a8061001c5f395ff3fe608060405234801561000f575f5ffd5b506004361061003f575f3560e01c80631626ba7e1461004357806320c13b0b14610073578063d482bb47146100a3575b5f5ffd5b61005d60048036038101906100589190610293565b6100c1565b60405161006a9190610305565b60405180910390f35b61008d6004803603810190610088919061031e565b6100cb565b60405161009a9190610305565b60405180910390f35b6100ab6100d6565b6040516100b891906103f4565b60405180910390f35b5f5f905092915050565b5f6001905092915050565b60606040518060400160405280600581526020017f76616c6964000000000000000000000000000000000000000000000000000000815250905090565b5f604051905090565b5f5ffd5b5f5ffd5b5f819050919050565b61013681610124565b8114610140575f5ffd5b50565b5f813590506101518161012d565b92915050565b5f5ffd5b5f5ffd5b5f601f19601f8301169050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b6101a58261015f565b810181811067ffffffffffffffff821117156101c4576101c361016f565b5b80604052505050565b5f6101d6610113565b90506101e2828261019c565b919050565b5f67ffffffffffffffff8211156102015761020061016f565b5b61020a8261015f565b9050602081019050919050565b828183375f83830152505050565b5f610237610232846101e7565b6101cd565b9050828152602081018484840111156102535761025261015b565b5b61025e848285610217565b509392505050565b5f82601f83011261027a57610279610157565b5b813561028a848260208601610225565b91505092915050565b5f5f604083850312156102a9576102a861011c565b5b5f6102b685828601610143565b925050602083013567ffffffffffffffff8111156102d7576102d6610120565b5b6102e385828601610266565b9150509250929050565b5f819050919050565b6102ff816102ed565b82525050565b5f6020820190506103185f8301846102f6565b92915050565b5f5f604083850312156103345761033361011c565b5b5f83013567ffffffffffffffff81111561035157610350610120565b5b61035d85828601610266565b925050602083013567ffffffffffffffff81111561037e5761037d610120565b5b61038a85828601610266565b9150509250929050565b5f81519050919050565b5f82825260208201905092915050565b8281835e5f83830152505050565b5f6103c682610394565b6103d0818561039e565b93506103e08185602086016103ae565b6103e98161015f565b840191505092915050565b5f6020820190508181035f83015261040c81846103bc565b90509291505056fea2646970667358221220baaf91e0e0589f566caa06e4f8fa283b865412d3e3c1dc1eca705cc8ad7f393764736f6c634300081c0033" # noqa: E501
|
|
8
|
+
AMBIGUOUS_FUNCTION_CONTRACT_RUNTIME = "0x608060405234801561000f575f5ffd5b506004361061003f575f3560e01c80631626ba7e1461004357806320c13b0b14610073578063d482bb47146100a3575b5f5ffd5b61005d60048036038101906100589190610293565b6100c1565b60405161006a9190610305565b60405180910390f35b61008d6004803603810190610088919061031e565b6100cb565b60405161009a9190610305565b60405180910390f35b6100ab6100d6565b6040516100b891906103f4565b60405180910390f35b5f5f905092915050565b5f6001905092915050565b60606040518060400160405280600581526020017f76616c6964000000000000000000000000000000000000000000000000000000815250905090565b5f604051905090565b5f5ffd5b5f5ffd5b5f819050919050565b61013681610124565b8114610140575f5ffd5b50565b5f813590506101518161012d565b92915050565b5f5ffd5b5f5ffd5b5f601f19601f8301169050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b6101a58261015f565b810181811067ffffffffffffffff821117156101c4576101c361016f565b5b80604052505050565b5f6101d6610113565b90506101e2828261019c565b919050565b5f67ffffffffffffffff8211156102015761020061016f565b5b61020a8261015f565b9050602081019050919050565b828183375f83830152505050565b5f610237610232846101e7565b6101cd565b9050828152602081018484840111156102535761025261015b565b5b61025e848285610217565b509392505050565b5f82601f83011261027a57610279610157565b5b813561028a848260208601610225565b91505092915050565b5f5f604083850312156102a9576102a861011c565b5b5f6102b685828601610143565b925050602083013567ffffffffffffffff8111156102d7576102d6610120565b5b6102e385828601610266565b9150509250929050565b5f819050919050565b6102ff816102ed565b82525050565b5f6020820190506103185f8301846102f6565b92915050565b5f5f604083850312156103345761033361011c565b5b5f83013567ffffffffffffffff81111561035157610350610120565b5b61035d85828601610266565b925050602083013567ffffffffffffffff81111561037e5761037d610120565b5b61038a85828601610266565b9150509250929050565b5f81519050919050565b5f82825260208201905092915050565b8281835e5f83830152505050565b5f6103c682610394565b6103d0818561039e565b93506103e08185602086016103ae565b6103e98161015f565b840191505092915050565b5f6020820190508181035f83015261040c81846103bc565b90509291505056fea2646970667358221220baaf91e0e0589f566caa06e4f8fa283b865412d3e3c1dc1eca705cc8ad7f393764736f6c634300081c0033" # noqa: E501
|
|
9
|
+
AMBIGUOUS_FUNCTION_CONTRACT_ABI = [
|
|
10
|
+
{
|
|
11
|
+
"inputs": [
|
|
12
|
+
{"internalType": "bytes32", "name": "message", "type": "bytes32"},
|
|
13
|
+
{"internalType": "bytes", "name": "signature", "type": "bytes"},
|
|
14
|
+
],
|
|
15
|
+
"name": "isValidSignature",
|
|
16
|
+
"outputs": [{"internalType": "uint256", "name": "result", "type": "uint256"}],
|
|
17
|
+
"stateMutability": "view",
|
|
18
|
+
"type": "function",
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
"inputs": [
|
|
22
|
+
{"internalType": "bytes", "name": "message", "type": "bytes"},
|
|
23
|
+
{"internalType": "bytes", "name": "signature", "type": "bytes"},
|
|
24
|
+
],
|
|
25
|
+
"name": "isValidSignature",
|
|
26
|
+
"outputs": [{"internalType": "uint256", "name": "result", "type": "uint256"}],
|
|
27
|
+
"stateMutability": "view",
|
|
28
|
+
"type": "function",
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
"inputs": [],
|
|
32
|
+
"name": "isValidSignature",
|
|
33
|
+
"outputs": [{"internalType": "string", "name": "result", "type": "string"}],
|
|
34
|
+
"stateMutability": "view",
|
|
35
|
+
"type": "function",
|
|
36
|
+
},
|
|
37
|
+
]
|
|
38
|
+
AMBIGUOUS_FUNCTION_CONTRACT_DATA = {
|
|
39
|
+
"bytecode": AMBIGUOUS_FUNCTION_CONTRACT_BYTECODE,
|
|
40
|
+
"bytecode_runtime": AMBIGUOUS_FUNCTION_CONTRACT_RUNTIME,
|
|
41
|
+
"abi": AMBIGUOUS_FUNCTION_CONTRACT_ABI,
|
|
42
|
+
}
|
web3/_utils/contracts.py
CHANGED
|
@@ -335,7 +335,7 @@ def validate_payable(transaction: TxParams, abi_callable: ABICallable) -> None:
|
|
|
335
335
|
|
|
336
336
|
|
|
337
337
|
def parse_block_identifier(
|
|
338
|
-
w3: "Web3", block_identifier: BlockIdentifier
|
|
338
|
+
w3: "Web3", block_identifier: Optional[BlockIdentifier]
|
|
339
339
|
) -> BlockIdentifier:
|
|
340
340
|
if block_identifier is None:
|
|
341
341
|
return w3.eth.default_block
|
web3/contract/async_contract.py
CHANGED
|
@@ -14,6 +14,7 @@ from typing import (
|
|
|
14
14
|
|
|
15
15
|
from eth_typing import (
|
|
16
16
|
ABI,
|
|
17
|
+
ABIFunction,
|
|
17
18
|
ChecksumAddress,
|
|
18
19
|
)
|
|
19
20
|
from eth_utils import (
|
|
@@ -21,9 +22,8 @@ from eth_utils import (
|
|
|
21
22
|
)
|
|
22
23
|
from eth_utils.abi import (
|
|
23
24
|
abi_to_signature,
|
|
25
|
+
filter_abi_by_type,
|
|
24
26
|
get_abi_input_names,
|
|
25
|
-
get_abi_input_types,
|
|
26
|
-
get_all_function_abis,
|
|
27
27
|
)
|
|
28
28
|
from eth_utils.toolz import (
|
|
29
29
|
partial,
|
|
@@ -34,8 +34,6 @@ from hexbytes import (
|
|
|
34
34
|
|
|
35
35
|
from web3._utils.abi import (
|
|
36
36
|
fallback_func_abi_exists,
|
|
37
|
-
filter_by_types,
|
|
38
|
-
get_abi_element_signature,
|
|
39
37
|
get_name_from_abi_element_identifier,
|
|
40
38
|
receive_func_abi_exists,
|
|
41
39
|
)
|
|
@@ -93,6 +91,7 @@ from web3.contract.utils import (
|
|
|
93
91
|
from web3.exceptions import (
|
|
94
92
|
ABIEventNotFound,
|
|
95
93
|
ABIFunctionNotFound,
|
|
94
|
+
MismatchedABI,
|
|
96
95
|
NoABIEventsFound,
|
|
97
96
|
NoABIFound,
|
|
98
97
|
NoABIFunctionsFound,
|
|
@@ -108,8 +107,9 @@ from web3.types import (
|
|
|
108
107
|
TxParams,
|
|
109
108
|
)
|
|
110
109
|
from web3.utils.abi import (
|
|
110
|
+
_filter_by_argument_count,
|
|
111
111
|
_get_any_abi_signature_with_name,
|
|
112
|
-
|
|
112
|
+
_mismatched_abi_error_diagnosis,
|
|
113
113
|
get_abi_element,
|
|
114
114
|
)
|
|
115
115
|
|
|
@@ -123,26 +123,7 @@ class AsyncContractEvent(BaseContractEvent):
|
|
|
123
123
|
w3: "AsyncWeb3"
|
|
124
124
|
|
|
125
125
|
def __call__(self, *args: Any, **kwargs: Any) -> "AsyncContractEvent":
|
|
126
|
-
|
|
127
|
-
filter_abi_by_type("event", self.contract_abi),
|
|
128
|
-
self.name,
|
|
129
|
-
*args,
|
|
130
|
-
abi_codec=self.w3.codec,
|
|
131
|
-
**kwargs,
|
|
132
|
-
)
|
|
133
|
-
argument_types = get_abi_input_types(event_abi)
|
|
134
|
-
event_signature = str(
|
|
135
|
-
get_abi_element_signature(self.abi_element_identifier, argument_types)
|
|
136
|
-
)
|
|
137
|
-
contract_event = AsyncContractEvent.factory(
|
|
138
|
-
event_signature,
|
|
139
|
-
w3=self.w3,
|
|
140
|
-
contract_abi=self.contract_abi,
|
|
141
|
-
address=self.address,
|
|
142
|
-
abi_element_identifier=event_signature,
|
|
143
|
-
)
|
|
144
|
-
|
|
145
|
-
return copy_contract_event(contract_event, *args, **kwargs)
|
|
126
|
+
return copy_contract_event(self, *args, **kwargs)
|
|
146
127
|
|
|
147
128
|
@combomethod
|
|
148
129
|
async def get_logs(
|
|
@@ -297,7 +278,7 @@ class AsyncContractEvents(BaseContractEvents):
|
|
|
297
278
|
raise NoABIFound(
|
|
298
279
|
"There is no ABI found for this contract.",
|
|
299
280
|
)
|
|
300
|
-
|
|
281
|
+
elif "_events" not in self.__dict__ or len(self._events) == 0:
|
|
301
282
|
raise NoABIEventsFound(
|
|
302
283
|
"The abi for this contract contains no event definitions. ",
|
|
303
284
|
"Are you sure you provided the correct contract abi?",
|
|
@@ -310,11 +291,13 @@ class AsyncContractEvents(BaseContractEvents):
|
|
|
310
291
|
f"The event '{event_name}' was not found in this contract's abi. ",
|
|
311
292
|
"Are you sure you provided the correct contract abi?",
|
|
312
293
|
)
|
|
294
|
+
|
|
295
|
+
if "(" not in event_name:
|
|
296
|
+
event_name = _get_any_abi_signature_with_name(event_name, self._events)
|
|
313
297
|
else:
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
return super().__getattribute__(event_signature)
|
|
298
|
+
event_name = f"_{event_name}"
|
|
299
|
+
|
|
300
|
+
return super().__getattribute__(event_name)
|
|
318
301
|
|
|
319
302
|
def __getitem__(self, event_name: str) -> "AsyncContractEvent":
|
|
320
303
|
return getattr(self, event_name)
|
|
@@ -325,39 +308,103 @@ class AsyncContractFunction(BaseContractFunction):
|
|
|
325
308
|
w3: "AsyncWeb3"
|
|
326
309
|
|
|
327
310
|
def __call__(self, *args: Any, **kwargs: Any) -> "AsyncContractFunction":
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
311
|
+
# When a function is called, check arguments to obtain the correct function
|
|
312
|
+
# in the contract. self will be used if all args and kwargs are
|
|
313
|
+
# encodable to self.abi, otherwise the correct function is obtained from
|
|
314
|
+
# the contract.
|
|
315
|
+
if (
|
|
316
|
+
self.abi_element_identifier in [FallbackFn, ReceiveFn]
|
|
317
|
+
or self.abi_element_identifier == "constructor"
|
|
318
|
+
):
|
|
319
|
+
return copy_contract_function(self, *args, **kwargs)
|
|
320
|
+
|
|
321
|
+
all_functions = cast(
|
|
322
|
+
List[ABIFunction],
|
|
323
|
+
filter_abi_by_type(
|
|
324
|
+
"function",
|
|
337
325
|
self.contract_abi,
|
|
338
326
|
),
|
|
339
|
-
element_name,
|
|
340
|
-
*args,
|
|
341
|
-
abi_codec=self.w3.codec,
|
|
342
|
-
**kwargs,
|
|
343
327
|
)
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
argument_types = get_abi_input_types(function_abi)
|
|
348
|
-
|
|
349
|
-
function_signature = str(
|
|
350
|
-
get_abi_element_signature(self.abi_element_identifier, argument_types)
|
|
328
|
+
# Filter functions by name to obtain function signatures
|
|
329
|
+
function_name = get_name_from_abi_element_identifier(
|
|
330
|
+
self.abi_element_identifier
|
|
351
331
|
)
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
332
|
+
function_abis = [
|
|
333
|
+
function for function in all_functions if function["name"] == function_name
|
|
334
|
+
]
|
|
335
|
+
num_args = len(args) + len(kwargs)
|
|
336
|
+
function_abis_with_arg_count = cast(
|
|
337
|
+
List[ABIFunction],
|
|
338
|
+
_filter_by_argument_count(
|
|
339
|
+
num_args,
|
|
340
|
+
function_abis,
|
|
341
|
+
),
|
|
359
342
|
)
|
|
360
343
|
|
|
344
|
+
if not len(function_abis_with_arg_count):
|
|
345
|
+
# Build an ABI without arguments to determine if one exists
|
|
346
|
+
function_abis_with_arg_count = [
|
|
347
|
+
ABIFunction({"type": "function", "name": function_name})
|
|
348
|
+
]
|
|
349
|
+
|
|
350
|
+
# Check that arguments in call match a function ABI
|
|
351
|
+
num_attempts = 0
|
|
352
|
+
function_abi_matches = []
|
|
353
|
+
contract_function = None
|
|
354
|
+
for abi in function_abis_with_arg_count:
|
|
355
|
+
try:
|
|
356
|
+
num_attempts += 1
|
|
357
|
+
|
|
358
|
+
# Search for a function ABI that matches the arguments used
|
|
359
|
+
function_abi_matches.append(
|
|
360
|
+
cast(
|
|
361
|
+
ABIFunction,
|
|
362
|
+
get_abi_element(
|
|
363
|
+
function_abis,
|
|
364
|
+
abi_to_signature(abi),
|
|
365
|
+
*args,
|
|
366
|
+
abi_codec=self.w3.codec,
|
|
367
|
+
**kwargs,
|
|
368
|
+
),
|
|
369
|
+
)
|
|
370
|
+
)
|
|
371
|
+
except MismatchedABI:
|
|
372
|
+
# ignore exceptions
|
|
373
|
+
continue
|
|
374
|
+
|
|
375
|
+
if len(function_abi_matches) == 1:
|
|
376
|
+
function_abi = function_abi_matches[0]
|
|
377
|
+
if abi_to_signature(self.abi) == abi_to_signature(function_abi):
|
|
378
|
+
contract_function = self
|
|
379
|
+
else:
|
|
380
|
+
# Found a match that is not self
|
|
381
|
+
contract_function = AsyncContractFunction.factory(
|
|
382
|
+
abi_to_signature(function_abi),
|
|
383
|
+
w3=self.w3,
|
|
384
|
+
contract_abi=self.contract_abi,
|
|
385
|
+
address=self.address,
|
|
386
|
+
abi_element_identifier=abi_to_signature(function_abi),
|
|
387
|
+
abi=function_abi,
|
|
388
|
+
)
|
|
389
|
+
else:
|
|
390
|
+
for abi in function_abi_matches:
|
|
391
|
+
if abi_to_signature(self.abi) == abi_to_signature(abi):
|
|
392
|
+
contract_function = self
|
|
393
|
+
break
|
|
394
|
+
else:
|
|
395
|
+
# Raise exception if multiple found
|
|
396
|
+
raise MismatchedABI(
|
|
397
|
+
_mismatched_abi_error_diagnosis(
|
|
398
|
+
function_name,
|
|
399
|
+
self.contract_abi,
|
|
400
|
+
len(function_abi_matches),
|
|
401
|
+
num_args,
|
|
402
|
+
*args,
|
|
403
|
+
abi_codec=self.w3.codec,
|
|
404
|
+
**kwargs,
|
|
405
|
+
)
|
|
406
|
+
)
|
|
407
|
+
|
|
361
408
|
return copy_contract_function(contract_function, *args, **kwargs)
|
|
362
409
|
|
|
363
410
|
@classmethod
|
|
@@ -536,19 +583,19 @@ class AsyncContractFunctions(BaseContractFunctions):
|
|
|
536
583
|
for function in self._functions
|
|
537
584
|
]:
|
|
538
585
|
raise ABIFunctionNotFound(
|
|
539
|
-
f"The function '{function_name}' was not found in this
|
|
540
|
-
"
|
|
586
|
+
f"The function '{function_name}' was not found in this ",
|
|
587
|
+
"contract's abi.",
|
|
541
588
|
)
|
|
542
589
|
|
|
543
|
-
function_identifier = function_name
|
|
544
|
-
|
|
545
590
|
if "(" not in function_name:
|
|
546
|
-
|
|
591
|
+
function_name = _get_any_abi_signature_with_name(
|
|
547
592
|
function_name, self._functions
|
|
548
593
|
)
|
|
594
|
+
else:
|
|
595
|
+
function_name = f"_{function_name}"
|
|
549
596
|
|
|
550
597
|
return super().__getattribute__(
|
|
551
|
-
|
|
598
|
+
function_name,
|
|
552
599
|
)
|
|
553
600
|
|
|
554
601
|
def __getitem__(self, function_name: str) -> "AsyncContractFunction":
|
|
@@ -588,7 +635,11 @@ class AsyncContract(BaseContract):
|
|
|
588
635
|
self.abi, self.w3, self.address, decode_tuples=self.decode_tuples
|
|
589
636
|
)
|
|
590
637
|
self.caller = AsyncContractCaller(
|
|
591
|
-
self.abi,
|
|
638
|
+
self.abi,
|
|
639
|
+
self.w3,
|
|
640
|
+
self.address,
|
|
641
|
+
decode_tuples=self.decode_tuples,
|
|
642
|
+
contract_functions=self.functions,
|
|
592
643
|
)
|
|
593
644
|
self.events = AsyncContractEvents(self.abi, self.w3, self.address)
|
|
594
645
|
self.fallback = AsyncContract.get_fallback_function(
|
|
@@ -638,6 +689,7 @@ class AsyncContract(BaseContract):
|
|
|
638
689
|
contract.w3,
|
|
639
690
|
contract.address,
|
|
640
691
|
decode_tuples=contract.decode_tuples,
|
|
692
|
+
contract_functions=contract.functions,
|
|
641
693
|
)
|
|
642
694
|
contract.events = AsyncContractEvents(contract.abi, contract.w3)
|
|
643
695
|
contract.fallback = AsyncContract.get_fallback_function(
|
|
@@ -720,6 +772,7 @@ class AsyncContractCaller(BaseContractCaller):
|
|
|
720
772
|
block_identifier: BlockIdentifier = None,
|
|
721
773
|
ccip_read_enabled: Optional[bool] = None,
|
|
722
774
|
decode_tuples: Optional[bool] = False,
|
|
775
|
+
contract_functions: Optional[AsyncContractFunctions] = None,
|
|
723
776
|
) -> None:
|
|
724
777
|
super().__init__(abi, w3, address, decode_tuples=decode_tuples)
|
|
725
778
|
|
|
@@ -727,18 +780,13 @@ class AsyncContractCaller(BaseContractCaller):
|
|
|
727
780
|
if transaction is None:
|
|
728
781
|
transaction = {}
|
|
729
782
|
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
abi_signature = abi_to_signature(func)
|
|
734
|
-
fn = AsyncContractFunction.factory(
|
|
735
|
-
abi_signature,
|
|
736
|
-
w3=w3,
|
|
737
|
-
contract_abi=self.abi,
|
|
738
|
-
address=self.address,
|
|
739
|
-
decode_tuples=decode_tuples,
|
|
783
|
+
if contract_functions is None:
|
|
784
|
+
contract_functions = AsyncContractFunctions(
|
|
785
|
+
abi, w3, address, decode_tuples=decode_tuples
|
|
740
786
|
)
|
|
741
787
|
|
|
788
|
+
self._functions = contract_functions._functions
|
|
789
|
+
for fn in contract_functions.__iter__():
|
|
742
790
|
caller_method = partial(
|
|
743
791
|
self.call_function,
|
|
744
792
|
fn,
|
|
@@ -746,8 +794,7 @@ class AsyncContractCaller(BaseContractCaller):
|
|
|
746
794
|
block_identifier=block_identifier,
|
|
747
795
|
ccip_read_enabled=ccip_read_enabled,
|
|
748
796
|
)
|
|
749
|
-
|
|
750
|
-
setattr(self, abi_signature, caller_method)
|
|
797
|
+
setattr(self, str(fn.abi_element_identifier), caller_method)
|
|
751
798
|
|
|
752
799
|
def __call__(
|
|
753
800
|
self,
|
web3/contract/base_contract.py
CHANGED
|
@@ -48,7 +48,6 @@ from hexbytes import (
|
|
|
48
48
|
|
|
49
49
|
from web3._utils.abi import (
|
|
50
50
|
fallback_func_abi_exists,
|
|
51
|
-
filter_by_types,
|
|
52
51
|
find_constructor_abi_element_by_type,
|
|
53
52
|
get_abi_element_signature,
|
|
54
53
|
get_name_from_abi_element_identifier,
|
|
@@ -155,27 +154,34 @@ class BaseContractEvent:
|
|
|
155
154
|
|
|
156
155
|
address: ChecksumAddress = None
|
|
157
156
|
event_name: str = None
|
|
157
|
+
name: str = None
|
|
158
158
|
abi_element_identifier: ABIElementIdentifier = None
|
|
159
|
+
signature: str = None
|
|
159
160
|
w3: Union["Web3", "AsyncWeb3"] = None
|
|
160
161
|
contract_abi: ABI = None
|
|
161
162
|
abi: ABIEvent = None
|
|
162
|
-
|
|
163
|
+
argument_names: Tuple[str, ...] = tuple()
|
|
164
|
+
argument_types: Tuple[str, ...] = tuple()
|
|
163
165
|
args: Any = None
|
|
164
166
|
kwargs: Any = None
|
|
165
167
|
|
|
166
|
-
def __init__(self, *argument_names:
|
|
167
|
-
self.event_name = get_name_from_abi_element_identifier(type(self).__name__)
|
|
168
|
+
def __init__(self, *argument_names: str, abi: Optional[ABIEvent] = None) -> None:
|
|
168
169
|
self.abi_element_identifier = type(self).__name__
|
|
169
|
-
|
|
170
|
-
self.
|
|
171
|
-
self.abi = abi
|
|
170
|
+
self.name = get_name_from_abi_element_identifier(self.abi_element_identifier)
|
|
171
|
+
self.event_name = self.name
|
|
172
172
|
|
|
173
|
-
if
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
173
|
+
if abi:
|
|
174
|
+
self.abi = abi
|
|
175
|
+
|
|
176
|
+
self.signature = abi_to_signature(self.abi)
|
|
177
|
+
|
|
178
|
+
if argument_names:
|
|
177
179
|
self.argument_names = argument_names
|
|
178
180
|
|
|
181
|
+
event_inputs = self.abi.get("inputs", [])
|
|
182
|
+
self.argument_names = tuple([input.get("name", None) for input in event_inputs])
|
|
183
|
+
self.argument_types = tuple([input["type"] for input in event_inputs])
|
|
184
|
+
|
|
179
185
|
def __repr__(self) -> str:
|
|
180
186
|
if self.abi:
|
|
181
187
|
return f"<Event {abi_to_signature(self.abi)}>"
|
|
@@ -461,7 +467,10 @@ class BaseContractEvents:
|
|
|
461
467
|
_events: Sequence[ABIEvent] = None
|
|
462
468
|
|
|
463
469
|
if self.abi:
|
|
464
|
-
_events =
|
|
470
|
+
_events = sorted(
|
|
471
|
+
filter_abi_by_type("event", self.abi),
|
|
472
|
+
key=lambda evt: (evt["name"], len(evt.get("inputs", []))),
|
|
473
|
+
)
|
|
465
474
|
for event in _events:
|
|
466
475
|
abi_signature = abi_to_signature(event)
|
|
467
476
|
event_factory = contract_event_type.factory(
|
|
@@ -469,9 +478,16 @@ class BaseContractEvents:
|
|
|
469
478
|
w3=self.w3,
|
|
470
479
|
contract_abi=self.abi,
|
|
471
480
|
address=self.address,
|
|
472
|
-
|
|
481
|
+
abi=event,
|
|
473
482
|
)
|
|
474
|
-
|
|
483
|
+
|
|
484
|
+
# Set event name on instance if it does not already exist
|
|
485
|
+
if event["name"] not in self.__dict__:
|
|
486
|
+
setattr(self, event["name"], event_factory)
|
|
487
|
+
|
|
488
|
+
# Set underscore prefixed event signature on instance
|
|
489
|
+
# Handles ambiguity in overloaded contract events
|
|
490
|
+
setattr(self, f"_{abi_signature}", event_factory)
|
|
475
491
|
|
|
476
492
|
if _events:
|
|
477
493
|
self._events = _events
|
|
@@ -494,6 +510,7 @@ class BaseContractFunction:
|
|
|
494
510
|
address: ChecksumAddress = None
|
|
495
511
|
fn_name: str = None
|
|
496
512
|
name: str = None
|
|
513
|
+
signature: str = None
|
|
497
514
|
abi_element_identifier: ABIElementIdentifier = None
|
|
498
515
|
w3: Union["Web3", "AsyncWeb3"] = None
|
|
499
516
|
contract_abi: ABI = None
|
|
@@ -501,6 +518,8 @@ class BaseContractFunction:
|
|
|
501
518
|
transaction: TxParams = None
|
|
502
519
|
arguments: Tuple[Any, ...] = None
|
|
503
520
|
decode_tuples: Optional[bool] = None
|
|
521
|
+
argument_names: Tuple[str, ...] = tuple()
|
|
522
|
+
argument_types: Tuple[str, ...] = tuple()
|
|
504
523
|
args: Any = None
|
|
505
524
|
kwargs: Any = None
|
|
506
525
|
|
|
@@ -508,18 +527,17 @@ class BaseContractFunction:
|
|
|
508
527
|
if not self.abi_element_identifier:
|
|
509
528
|
self.abi_element_identifier = type(self).__name__
|
|
510
529
|
|
|
511
|
-
self.
|
|
512
|
-
self.
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
)
|
|
522
|
-
self.name = abi_to_signature(self.abi)
|
|
530
|
+
self.name = get_name_from_abi_element_identifier(self.abi_element_identifier)
|
|
531
|
+
self.fn_name = self.name
|
|
532
|
+
|
|
533
|
+
if abi:
|
|
534
|
+
self.abi = abi
|
|
535
|
+
|
|
536
|
+
self.signature = abi_to_signature(self.abi)
|
|
537
|
+
|
|
538
|
+
event_inputs = self.abi.get("inputs", [])
|
|
539
|
+
self.argument_names = tuple([input.get("name", None) for input in event_inputs])
|
|
540
|
+
self.argument_types = tuple([input["type"] for input in event_inputs])
|
|
523
541
|
|
|
524
542
|
@combomethod
|
|
525
543
|
def _get_abi(cls) -> ABIFunction:
|
|
@@ -553,13 +571,9 @@ class BaseContractFunction:
|
|
|
553
571
|
FallbackFn,
|
|
554
572
|
ReceiveFn,
|
|
555
573
|
]:
|
|
556
|
-
self.abi = self._get_abi()
|
|
557
|
-
|
|
558
574
|
self.selector = encode_hex(function_abi_to_4byte_selector(self.abi))
|
|
559
575
|
self.arguments = None
|
|
560
576
|
elif is_text(self.abi_element_identifier):
|
|
561
|
-
self.abi = self._get_abi()
|
|
562
|
-
|
|
563
577
|
self.selector = encode_hex(function_abi_to_4byte_selector(self.abi))
|
|
564
578
|
self.arguments = get_normalized_abi_inputs(
|
|
565
579
|
self.abi, *self.args, **self.kwargs
|
|
@@ -727,21 +741,33 @@ class BaseContractFunctions:
|
|
|
727
741
|
_functions: Sequence[ABIFunction] = None
|
|
728
742
|
|
|
729
743
|
if self.abi:
|
|
730
|
-
|
|
744
|
+
# Function with least number of inputs is first
|
|
745
|
+
# This ensures ambiguity will always be deterministic
|
|
746
|
+
# Prefer function without arguments if present, otherwise
|
|
747
|
+
# just use the first available
|
|
748
|
+
_functions = sorted(
|
|
749
|
+
filter_abi_by_type("function", self.abi),
|
|
750
|
+
key=lambda fn: (fn["name"], len(fn.get("inputs", []))),
|
|
751
|
+
)
|
|
731
752
|
for func in _functions:
|
|
732
753
|
abi_signature = abi_to_signature(func)
|
|
733
|
-
|
|
734
|
-
self,
|
|
754
|
+
function_factory = contract_function_class.factory(
|
|
735
755
|
abi_signature,
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
decode_tuples=decode_tuples,
|
|
742
|
-
),
|
|
756
|
+
w3=self.w3,
|
|
757
|
+
contract_abi=self.abi,
|
|
758
|
+
address=self.address,
|
|
759
|
+
decode_tuples=decode_tuples,
|
|
760
|
+
abi=func,
|
|
743
761
|
)
|
|
744
762
|
|
|
763
|
+
# Set function name on instance if it does not already exist
|
|
764
|
+
if func["name"] not in self.__dict__:
|
|
765
|
+
setattr(self, func["name"], function_factory)
|
|
766
|
+
|
|
767
|
+
# Set function signature on instance
|
|
768
|
+
# Handles ambiguity in overloaded contract functions
|
|
769
|
+
setattr(self, f"_{abi_signature}", function_factory)
|
|
770
|
+
|
|
745
771
|
if _functions:
|
|
746
772
|
self._functions = _functions
|
|
747
773
|
|
|
@@ -1100,12 +1126,14 @@ class BaseContract:
|
|
|
1100
1126
|
address: Optional[ChecksumAddress] = None,
|
|
1101
1127
|
) -> "BaseContractFunction":
|
|
1102
1128
|
if abi and fallback_func_abi_exists(abi):
|
|
1129
|
+
fallback_abi = filter_abi_by_type("fallback", abi)[0]
|
|
1103
1130
|
return function_type.factory(
|
|
1104
1131
|
"fallback",
|
|
1105
1132
|
w3=w3,
|
|
1106
1133
|
contract_abi=abi,
|
|
1107
1134
|
address=address,
|
|
1108
1135
|
abi_element_identifier=FallbackFn,
|
|
1136
|
+
abi=fallback_abi,
|
|
1109
1137
|
)()
|
|
1110
1138
|
|
|
1111
1139
|
return cast(function_type, NonExistentFallbackFunction()) # type: ignore
|
|
@@ -1118,12 +1146,14 @@ class BaseContract:
|
|
|
1118
1146
|
address: Optional[ChecksumAddress] = None,
|
|
1119
1147
|
) -> "BaseContractFunction":
|
|
1120
1148
|
if abi and receive_func_abi_exists(abi):
|
|
1149
|
+
receive_abi = filter_abi_by_type("receive", abi)[0]
|
|
1121
1150
|
return function_type.factory(
|
|
1122
1151
|
"receive",
|
|
1123
1152
|
w3=w3,
|
|
1124
1153
|
contract_abi=abi,
|
|
1125
1154
|
address=address,
|
|
1126
1155
|
abi_element_identifier=ReceiveFn,
|
|
1156
|
+
abi=receive_abi,
|
|
1127
1157
|
)()
|
|
1128
1158
|
|
|
1129
1159
|
return cast(function_type, NonExistentReceiveFunction()) # type: ignore
|