0
# Smart Contracts
1
2
Smart contract deployment, interaction, and management with ABI-based function calls, event filtering, transaction handling, and comprehensive type support for contract development.
3
4
## Capabilities
5
6
### Contract Factory
7
8
Create contract instances for deployment or interaction with existing contracts.
9
10
```python { .api }
11
class Contract:
12
def __init__(
13
self,
14
address: Optional[AnyAddress] = None,
15
abi: Optional[ABI] = None
16
):
17
"""
18
Initialize contract instance.
19
20
Parameters:
21
- address: Contract address (for existing contracts)
22
- abi: Contract Application Binary Interface
23
"""
24
25
@classmethod
26
def constructor(
27
cls,
28
**constructor_kwargs: Any
29
) -> ContractConstructor:
30
"""
31
Create contract constructor for deployment.
32
33
Parameters:
34
- constructor_kwargs: Constructor arguments
35
"""
36
37
@property
38
def address(self) -> ChecksumAddress:
39
"""Get contract address."""
40
41
@property
42
def abi(self) -> ABI:
43
"""Get contract ABI."""
44
45
@property
46
def functions(self) -> ContractFunctions:
47
"""Access contract functions."""
48
49
@property
50
def events(self) -> ContractEvents:
51
"""Access contract events."""
52
53
@property
54
def fallback(self) -> ContractFunction:
55
"""Access fallback function."""
56
57
@property
58
def receive(self) -> ContractFunction:
59
"""Access receive function."""
60
61
def caller(self, transaction: Optional[TxParams] = None) -> ContractCaller:
62
"""
63
Create contract caller for read-only operations.
64
65
Parameters:
66
- transaction: Transaction parameters for call context
67
"""
68
```
69
70
### Async Contract
71
72
Async version of contract operations with the same interface.
73
74
```python { .api }
75
class AsyncContract:
76
def __init__(
77
self,
78
address: Optional[AnyAddress] = None,
79
abi: Optional[ABI] = None
80
):
81
"""
82
Initialize async contract instance.
83
84
Parameters:
85
- address: Contract address
86
- abi: Contract ABI
87
"""
88
89
@classmethod
90
async def constructor(
91
cls,
92
**constructor_kwargs: Any
93
) -> AsyncContractConstructor:
94
"""Async contract constructor."""
95
96
@property
97
def address(self) -> ChecksumAddress:
98
"""Get contract address."""
99
100
@property
101
def abi(self) -> ABI:
102
"""Get contract ABI."""
103
104
@property
105
def functions(self) -> AsyncContractFunctions:
106
"""Access async contract functions."""
107
108
@property
109
def events(self) -> AsyncContractEvents:
110
"""Access async contract events."""
111
112
def caller(self, transaction: Optional[TxParams] = None) -> AsyncContractCaller:
113
"""Create async contract caller."""
114
```
115
116
### Contract Functions
117
118
Interface for calling contract functions and sending transactions.
119
120
```python { .api }
121
class ContractFunction:
122
def call(
123
self,
124
transaction: Optional[TxParams] = None,
125
block_identifier: BlockIdentifier = "latest"
126
) -> Any:
127
"""
128
Call function without creating transaction.
129
130
Parameters:
131
- transaction: Transaction parameters for call context
132
- block_identifier: Block for execution
133
"""
134
135
def transact(self, transaction: Optional[TxParams] = None) -> HexBytes:
136
"""
137
Execute function as transaction.
138
139
Parameters:
140
- transaction: Transaction parameters
141
142
Returns:
143
Transaction hash
144
"""
145
146
def estimate_gas(
147
self,
148
transaction: Optional[TxParams] = None,
149
block_identifier: BlockIdentifier = "latest"
150
) -> int:
151
"""
152
Estimate gas for function execution.
153
154
Parameters:
155
- transaction: Transaction parameters
156
- block_identifier: Block for estimation
157
"""
158
159
def build_transaction(self, transaction: Optional[TxParams] = None) -> TxParams:
160
"""
161
Build transaction data for function call.
162
163
Parameters:
164
- transaction: Base transaction parameters
165
"""
166
```
167
168
### Contract Events
169
170
Interface for filtering and processing contract events.
171
172
```python { .api }
173
class ContractEvent:
174
def get_logs(
175
self,
176
from_block: BlockIdentifier = "earliest",
177
to_block: BlockIdentifier = "latest",
178
argument_filters: Optional[Dict[str, Any]] = None
179
) -> List[EventData]:
180
"""
181
Get historical event logs.
182
183
Parameters:
184
- from_block: Starting block
185
- to_block: Ending block
186
- argument_filters: Filter by event arguments
187
"""
188
189
def create_filter(
190
self,
191
from_block: BlockIdentifier = "latest",
192
to_block: BlockIdentifier = "latest",
193
argument_filters: Optional[Dict[str, Any]] = None
194
) -> LogFilter:
195
"""
196
Create event filter for new events.
197
198
Parameters:
199
- from_block: Starting block
200
- to_block: Ending block
201
- argument_filters: Filter by event arguments
202
"""
203
204
def process_log(self, log: LogReceipt) -> EventData:
205
"""
206
Process raw log into event data.
207
208
Parameters:
209
- log: Raw log receipt
210
"""
211
212
def process_receipt(self, receipt: TxReceipt) -> List[EventData]:
213
"""
214
Process transaction receipt for events.
215
216
Parameters:
217
- receipt: Transaction receipt
218
"""
219
```
220
221
### Contract Constructor
222
223
Interface for contract deployment.
224
225
```python { .api }
226
class ContractConstructor:
227
def transact(self, transaction: Optional[TxParams] = None) -> HexBytes:
228
"""
229
Deploy contract.
230
231
Parameters:
232
- transaction: Deployment transaction parameters
233
234
Returns:
235
Transaction hash
236
"""
237
238
def estimate_gas(
239
self,
240
transaction: Optional[TxParams] = None,
241
block_identifier: BlockIdentifier = "latest"
242
) -> int:
243
"""
244
Estimate gas for contract deployment.
245
246
Parameters:
247
- transaction: Deployment parameters
248
- block_identifier: Block for estimation
249
"""
250
251
def build_transaction(self, transaction: Optional[TxParams] = None) -> TxParams:
252
"""
253
Build deployment transaction.
254
255
Parameters:
256
- transaction: Base transaction parameters
257
"""
258
```
259
260
### Contract Caller
261
262
Interface for read-only contract operations.
263
264
```python { .api }
265
class ContractCaller:
266
def __init__(self, contract_functions: ContractFunctions):
267
"""
268
Initialize contract caller.
269
270
Parameters:
271
- contract_functions: Contract functions interface
272
"""
273
274
def __getattr__(self, function_name: str) -> Callable:
275
"""Access contract function for calling."""
276
```
277
278
## Types
279
280
Contract-related type definitions.
281
282
```python { .api }
283
ABI = List[ABIElement]
284
285
class ABIElement(TypedDict):
286
type: Literal["function", "constructor", "event", "fallback", "receive"]
287
name: NotRequired[str]
288
inputs: NotRequired[List[ABIInput]]
289
outputs: NotRequired[List[ABIOutput]]
290
stateMutability: NotRequired[Literal["pure", "view", "nonpayable", "payable"]]
291
292
class ABIInput(TypedDict):
293
name: str
294
type: str
295
indexed: NotRequired[bool]
296
297
class ABIOutput(TypedDict):
298
name: str
299
type: str
300
301
class EventData(TypedDict):
302
event: str
303
logIndex: int
304
transactionIndex: int
305
transactionHash: Hash32
306
address: ChecksumAddress
307
blockHash: Hash32
308
blockNumber: BlockNumber
309
args: Dict[str, Any]
310
311
class TxReceipt(TypedDict):
312
transactionHash: Hash32
313
transactionIndex: int
314
blockHash: Hash32
315
blockNumber: BlockNumber
316
from_: ChecksumAddress
317
to: ChecksumAddress
318
gasUsed: int
319
status: int
320
logs: List[LogReceipt]
321
contractAddress: Optional[ChecksumAddress]
322
```
323
324
## Usage Examples
325
326
### Contract Deployment
327
328
```python
329
from web3 import Web3
330
import json
331
332
w3 = Web3(Web3.HTTPProvider('http://localhost:8545'))
333
334
# Load contract ABI and bytecode
335
with open('contract.json') as f:
336
contract_data = json.load(f)
337
abi = contract_data['abi']
338
bytecode = contract_data['bytecode']
339
340
# Create contract factory
341
contract = w3.eth.contract(abi=abi, bytecode=bytecode)
342
343
# Deploy contract
344
constructor_tx = contract.constructor(
345
initial_value=100,
346
owner=w3.eth.accounts[0]
347
).build_transaction({
348
'from': w3.eth.accounts[0],
349
'gas': 2000000,
350
'gasPrice': w3.to_wei(20, 'gwei')
351
})
352
353
# Send deployment transaction
354
tx_hash = w3.eth.send_transaction(constructor_tx)
355
receipt = w3.eth.wait_for_transaction_receipt(tx_hash)
356
357
print(f"Contract deployed at: {receipt.contractAddress}")
358
```
359
360
### Contract Interaction
361
362
```python
363
from web3 import Web3
364
365
w3 = Web3(Web3.HTTPProvider('http://localhost:8545'))
366
367
# Connect to existing contract
368
contract_address = '0x123...'
369
contract_abi = [...] # Contract ABI
370
371
contract = w3.eth.contract(address=contract_address, abi=contract_abi)
372
373
# Call read-only function
374
balance = contract.functions.balanceOf('0x742d35Cc6635C0532925a3b8D5c0d9E3C4B3c8').call()
375
print(f"Balance: {balance}")
376
377
# Send transaction to contract function
378
tx_hash = contract.functions.transfer(
379
'0x456...',
380
w3.to_wei(10, 'ether')
381
).transact({
382
'from': w3.eth.accounts[0],
383
'gas': 100000
384
})
385
386
receipt = w3.eth.wait_for_transaction_receipt(tx_hash)
387
print(f"Transfer completed in block: {receipt.blockNumber}")
388
```
389
390
### Event Filtering
391
392
```python
393
from web3 import Web3
394
395
w3 = Web3(Web3.HTTPProvider('http://localhost:8545'))
396
contract = w3.eth.contract(address='0x123...', abi=abi)
397
398
# Get historical events
399
transfer_events = contract.events.Transfer.get_logs(
400
from_block=17000000,
401
to_block=17001000,
402
argument_filters={'from': '0x742d35Cc6635C0532925a3b8D5c0d9E3C4B3c8'}
403
)
404
405
for event in transfer_events:
406
print(f"Transfer: {event.args['from']} -> {event.args['to']}, Amount: {event.args['value']}")
407
408
# Create filter for new events
409
event_filter = contract.events.Transfer.create_filter(
410
from_block='latest',
411
argument_filters={'to': '0x456...'}
412
)
413
414
# Poll for new events
415
while True:
416
for event in event_filter.get_new_entries():
417
print(f"New transfer to monitored address: {event.args}")
418
time.sleep(2)
419
```
420
421
### Contract Caller
422
423
```python
424
from web3 import Web3
425
426
w3 = Web3(Web3.HTTPProvider('http://localhost:8545'))
427
contract = w3.eth.contract(address='0x123...', abi=abi)
428
429
# Use caller for read-only operations with custom context
430
caller = contract.caller({
431
'from': '0x742d35Cc6635C0532925a3b8D5c0d9E3C4B3c8',
432
'block_identifier': 17000000
433
})
434
435
# Call functions through caller
436
balance = caller.balanceOf('0x456...')
437
allowance = caller.allowance('0x742d35Cc6635C0532925a3b8D5c0d9E3C4B3c8', '0x456...')
438
439
print(f"Historical balance: {balance}")
440
print(f"Historical allowance: {allowance}")
441
```
442
443
### Async Contract Operations
444
445
```python
446
import asyncio
447
from web3 import AsyncWeb3
448
449
async def main():
450
w3 = AsyncWeb3(AsyncWeb3.AsyncHTTPProvider('http://localhost:8545'))
451
contract = w3.eth.contract(address='0x123...', abi=abi)
452
453
# Async contract call
454
balance = await contract.functions.balanceOf('0x742d35Cc6635C0532925a3b8D5c0d9E3C4B3c8').call()
455
print(f"Balance: {balance}")
456
457
# Async transaction
458
tx_hash = await contract.functions.transfer(
459
'0x456...',
460
w3.to_wei(1, 'ether')
461
).transact({'from': w3.eth.accounts[0]})
462
463
receipt = await w3.eth.wait_for_transaction_receipt(tx_hash)
464
print(f"Transaction completed: {receipt.transactionHash.hex()}")
465
466
asyncio.run(main())
467
```
468
469
### Processing Transaction Receipts
470
471
```python
472
from web3 import Web3
473
474
w3 = Web3(Web3.HTTPProvider('http://localhost:8545'))
475
contract = w3.eth.contract(address='0x123...', abi=abi)
476
477
# Send transaction
478
tx_hash = contract.functions.someMethod().transact({'from': w3.eth.accounts[0]})
479
receipt = w3.eth.wait_for_transaction_receipt(tx_hash)
480
481
# Process events from receipt
482
events = contract.events.SomeEvent.process_receipt(receipt)
483
for event in events:
484
print(f"Event data: {event.args}")
485
print(f"Event address: {event.address}")
486
print(f"Block number: {event.blockNumber}")
487
```