web3 7.0.0b3__py3-none-any.whl → 7.0.0b4__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.
- ens/_normalization.py +1 -3
- ens/async_ens.py +12 -9
- ens/contract_data.py +2 -2
- ens/ens.py +8 -5
- ens/exceptions.py +19 -27
- ens/specs/nf.json +1 -1
- ens/specs/normalization_spec.json +1 -1
- ens/utils.py +17 -10
- web3/__init__.py +2 -7
- web3/_utils/abi.py +30 -29
- web3/_utils/async_transactions.py +7 -4
- web3/_utils/blocks.py +6 -2
- web3/_utils/caching.py +7 -3
- web3/_utils/compat/__init__.py +0 -3
- web3/_utils/contract_sources/compile_contracts.py +1 -1
- web3/_utils/contracts.py +12 -12
- web3/_utils/datatypes.py +5 -1
- web3/_utils/decorators.py +6 -1
- web3/_utils/empty.py +1 -1
- web3/_utils/encoding.py +15 -10
- web3/_utils/error_formatters_utils.py +5 -3
- web3/_utils/events.py +20 -18
- web3/_utils/fee_utils.py +2 -4
- web3/_utils/filters.py +17 -12
- web3/_utils/formatters.py +2 -2
- web3/_utils/math.py +3 -2
- web3/_utils/method_formatters.py +24 -5
- web3/_utils/module.py +2 -1
- web3/_utils/module_testing/eth_module.py +62 -69
- web3/_utils/module_testing/go_ethereum_personal_module.py +1 -1
- web3/_utils/module_testing/module_testing_utils.py +1 -3
- web3/_utils/module_testing/utils.py +14 -7
- web3/_utils/normalizers.py +3 -3
- web3/_utils/request.py +4 -4
- web3/_utils/rpc_abi.py +5 -1
- web3/_utils/threads.py +8 -7
- web3/_utils/transactions.py +14 -12
- web3/_utils/type_conversion.py +5 -1
- web3/_utils/validation.py +12 -10
- web3/contract/async_contract.py +12 -7
- web3/contract/base_contract.py +50 -56
- web3/contract/contract.py +12 -6
- web3/contract/utils.py +11 -6
- web3/datastructures.py +22 -12
- web3/eth/async_eth.py +33 -28
- web3/eth/base_eth.py +7 -3
- web3/eth/eth.py +18 -13
- web3/exceptions.py +30 -59
- web3/gas_strategies/time_based.py +2 -4
- web3/geth.py +1 -3
- web3/main.py +6 -2
- web3/manager.py +7 -5
- web3/method.py +13 -5
- web3/middleware/base.py +4 -2
- web3/middleware/filter.py +27 -17
- web3/middleware/formatting.py +6 -3
- web3/middleware/names.py +4 -1
- web3/middleware/signing.py +6 -2
- web3/middleware/stalecheck.py +2 -1
- web3/providers/eth_tester/defaults.py +1 -1
- web3/providers/eth_tester/main.py +5 -4
- web3/providers/eth_tester/middleware.py +10 -1
- web3/providers/ipc.py +7 -3
- web3/providers/persistent/async_ipc.py +6 -7
- web3/providers/persistent/persistent.py +11 -1
- web3/providers/persistent/request_processor.py +7 -7
- web3/providers/persistent/websocket.py +3 -3
- web3/providers/rpc/async_rpc.py +23 -6
- web3/providers/rpc/rpc.py +27 -16
- web3/testing.py +4 -4
- web3/tools/benchmark/main.py +13 -9
- web3/tools/benchmark/utils.py +1 -1
- web3/tracing.py +9 -5
- web3/types.py +19 -22
- {web3-7.0.0b3.dist-info → web3-7.0.0b4.dist-info}/METADATA +13 -28
- {web3-7.0.0b3.dist-info → web3-7.0.0b4.dist-info}/RECORD +79 -79
- {web3-7.0.0b3.dist-info → web3-7.0.0b4.dist-info}/LICENSE +0 -0
- {web3-7.0.0b3.dist-info → web3-7.0.0b4.dist-info}/WHEEL +0 -0
- {web3-7.0.0b3.dist-info → web3-7.0.0b4.dist-info}/top_level.txt +0 -0
web3/_utils/transactions.py
CHANGED
|
@@ -2,6 +2,7 @@ import math
|
|
|
2
2
|
from typing import (
|
|
3
3
|
TYPE_CHECKING,
|
|
4
4
|
List,
|
|
5
|
+
Literal,
|
|
5
6
|
Optional,
|
|
6
7
|
Union,
|
|
7
8
|
cast,
|
|
@@ -19,9 +20,6 @@ from hexbytes import (
|
|
|
19
20
|
HexBytes,
|
|
20
21
|
)
|
|
21
22
|
|
|
22
|
-
from web3._utils.compat import (
|
|
23
|
-
Literal,
|
|
24
|
-
)
|
|
25
23
|
from web3._utils.utility_methods import (
|
|
26
24
|
all_in_dict,
|
|
27
25
|
any_in_dict,
|
|
@@ -29,6 +27,10 @@ from web3._utils.utility_methods import (
|
|
|
29
27
|
from web3.constants import (
|
|
30
28
|
DYNAMIC_FEE_TXN_PARAMS,
|
|
31
29
|
)
|
|
30
|
+
from web3.exceptions import (
|
|
31
|
+
Web3AttributeError,
|
|
32
|
+
Web3ValueError,
|
|
33
|
+
)
|
|
32
34
|
from web3.types import (
|
|
33
35
|
BlockIdentifier,
|
|
34
36
|
TxData,
|
|
@@ -107,7 +109,7 @@ def fill_nonce(w3: "Web3", transaction: TxParams) -> TxParams:
|
|
|
107
109
|
@curry
|
|
108
110
|
def fill_transaction_defaults(w3: "Web3", transaction: TxParams) -> TxParams:
|
|
109
111
|
"""
|
|
110
|
-
|
|
112
|
+
If w3 is None, fill as much as possible while offline
|
|
111
113
|
"""
|
|
112
114
|
strategy_based_gas_price = w3.eth.generate_gas_price(transaction)
|
|
113
115
|
is_dynamic_fee_transaction = strategy_based_gas_price is None and (
|
|
@@ -130,7 +132,7 @@ def fill_transaction_defaults(w3: "Web3", transaction: TxParams) -> TxParams:
|
|
|
130
132
|
|
|
131
133
|
if callable(default_getter):
|
|
132
134
|
if w3 is None:
|
|
133
|
-
raise
|
|
135
|
+
raise Web3ValueError(
|
|
134
136
|
f"You must specify a '{key}' value in the transaction"
|
|
135
137
|
)
|
|
136
138
|
default_val = default_getter(w3, transaction)
|
|
@@ -160,7 +162,7 @@ def get_buffered_gas_estimate(
|
|
|
160
162
|
gas_limit = get_block_gas_limit(w3)
|
|
161
163
|
|
|
162
164
|
if gas_estimate > gas_limit:
|
|
163
|
-
raise
|
|
165
|
+
raise Web3ValueError(
|
|
164
166
|
"Contract does not appear to be deployable within the "
|
|
165
167
|
f"current network gas limits. Estimated: {gas_estimate}. "
|
|
166
168
|
f"Current gas limit: {gas_limit}"
|
|
@@ -172,7 +174,7 @@ def get_buffered_gas_estimate(
|
|
|
172
174
|
def get_required_transaction(w3: "Web3", transaction_hash: _Hash32) -> TxData:
|
|
173
175
|
current_transaction = w3.eth.get_transaction(transaction_hash)
|
|
174
176
|
if not current_transaction:
|
|
175
|
-
raise
|
|
177
|
+
raise Web3ValueError(
|
|
176
178
|
f"Supplied transaction with hash {transaction_hash!r} does not exist"
|
|
177
179
|
)
|
|
178
180
|
return current_transaction
|
|
@@ -204,7 +206,7 @@ def extract_valid_transaction_params(transaction_params: TxData) -> TxParams:
|
|
|
204
206
|
msg = 'failure to handle this transaction due to both "input: {}" and'
|
|
205
207
|
msg += ' "data: {}" are populated. You need to resolve this conflict.'
|
|
206
208
|
err_vals = (transaction_params["input"], extracted_params["data"])
|
|
207
|
-
raise
|
|
209
|
+
raise Web3AttributeError(msg.format(*err_vals))
|
|
208
210
|
else:
|
|
209
211
|
return extracted_params
|
|
210
212
|
else:
|
|
@@ -223,7 +225,7 @@ def extract_valid_transaction_params(transaction_params: TxData) -> TxParams:
|
|
|
223
225
|
def assert_valid_transaction_params(transaction_params: TxParams) -> None:
|
|
224
226
|
for param in transaction_params:
|
|
225
227
|
if param not in VALID_TRANSACTION_PARAMS:
|
|
226
|
-
raise
|
|
228
|
+
raise Web3ValueError(f"{param} is not a valid transaction parameter")
|
|
227
229
|
|
|
228
230
|
|
|
229
231
|
def prepare_replacement_transaction(
|
|
@@ -233,14 +235,14 @@ def prepare_replacement_transaction(
|
|
|
233
235
|
gas_multiplier: float = 1.125,
|
|
234
236
|
) -> TxParams:
|
|
235
237
|
if original_transaction["blockHash"] is not None:
|
|
236
|
-
raise
|
|
238
|
+
raise Web3ValueError(
|
|
237
239
|
f'Supplied transaction with hash {original_transaction["hash"]!r} '
|
|
238
240
|
"has already been mined"
|
|
239
241
|
)
|
|
240
242
|
if "nonce" in replacement_transaction and (
|
|
241
243
|
replacement_transaction["nonce"] != original_transaction["nonce"]
|
|
242
244
|
):
|
|
243
|
-
raise
|
|
245
|
+
raise Web3ValueError(
|
|
244
246
|
"Supplied nonce in new_transaction must match the pending transaction"
|
|
245
247
|
)
|
|
246
248
|
|
|
@@ -259,7 +261,7 @@ def prepare_replacement_transaction(
|
|
|
259
261
|
and original_transaction["gasPrice"] is not None
|
|
260
262
|
):
|
|
261
263
|
if replacement_transaction["gasPrice"] <= original_transaction["gasPrice"]:
|
|
262
|
-
raise
|
|
264
|
+
raise Web3ValueError(
|
|
263
265
|
"Supplied gas price must exceed existing transaction gas price"
|
|
264
266
|
)
|
|
265
267
|
|
web3/_utils/type_conversion.py
CHANGED
|
@@ -10,6 +10,10 @@ from eth_utils import (
|
|
|
10
10
|
to_hex,
|
|
11
11
|
)
|
|
12
12
|
|
|
13
|
+
from web3.exceptions import (
|
|
14
|
+
Web3ValueError,
|
|
15
|
+
)
|
|
16
|
+
|
|
13
17
|
|
|
14
18
|
def to_hex_if_bytes(val: Union[HexStr, str, bytes, bytearray]) -> HexStr:
|
|
15
19
|
"""
|
|
@@ -17,7 +21,7 @@ def to_hex_if_bytes(val: Union[HexStr, str, bytes, bytearray]) -> HexStr:
|
|
|
17
21
|
meant to work with bytes and hex strings.
|
|
18
22
|
"""
|
|
19
23
|
if isinstance(val, str) and not val.startswith("0x"):
|
|
20
|
-
raise
|
|
24
|
+
raise Web3ValueError(f"Expected a hex string. Got: {val!r}")
|
|
21
25
|
|
|
22
26
|
return to_hex(val) if isinstance(val, (bytes, bytearray)) else to_hex(hexstr=val)
|
|
23
27
|
|
web3/_utils/validation.py
CHANGED
|
@@ -53,6 +53,8 @@ from web3._utils.abi import (
|
|
|
53
53
|
)
|
|
54
54
|
from web3.exceptions import (
|
|
55
55
|
InvalidAddress,
|
|
56
|
+
Web3TypeError,
|
|
57
|
+
Web3ValueError,
|
|
56
58
|
)
|
|
57
59
|
from web3.types import (
|
|
58
60
|
ABI,
|
|
@@ -74,16 +76,16 @@ def validate_abi(abi: ABI) -> None:
|
|
|
74
76
|
Helper function for validating an ABI
|
|
75
77
|
"""
|
|
76
78
|
if not is_list_like(abi):
|
|
77
|
-
raise
|
|
79
|
+
raise Web3ValueError("'abi' is not a list")
|
|
78
80
|
|
|
79
81
|
if not all(is_dict(e) for e in abi):
|
|
80
|
-
raise
|
|
82
|
+
raise Web3ValueError("'abi' is not a list of dictionaries")
|
|
81
83
|
|
|
82
84
|
functions = filter_by_type("function", abi)
|
|
83
85
|
selectors = groupby(compose(encode_hex, function_abi_to_4byte_selector), functions)
|
|
84
86
|
duplicates = valfilter(lambda funcs: len(funcs) > 1, selectors)
|
|
85
87
|
if duplicates:
|
|
86
|
-
raise
|
|
88
|
+
raise Web3ValueError(
|
|
87
89
|
"Abi contains functions with colliding selectors. "
|
|
88
90
|
f"Functions {_prepare_selector_collision_msg(duplicates)}"
|
|
89
91
|
)
|
|
@@ -94,7 +96,7 @@ def validate_abi_type(abi_type: TypeStr) -> None:
|
|
|
94
96
|
Helper function for validating an abi_type
|
|
95
97
|
"""
|
|
96
98
|
if not is_recognized_type(abi_type):
|
|
97
|
-
raise
|
|
99
|
+
raise Web3ValueError(f"Unrecognized abi_type: {abi_type}")
|
|
98
100
|
|
|
99
101
|
|
|
100
102
|
def validate_abi_value(abi_type: TypeStr, value: Any) -> None:
|
|
@@ -107,12 +109,12 @@ def validate_abi_value(abi_type: TypeStr, value: Any) -> None:
|
|
|
107
109
|
specified_length = length_of_array_type(abi_type)
|
|
108
110
|
if specified_length is not None:
|
|
109
111
|
if specified_length < 1:
|
|
110
|
-
raise
|
|
112
|
+
raise Web3TypeError(
|
|
111
113
|
f"Invalid abi-type: {abi_type}. Length of fixed sized "
|
|
112
114
|
"arrays must be greater than 0."
|
|
113
115
|
)
|
|
114
116
|
if specified_length != len(value):
|
|
115
|
-
raise
|
|
117
|
+
raise Web3TypeError(
|
|
116
118
|
"The following array length does not the length specified"
|
|
117
119
|
f"by the abi-type, {abi_type}: {value}"
|
|
118
120
|
)
|
|
@@ -138,14 +140,14 @@ def validate_abi_value(abi_type: TypeStr, value: Any) -> None:
|
|
|
138
140
|
if is_0x_prefixed(value):
|
|
139
141
|
return
|
|
140
142
|
else:
|
|
141
|
-
raise
|
|
143
|
+
raise Web3TypeError(
|
|
142
144
|
"ABI values of abi-type 'bytes' must be either"
|
|
143
145
|
"a python3 'bytes' object or an '0x' prefixed string."
|
|
144
146
|
)
|
|
145
147
|
elif is_string_type(abi_type) and is_string(value):
|
|
146
148
|
return
|
|
147
149
|
|
|
148
|
-
raise
|
|
150
|
+
raise Web3TypeError(f"The following abi value is not a '{abi_type}': {value}")
|
|
149
151
|
|
|
150
152
|
|
|
151
153
|
def is_not_address_string(value: Any) -> bool:
|
|
@@ -173,7 +175,7 @@ def validate_address(value: Any) -> None:
|
|
|
173
175
|
return
|
|
174
176
|
|
|
175
177
|
if not isinstance(value, str):
|
|
176
|
-
raise
|
|
178
|
+
raise Web3TypeError(f"Address {value} must be provided as a string")
|
|
177
179
|
if not is_hex_address(value):
|
|
178
180
|
raise InvalidAddress(
|
|
179
181
|
"Address must be 20 bytes, as a hex string with a 0x prefix", value
|
|
@@ -204,7 +206,7 @@ def has_one_val(*args: Any, **kwargs: Any) -> bool:
|
|
|
204
206
|
|
|
205
207
|
def assert_one_val(*args: Any, **kwargs: Any) -> None:
|
|
206
208
|
if not has_one_val(*args, **kwargs):
|
|
207
|
-
raise
|
|
209
|
+
raise Web3TypeError(
|
|
208
210
|
"Exactly one of the passed values can be specified. "
|
|
209
211
|
f"Instead, values were: {args!r}, {kwargs!r}"
|
|
210
212
|
)
|
web3/contract/async_contract.py
CHANGED
|
@@ -82,7 +82,10 @@ from web3.exceptions import (
|
|
|
82
82
|
ABIFunctionNotFound,
|
|
83
83
|
NoABIFound,
|
|
84
84
|
NoABIFunctionsFound,
|
|
85
|
+
Web3AttributeError,
|
|
86
|
+
Web3TypeError,
|
|
85
87
|
Web3ValidationError,
|
|
88
|
+
Web3ValueError,
|
|
86
89
|
)
|
|
87
90
|
from web3.types import (
|
|
88
91
|
ABI,
|
|
@@ -112,7 +115,8 @@ class AsyncContractEvent(BaseContractEvent):
|
|
|
112
115
|
toBlock: Optional[BlockIdentifier] = None,
|
|
113
116
|
block_hash: Optional[HexBytes] = None,
|
|
114
117
|
) -> Awaitable[Iterable[EventData]]:
|
|
115
|
-
"""
|
|
118
|
+
"""
|
|
119
|
+
Get events for this contract instance using eth_getLogs API.
|
|
116
120
|
|
|
117
121
|
This is a stateless method, as opposed to createFilter.
|
|
118
122
|
It can be safely called against nodes which do not provide
|
|
@@ -440,12 +444,13 @@ class AsyncContract(BaseContract):
|
|
|
440
444
|
events: AsyncContractEvents = None
|
|
441
445
|
|
|
442
446
|
def __init__(self, address: Optional[ChecksumAddress] = None) -> None:
|
|
443
|
-
"""
|
|
444
|
-
|
|
445
|
-
:param address: Contract address as 0x hex string"""
|
|
447
|
+
"""
|
|
448
|
+
Create a new smart contract proxy object.
|
|
446
449
|
|
|
450
|
+
:param address: Contract address as 0x hex string
|
|
451
|
+
"""
|
|
447
452
|
if self.w3 is None:
|
|
448
|
-
raise
|
|
453
|
+
raise Web3AttributeError(
|
|
449
454
|
"The `Contract` class has not been initialized. Please use the "
|
|
450
455
|
"`web3.contract` interface to create your contract class."
|
|
451
456
|
)
|
|
@@ -454,7 +459,7 @@ class AsyncContract(BaseContract):
|
|
|
454
459
|
self.address = normalize_address_no_ens(address)
|
|
455
460
|
|
|
456
461
|
if not self.address:
|
|
457
|
-
raise
|
|
462
|
+
raise Web3TypeError(
|
|
458
463
|
"The address argument is required to instantiate a contract."
|
|
459
464
|
)
|
|
460
465
|
self.functions = AsyncContractFunctions(
|
|
@@ -523,7 +528,7 @@ class AsyncContract(BaseContract):
|
|
|
523
528
|
:return: a contract constructor object
|
|
524
529
|
"""
|
|
525
530
|
if cls.bytecode is None:
|
|
526
|
-
raise
|
|
531
|
+
raise Web3ValueError(
|
|
527
532
|
"Cannot call constructor on a contract that does not have "
|
|
528
533
|
"'bytecode' associated with it"
|
|
529
534
|
)
|
web3/contract/base_contract.py
CHANGED
|
@@ -92,7 +92,10 @@ from web3.exceptions import (
|
|
|
92
92
|
NoABIEventsFound,
|
|
93
93
|
NoABIFound,
|
|
94
94
|
NoABIFunctionsFound,
|
|
95
|
+
Web3AttributeError,
|
|
96
|
+
Web3TypeError,
|
|
95
97
|
Web3ValidationError,
|
|
98
|
+
Web3ValueError,
|
|
96
99
|
)
|
|
97
100
|
from web3.logs import (
|
|
98
101
|
DISCARD,
|
|
@@ -125,7 +128,8 @@ if TYPE_CHECKING:
|
|
|
125
128
|
|
|
126
129
|
|
|
127
130
|
class BaseContractEvent:
|
|
128
|
-
"""
|
|
131
|
+
"""
|
|
132
|
+
Base class for contract events
|
|
129
133
|
|
|
130
134
|
An event accessed via the api `contract.events.myEvents(*args, **kwargs)`
|
|
131
135
|
is a subclass of this class.
|
|
@@ -163,7 +167,7 @@ class BaseContractEvent:
|
|
|
163
167
|
try:
|
|
164
168
|
errors.name
|
|
165
169
|
except AttributeError:
|
|
166
|
-
raise
|
|
170
|
+
raise Web3AttributeError(
|
|
167
171
|
f"Error flag must be one of: {EventLogErrorFlags.flag_options()}"
|
|
168
172
|
)
|
|
169
173
|
|
|
@@ -185,7 +189,8 @@ class BaseContractEvent:
|
|
|
185
189
|
f"The log with transaction hash: {log['transactionHash']!r} "
|
|
186
190
|
f"and logIndex: {log['logIndex']} encountered the following "
|
|
187
191
|
f"error during processing: {type(e).__name__}({e}). It has "
|
|
188
|
-
"been discarded."
|
|
192
|
+
"been discarded.",
|
|
193
|
+
stacklevel=2,
|
|
189
194
|
)
|
|
190
195
|
continue
|
|
191
196
|
yield rich_log
|
|
@@ -204,7 +209,7 @@ class BaseContractEvent:
|
|
|
204
209
|
blockHash: Optional[HexBytes] = None,
|
|
205
210
|
) -> FilterParams:
|
|
206
211
|
if not self.address:
|
|
207
|
-
raise
|
|
212
|
+
raise Web3TypeError(
|
|
208
213
|
"This method can be only called on "
|
|
209
214
|
"an instated contract with an address"
|
|
210
215
|
)
|
|
@@ -251,12 +256,12 @@ class BaseContractEvent:
|
|
|
251
256
|
for filter_name, filter_value in _filters.items():
|
|
252
257
|
_input = name_indexed_inputs[filter_name]
|
|
253
258
|
if is_array_type(_input["type"]):
|
|
254
|
-
raise
|
|
259
|
+
raise Web3TypeError(
|
|
255
260
|
"createFilter no longer supports array type filter arguments. "
|
|
256
261
|
"see the build_filter method for filtering array type filters."
|
|
257
262
|
)
|
|
258
263
|
if is_list_like(filter_value) and is_dynamic_sized_type(_input["type"]):
|
|
259
|
-
raise
|
|
264
|
+
raise Web3TypeError(
|
|
260
265
|
"createFilter no longer supports setting filter argument options "
|
|
261
266
|
"for dynamic sized types. See the build_filter method for setting "
|
|
262
267
|
"filters with the match_any method."
|
|
@@ -321,7 +326,7 @@ class BaseContractEvent:
|
|
|
321
326
|
filter_builder: Union[EventFilterBuilder, AsyncEventFilterBuilder] = None,
|
|
322
327
|
) -> None:
|
|
323
328
|
if fromBlock is None:
|
|
324
|
-
raise
|
|
329
|
+
raise Web3TypeError(
|
|
325
330
|
"Missing mandatory keyword argument to create_filter: fromBlock"
|
|
326
331
|
)
|
|
327
332
|
|
|
@@ -370,7 +375,8 @@ class BaseContractEvent:
|
|
|
370
375
|
|
|
371
376
|
|
|
372
377
|
class BaseContractEvents:
|
|
373
|
-
"""
|
|
378
|
+
"""
|
|
379
|
+
Class containing contract event objects
|
|
374
380
|
|
|
375
381
|
This is available via:
|
|
376
382
|
|
|
@@ -431,7 +437,8 @@ class BaseContractEvents:
|
|
|
431
437
|
return getattr(self, event_name)
|
|
432
438
|
|
|
433
439
|
def __iter__(self) -> Iterable[Type["BaseContractEvent"]]:
|
|
434
|
-
"""
|
|
440
|
+
"""
|
|
441
|
+
Iterate over supported
|
|
435
442
|
|
|
436
443
|
:return: Iterable of :class:`ContractEvent`
|
|
437
444
|
"""
|
|
@@ -446,7 +453,8 @@ class BaseContractEvents:
|
|
|
446
453
|
|
|
447
454
|
|
|
448
455
|
class BaseContractFunction:
|
|
449
|
-
"""
|
|
456
|
+
"""
|
|
457
|
+
Base class for contract functions
|
|
450
458
|
|
|
451
459
|
A function accessed via the api `contract.functions.myMethod(*args, **kwargs)`
|
|
452
460
|
is a subclass of this class.
|
|
@@ -479,12 +487,9 @@ class BaseContractFunction:
|
|
|
479
487
|
if self.function_identifier in [FallbackFn, ReceiveFn]:
|
|
480
488
|
self.selector = encode_hex(b"")
|
|
481
489
|
elif is_text(self.function_identifier):
|
|
482
|
-
|
|
483
|
-
self.selector = encode_hex(
|
|
484
|
-
function_abi_to_4byte_selector(self.abi) # type: ignore
|
|
485
|
-
)
|
|
490
|
+
self.selector = encode_hex(function_abi_to_4byte_selector(self.abi))
|
|
486
491
|
else:
|
|
487
|
-
raise
|
|
492
|
+
raise Web3TypeError("Unsupported function identifier")
|
|
488
493
|
|
|
489
494
|
self.arguments = merge_args_and_kwargs(self.abi, self.args, self.kwargs)
|
|
490
495
|
|
|
@@ -495,26 +500,25 @@ class BaseContractFunction:
|
|
|
495
500
|
call_transaction = cast(TxParams, dict(**transaction))
|
|
496
501
|
|
|
497
502
|
if "data" in call_transaction:
|
|
498
|
-
raise
|
|
503
|
+
raise Web3ValueError("Cannot set 'data' field in call transaction")
|
|
499
504
|
|
|
500
505
|
if self.address:
|
|
501
506
|
call_transaction.setdefault("to", self.address)
|
|
502
507
|
if self.w3.eth.default_account is not empty:
|
|
503
|
-
# type ignored b/c check prevents an empty default_account
|
|
504
508
|
call_transaction.setdefault(
|
|
505
509
|
"from",
|
|
506
|
-
self.w3.eth.default_account,
|
|
510
|
+
self.w3.eth.default_account,
|
|
507
511
|
)
|
|
508
512
|
|
|
509
513
|
if "to" not in call_transaction:
|
|
510
514
|
if isinstance(self, type):
|
|
511
|
-
raise
|
|
515
|
+
raise Web3ValueError(
|
|
512
516
|
"When using `Contract.[methodtype].[method].call()` from"
|
|
513
517
|
" a contract factory you "
|
|
514
518
|
"must provide a `to` address with the transaction"
|
|
515
519
|
)
|
|
516
520
|
else:
|
|
517
|
-
raise
|
|
521
|
+
raise Web3ValueError(
|
|
518
522
|
"Please ensure that this contract instance has an address."
|
|
519
523
|
)
|
|
520
524
|
|
|
@@ -527,24 +531,21 @@ class BaseContractFunction:
|
|
|
527
531
|
transact_transaction = cast(TxParams, dict(**transaction))
|
|
528
532
|
|
|
529
533
|
if "data" in transact_transaction:
|
|
530
|
-
raise
|
|
534
|
+
raise Web3ValueError("Cannot set 'data' field in transact transaction")
|
|
531
535
|
|
|
532
536
|
if self.address is not None:
|
|
533
537
|
transact_transaction.setdefault("to", self.address)
|
|
534
538
|
if self.w3.eth.default_account is not empty:
|
|
535
|
-
|
|
536
|
-
transact_transaction.setdefault(
|
|
537
|
-
"from", self.w3.eth.default_account # type: ignore
|
|
538
|
-
)
|
|
539
|
+
transact_transaction.setdefault("from", self.w3.eth.default_account)
|
|
539
540
|
|
|
540
541
|
if "to" not in transact_transaction:
|
|
541
542
|
if isinstance(self, type):
|
|
542
|
-
raise
|
|
543
|
+
raise Web3ValueError(
|
|
543
544
|
"When using `Contract.transact` from a contract factory you "
|
|
544
545
|
"must provide a `to` address with the transaction"
|
|
545
546
|
)
|
|
546
547
|
else:
|
|
547
|
-
raise
|
|
548
|
+
raise Web3ValueError(
|
|
548
549
|
"Please ensure that this contract instance has an address."
|
|
549
550
|
)
|
|
550
551
|
return transact_transaction
|
|
@@ -556,26 +557,23 @@ class BaseContractFunction:
|
|
|
556
557
|
estimate_gas_transaction = cast(TxParams, dict(**transaction))
|
|
557
558
|
|
|
558
559
|
if "data" in estimate_gas_transaction:
|
|
559
|
-
raise
|
|
560
|
+
raise Web3ValueError("Cannot set 'data' field in estimate_gas transaction")
|
|
560
561
|
if "to" in estimate_gas_transaction:
|
|
561
|
-
raise
|
|
562
|
+
raise Web3ValueError("Cannot set to in estimate_gas transaction")
|
|
562
563
|
|
|
563
564
|
if self.address:
|
|
564
565
|
estimate_gas_transaction.setdefault("to", self.address)
|
|
565
566
|
if self.w3.eth.default_account is not empty:
|
|
566
|
-
|
|
567
|
-
estimate_gas_transaction.setdefault(
|
|
568
|
-
"from", self.w3.eth.default_account # type: ignore
|
|
569
|
-
)
|
|
567
|
+
estimate_gas_transaction.setdefault("from", self.w3.eth.default_account)
|
|
570
568
|
|
|
571
569
|
if "to" not in estimate_gas_transaction:
|
|
572
570
|
if isinstance(self, type):
|
|
573
|
-
raise
|
|
571
|
+
raise Web3ValueError(
|
|
574
572
|
"When using `Contract.estimate_gas` from a contract factory "
|
|
575
573
|
"you must provide a `to` address with the transaction"
|
|
576
574
|
)
|
|
577
575
|
else:
|
|
578
|
-
raise
|
|
576
|
+
raise Web3ValueError(
|
|
579
577
|
"Please ensure that this contract instance has an address."
|
|
580
578
|
)
|
|
581
579
|
return estimate_gas_transaction
|
|
@@ -587,21 +585,23 @@ class BaseContractFunction:
|
|
|
587
585
|
built_transaction = cast(TxParams, dict(**transaction))
|
|
588
586
|
|
|
589
587
|
if "data" in built_transaction:
|
|
590
|
-
raise
|
|
588
|
+
raise Web3ValueError("Cannot set 'data' field in build transaction")
|
|
591
589
|
|
|
592
590
|
if not self.address and "to" not in built_transaction:
|
|
593
|
-
raise
|
|
591
|
+
raise Web3ValueError(
|
|
594
592
|
"When using `ContractFunction.build_transaction` from a contract "
|
|
595
593
|
"factory you must provide a `to` address with the transaction"
|
|
596
594
|
)
|
|
597
595
|
if self.address and "to" in built_transaction:
|
|
598
|
-
raise
|
|
596
|
+
raise Web3ValueError(
|
|
597
|
+
"Cannot set 'to' field in contract call build transaction"
|
|
598
|
+
)
|
|
599
599
|
|
|
600
600
|
if self.address:
|
|
601
601
|
built_transaction.setdefault("to", self.address)
|
|
602
602
|
|
|
603
603
|
if "to" not in built_transaction:
|
|
604
|
-
raise
|
|
604
|
+
raise Web3ValueError(
|
|
605
605
|
"Please ensure that this contract instance has an address."
|
|
606
606
|
)
|
|
607
607
|
|
|
@@ -679,7 +679,8 @@ class BaseContractFunctions:
|
|
|
679
679
|
|
|
680
680
|
|
|
681
681
|
class BaseContract:
|
|
682
|
-
"""
|
|
682
|
+
"""
|
|
683
|
+
Base class for Contract proxy classes.
|
|
683
684
|
|
|
684
685
|
First you need to create your Contract classes using
|
|
685
686
|
:meth:`web3.eth.Eth.contract` that takes compiled Solidity contract
|
|
@@ -760,7 +761,7 @@ class BaseContract:
|
|
|
760
761
|
@combomethod
|
|
761
762
|
def get_function_by_signature(self, signature: str) -> "BaseContractFunction":
|
|
762
763
|
if " " in signature:
|
|
763
|
-
raise
|
|
764
|
+
raise Web3ValueError(
|
|
764
765
|
"Function signature should not contain any spaces. "
|
|
765
766
|
f"Found spaces in input: {signature}"
|
|
766
767
|
)
|
|
@@ -792,9 +793,9 @@ class BaseContract:
|
|
|
792
793
|
self, selector: Union[bytes, int, HexStr]
|
|
793
794
|
) -> "BaseContractFunction":
|
|
794
795
|
def callable_check(fn_abi: ABIFunction) -> bool:
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
796
|
+
return encode_hex(function_abi_to_4byte_selector(fn_abi)) == to_4byte_hex(
|
|
797
|
+
selector
|
|
798
|
+
)
|
|
798
799
|
|
|
799
800
|
fns = self.find_functions_by_identifier(
|
|
800
801
|
self.abi, self.w3, self.address, callable_check
|
|
@@ -805,8 +806,7 @@ class BaseContract:
|
|
|
805
806
|
def decode_function_input(
|
|
806
807
|
self, data: HexStr
|
|
807
808
|
) -> Tuple["BaseContractFunction", Dict[str, Any]]:
|
|
808
|
-
|
|
809
|
-
data = HexBytes(data) # type: ignore
|
|
809
|
+
data = HexBytes(data)
|
|
810
810
|
func = self.get_function_by_selector(data[:4])
|
|
811
811
|
arguments = decode_transaction_data(
|
|
812
812
|
func.abi, data, normalizers=BASE_RETURN_NORMALIZERS
|
|
@@ -893,7 +893,7 @@ class BaseContract:
|
|
|
893
893
|
else:
|
|
894
894
|
if args is not None or kwargs is not None:
|
|
895
895
|
msg = "Constructor args were provided, but no constructor function was provided." # noqa: E501
|
|
896
|
-
raise
|
|
896
|
+
raise Web3TypeError(msg)
|
|
897
897
|
|
|
898
898
|
deploy_data = to_hex(cls.bytecode)
|
|
899
899
|
|
|
@@ -1088,10 +1088,7 @@ class BaseContractConstructor:
|
|
|
1088
1088
|
)
|
|
1089
1089
|
|
|
1090
1090
|
if self.w3.eth.default_account is not empty:
|
|
1091
|
-
|
|
1092
|
-
estimate_gas_transaction.setdefault(
|
|
1093
|
-
"from", self.w3.eth.default_account # type: ignore
|
|
1094
|
-
)
|
|
1091
|
+
estimate_gas_transaction.setdefault("from", self.w3.eth.default_account)
|
|
1095
1092
|
|
|
1096
1093
|
estimate_gas_transaction["data"] = self.data_in_transaction
|
|
1097
1094
|
|
|
@@ -1107,10 +1104,7 @@ class BaseContractConstructor:
|
|
|
1107
1104
|
)
|
|
1108
1105
|
|
|
1109
1106
|
if self.w3.eth.default_account is not empty:
|
|
1110
|
-
|
|
1111
|
-
transact_transaction.setdefault(
|
|
1112
|
-
"from", self.w3.eth.default_account # type: ignore
|
|
1113
|
-
)
|
|
1107
|
+
transact_transaction.setdefault("from", self.w3.eth.default_account)
|
|
1114
1108
|
|
|
1115
1109
|
transact_transaction["data"] = self.data_in_transaction
|
|
1116
1110
|
|
|
@@ -1128,7 +1122,7 @@ class BaseContractConstructor:
|
|
|
1128
1122
|
) -> None:
|
|
1129
1123
|
keys_found = transaction.keys() & forbidden_keys
|
|
1130
1124
|
if keys_found:
|
|
1131
|
-
raise
|
|
1125
|
+
raise Web3ValueError(
|
|
1132
1126
|
f"Cannot set '{', '.join(keys_found)}' field(s) in transaction"
|
|
1133
1127
|
)
|
|
1134
1128
|
|
web3/contract/contract.py
CHANGED
|
@@ -81,7 +81,10 @@ from web3.exceptions import (
|
|
|
81
81
|
ABIFunctionNotFound,
|
|
82
82
|
NoABIFound,
|
|
83
83
|
NoABIFunctionsFound,
|
|
84
|
+
Web3AttributeError,
|
|
85
|
+
Web3TypeError,
|
|
84
86
|
Web3ValidationError,
|
|
87
|
+
Web3ValueError,
|
|
85
88
|
)
|
|
86
89
|
from web3.types import (
|
|
87
90
|
ABI,
|
|
@@ -111,7 +114,8 @@ class ContractEvent(BaseContractEvent):
|
|
|
111
114
|
toBlock: Optional[BlockIdentifier] = None,
|
|
112
115
|
block_hash: Optional[HexBytes] = None,
|
|
113
116
|
) -> Iterable[EventData]:
|
|
114
|
-
"""
|
|
117
|
+
"""
|
|
118
|
+
Get events for this contract instance using eth_getLogs API.
|
|
115
119
|
|
|
116
120
|
This is a stateless method, as opposed to create_filter.
|
|
117
121
|
It can be safely called against nodes which do not provide
|
|
@@ -438,11 +442,13 @@ class Contract(BaseContract):
|
|
|
438
442
|
events: ContractEvents = None
|
|
439
443
|
|
|
440
444
|
def __init__(self, address: Optional[ChecksumAddress] = None) -> None:
|
|
441
|
-
"""
|
|
442
|
-
|
|
445
|
+
"""
|
|
446
|
+
Create a new smart contract proxy object.
|
|
447
|
+
:param address: Contract address as 0x hex string
|
|
448
|
+
"""
|
|
443
449
|
_w3 = self.w3
|
|
444
450
|
if _w3 is None:
|
|
445
|
-
raise
|
|
451
|
+
raise Web3AttributeError(
|
|
446
452
|
"The `Contract` class has not been initialized. Please use the "
|
|
447
453
|
"`web3.contract` interface to create your contract class."
|
|
448
454
|
)
|
|
@@ -451,7 +457,7 @@ class Contract(BaseContract):
|
|
|
451
457
|
self.address = normalize_address(cast("ENS", _w3.ens), address)
|
|
452
458
|
|
|
453
459
|
if not self.address:
|
|
454
|
-
raise
|
|
460
|
+
raise Web3TypeError(
|
|
455
461
|
"The address argument is required to instantiate a contract."
|
|
456
462
|
)
|
|
457
463
|
|
|
@@ -528,7 +534,7 @@ class Contract(BaseContract):
|
|
|
528
534
|
:return: a contract constructor object
|
|
529
535
|
"""
|
|
530
536
|
if cls.bytecode is None:
|
|
531
|
-
raise
|
|
537
|
+
raise Web3ValueError(
|
|
532
538
|
"Cannot call constructor on a contract that does not have "
|
|
533
539
|
"'bytecode' associated with it"
|
|
534
540
|
)
|