or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

accounts.mdcli.mdcontracts.mdconversion-testing.mdindex.mdnetwork.mdproject.md

contracts.mddocs/

0

# Contract Interaction

1

2

Smart contract deployment, method calls, event handling, and transaction management with comprehensive debugging and error reporting capabilities.

3

4

## Capabilities

5

6

### Contract Base Class

7

8

The core Contract class provides the interface for interacting with deployed smart contracts, handling method calls, transactions, and event parsing.

9

10

```python { .api }

11

class Contract:

12

"""

13

Interface for interacting with deployed smart contracts.

14

15

Attributes:

16

address (str): Contract's deployed address

17

abi (list): Contract's ABI (Application Binary Interface)

18

bytecode (str): Contract's bytecode

19

tx (TransactionReceipt): Deployment transaction receipt

20

"""

21

22

def __init__(self, address: str, abi: list, owner: Account = None):

23

"""

24

Initialize contract interface.

25

26

Args:

27

address: Contract's deployed address

28

abi: Contract's ABI definition

29

owner: Account that deployed the contract

30

"""

31

32

def __getattr__(self, name: str):

33

"""

34

Access contract methods and attributes dynamically.

35

36

Args:

37

name: Method or attribute name

38

39

Returns:

40

ContractCall or ContractTx: Callable for contract interaction

41

"""

42

43

def balance(self) -> Wei:

44

"""Get contract's ether balance."""

45

46

def selectors(self) -> dict:

47

"""Get mapping of function names to their selectors."""

48

49

def topics(self) -> dict:

50

"""Get mapping of event names to their topic hashes."""

51

52

def decode_logs(self, logs: list) -> list:

53

"""

54

Decode raw event logs using contract ABI.

55

56

Args:

57

logs: Raw event logs from transaction receipt

58

59

Returns:

60

list: Decoded event data

61

"""

62

63

def get_method(self, calldata: str):

64

"""

65

Get method information from transaction calldata.

66

67

Args:

68

calldata: Transaction input data

69

70

Returns:

71

Method information and decoded parameters

72

"""

73

```

74

75

### Project Contract

76

77

Enhanced contract class with build information and deployment artifacts, providing additional metadata and debugging capabilities.

78

79

```python { .api }

80

class ProjectContract(Contract):

81

"""

82

Contract with associated build information and deployment artifacts.

83

84

Additional attributes:

85

_name (str): Contract name from source

86

_sources (Sources): Associated source files

87

_build (dict): Build artifacts and metadata

88

"""

89

90

@classmethod

91

def deploy(cls, *args, **kwargs) -> 'ProjectContract':

92

"""

93

Deploy new instance of this contract.

94

95

Args:

96

*args: Constructor arguments

97

**kwargs: Transaction parameters (from, gas_limit, etc.)

98

99

Returns:

100

ProjectContract: Deployed contract instance

101

"""

102

103

@classmethod

104

def at(cls, address: str, owner: Account = None) -> 'ProjectContract':

105

"""

106

Connect to existing deployed contract.

107

108

Args:

109

address: Contract address

110

owner: Account that owns the contract

111

112

Returns:

113

ProjectContract: Contract instance at address

114

"""

115

116

def get_verification_info(self) -> dict:

117

"""Get contract verification information for block explorers."""

118

119

def publish_source(self, silent: bool = False) -> str:

120

"""

121

Publish contract source to block explorer.

122

123

Args:

124

silent: Suppress console output

125

126

Returns:

127

str: Verification URL or status

128

"""

129

```

130

131

### Contract Container

132

133

Container class that manages multiple contract instances and provides deployment and access methods for contract types.

134

135

```python { .api }

136

class ContractContainer:

137

"""

138

Container for managing contracts of the same type.

139

140

Attributes:

141

_name (str): Contract name

142

abi (list): Contract ABI

143

bytecode (str): Contract bytecode

144

"""

145

146

def __init__(self, project, build: dict):

147

"""Initialize container with project and build data."""

148

149

def __call__(self, *args, **kwargs) -> ProjectContract:

150

"""Deploy new contract instance (alias for deploy)."""

151

152

def __iter__(self):

153

"""Iterate over deployed contract instances."""

154

155

def __getitem__(self, index: int) -> ProjectContract:

156

"""Get deployed contract by index."""

157

158

def __len__(self) -> int:

159

"""Get number of deployed contracts."""

160

161

def deploy(self, *args, **kwargs) -> ProjectContract:

162

"""

163

Deploy new contract instance.

164

165

Args:

166

*args: Constructor arguments

167

**kwargs: Transaction parameters

168

169

Returns:

170

ProjectContract: Newly deployed contract

171

"""

172

173

def at(self, address: str, owner: Account = None) -> ProjectContract:

174

"""

175

Connect to existing contract at address.

176

177

Args:

178

address: Contract address

179

owner: Contract owner account

180

181

Returns:

182

ProjectContract: Contract instance

183

"""

184

185

def remove(self, contract: ProjectContract) -> None:

186

"""Remove contract from container."""

187

188

def estimate_gas(self, *args) -> int:

189

"""

190

Estimate gas for contract deployment.

191

192

Args:

193

*args: Constructor arguments

194

195

Returns:

196

int: Estimated gas amount

197

"""

198

```

199

200

### Interface Container

201

202

Container for managing contract interfaces (ABI without bytecode) for interacting with contracts not deployed through the current project.

203

204

```python { .api }

205

class InterfaceContainer:

206

"""

207

Container for contract interfaces (ABI-only contracts).

208

209

Used for interacting with contracts deployed elsewhere.

210

"""

211

212

def __init__(self, name: str, abi: list):

213

"""

214

Initialize interface container.

215

216

Args:

217

name: Interface name

218

abi: Contract ABI

219

"""

220

221

def __call__(self, address: str, owner: Account = None) -> Contract:

222

"""Create contract instance at address."""

223

224

def at(self, address: str, owner: Account = None) -> Contract:

225

"""

226

Connect to contract at address using this interface.

227

228

Args:

229

address: Contract address

230

owner: Account for transactions

231

232

Returns:

233

Contract: Contract instance with interface ABI

234

"""

235

```

236

237

### Contract Methods

238

239

Contract methods are accessed dynamically and return callable objects that handle both read operations and transactions.

240

241

```python { .api }

242

class ContractCall:

243

"""

244

Callable for contract view/pure methods (read-only operations).

245

246

These methods don't modify blockchain state and don't require gas.

247

"""

248

249

def __call__(self, *args, block_identifier: Union[int, str] = 'latest') -> Any:

250

"""

251

Call contract method.

252

253

Args:

254

*args: Method arguments

255

block_identifier: Block number or 'latest'/'pending'

256

257

Returns:

258

Any: Method return value

259

"""

260

261

def call(self, tx_params: dict = None, block_identifier: Union[int, str] = 'latest') -> Any:

262

"""Call method with custom transaction parameters."""

263

264

def estimate_gas(self, *args) -> int:

265

"""Estimate gas if method were called as transaction."""

266

267

class ContractTx:

268

"""

269

Callable for contract state-changing methods (transactions).

270

271

These methods modify blockchain state and require gas.

272

"""

273

274

def __call__(self, *args, **kwargs) -> TransactionReceipt:

275

"""

276

Execute contract method as transaction.

277

278

Args:

279

*args: Method arguments

280

**kwargs: Transaction parameters (from, gas_limit, etc.)

281

282

Returns:

283

TransactionReceipt: Transaction receipt

284

"""

285

286

def call(self, *args, tx_params: dict = None, block_identifier: Union[int, str] = 'latest') -> Any:

287

"""Call method without sending transaction (simulation)."""

288

289

def estimate_gas(self, *args, tx_params: dict = None) -> int:

290

"""

291

Estimate gas for method execution.

292

293

Args:

294

*args: Method arguments

295

tx_params: Transaction parameters

296

297

Returns:

298

int: Estimated gas amount

299

"""

300

301

def transact(self, *args, **kwargs) -> TransactionReceipt:

302

"""Execute method as transaction (alias for __call__)."""

303

```

304

305

### Event Handling

306

307

```python { .api }

308

class EventDict(dict):

309

"""

310

Dictionary-like container for contract events with additional filtering methods.

311

"""

312

313

def get_sequence(self) -> list:

314

"""Get events in chronological order."""

315

316

def count(self) -> int:

317

"""Get total number of events."""

318

319

class Log:

320

"""

321

Individual event log with decoded data.

322

323

Attributes:

324

address (str): Contract address that emitted the event

325

topics (list): Event topics (including signature)

326

data (str): Raw event data

327

block_number (int): Block number

328

transaction_hash (str): Transaction hash

329

log_index (int): Log index within transaction

330

event (str): Event name

331

args (dict): Decoded event arguments

332

"""

333

334

def __init__(self, log_dict: dict, abi: dict):

335

"""Initialize log with raw data and ABI."""

336

```

337

338

## Usage Examples

339

340

### Contract Deployment

341

342

```python

343

from brownie import accounts, project

344

345

# Load project and account

346

p = project.load()

347

account = accounts[0]

348

349

# Deploy contract with constructor arguments

350

contract = p.MyContract.deploy(

351

"constructor_string",

352

42,

353

["array", "values"],

354

{'from': account, 'gas_limit': 3000000}

355

)

356

357

print(f"Contract deployed at: {contract.address}")

358

print(f"Transaction hash: {contract.tx.txid}")

359

```

360

361

### Contract Method Calls

362

363

```python

364

# Call view/pure methods (no gas required)

365

result = contract.myViewMethod(arg1, arg2)

366

print(f"Method returned: {result}")

367

368

# Call at specific block

369

historical_result = contract.myViewMethod(arg1, block_identifier=1000000)

370

371

# Execute state-changing methods (requires gas)

372

tx = contract.myStateMethod(

373

arg1,

374

arg2,

375

{'from': account, 'gas_limit': 200000}

376

)

377

378

print(f"Transaction hash: {tx.txid}")

379

print(f"Gas used: {tx.gas_used}")

380

print(f"Events emitted: {tx.events}")

381

```

382

383

### Interacting with Existing Contracts

384

385

```python

386

# Connect to deployed contract by address

387

existing_contract = p.MyContract.at("0x742d35Cc6634C0532925a3b8D8D944d0Cdbc-1234")

388

389

# Use interface for contracts deployed elsewhere

390

interface_contract = p.interface.IERC20.at("0xA0b86a33E6442496c5D58f95EF3cE-5678")

391

392

# Call methods on existing contract

393

balance = interface_contract.balanceOf(account.address)

394

```

395

396

### Event Filtering and Analysis

397

398

```python

399

# Get all events from transaction

400

tx = contract.myMethod({'from': account})

401

all_events = tx.events

402

403

# Access specific event type

404

my_events = tx.events['MyEvent']

405

print(f"Number of MyEvent events: {len(my_events)}")

406

407

# Iterate through events

408

for event in my_events:

409

print(f"Event args: {event.args}")

410

print(f"Block number: {event.block_number}")

411

412

# Filter events from multiple transactions

413

transfer_filter = contract.events.Transfer.createFilter(

414

fromBlock=1000000,

415

argument_filters={'from': account.address}

416

)

417

transfers = transfer_filter.get_all_entries()

418

```

419

420

### Error Handling and Debugging

421

422

```python

423

from brownie import reverts

424

425

# Handle expected reverts

426

with reverts("Insufficient balance"):

427

contract.withdraw(1000000, {'from': account})

428

429

# Allow reverted transactions for analysis

430

tx = contract.riskyMethod({'from': account, 'allow_revert': True})

431

432

if tx.status == 0:

433

print(f"Transaction reverted: {tx.revert_msg}")

434

tx.traceback() # Detailed error trace

435

tx.call_trace() # Step-by-step execution trace

436

437

# Simulate transaction before sending

438

try:

439

result = contract.myMethod.call(arg1, {'from': account})

440

print(f"Method would return: {result}")

441

except ValueError as e:

442

print(f"Method would revert: {e}")

443

```

444

445

### Gas Estimation and Optimization

446

447

```python

448

# Estimate gas for deployment

449

estimated_gas = p.MyContract.estimate_gas("constructor_arg", 42)

450

print(f"Deployment will use ~{estimated_gas} gas")

451

452

# Estimate gas for method call

453

method_gas = contract.myMethod.estimate_gas(arg1, {'from': account})

454

print(f"Method call will use ~{method_gas} gas")

455

456

# Use gas strategies for automatic optimization

457

from brownie.network.gas import LinearScalingStrategy

458

459

gas_strategy = LinearScalingStrategy("20 gwei", "50 gwei", 1.1)

460

tx = contract.myMethod(arg1, {'from': account, 'gas_strategy': gas_strategy})

461

```

462

463

## Advanced Features

464

465

### Multicall Operations

466

467

```python

468

from brownie import multicall

469

470

# Batch multiple contract calls

471

with multicall:

472

balance1 = token.balanceOf(account1)

473

balance2 = token.balanceOf(account2)

474

total_supply = token.totalSupply()

475

476

# All calls executed in single transaction

477

print(f"Balance 1: {balance1}")

478

print(f"Balance 2: {balance2}")

479

print(f"Total supply: {total_supply}")

480

```

481

482

### Contract Verification

483

484

```python

485

# Publish contract source to block explorer

486

verification_url = contract.publish_source()

487

print(f"Contract verified at: {verification_url}")

488

489

# Get verification info

490

verification_info = contract.get_verification_info()

491

print(f"Compiler version: {verification_info['compiler_version']}")

492

```

493

494

## Type Definitions

495

496

```python { .api }

497

# Type aliases for contract operations

498

ContractType = Union[Contract, ProjectContract]

499

AbiType = List[Dict[str, Any]]

500

EventFilter = Dict[str, Any]

501

CallResult = Any

502

TxReceipt = TransactionReceipt

503

```