0
# Project Management
1
2
Brownie project creation, contract compilation, script execution, and build artifact management with support for both Solidity and Vyper smart contracts.
3
4
## Capabilities
5
6
### Project Creation and Loading
7
8
Functions for creating new brownie projects and loading existing ones with proper configuration and dependency management.
9
10
```python { .api }
11
def new(path: str = ".", name: str = None, ignore_existing: bool = False) -> Project:
12
"""
13
Create a new brownie project.
14
15
Args:
16
path: Directory path for the new project
17
name: Project name (derived from path if None)
18
ignore_existing: Don't raise error if directory exists
19
20
Returns:
21
Project: Newly created project instance
22
23
Raises:
24
FileExistsError: If directory exists and ignore_existing is False
25
"""
26
27
def load(project_path: str = ".", name: str = None) -> Project:
28
"""
29
Load an existing brownie project.
30
31
Args:
32
project_path: Path to project directory
33
name: Project name override
34
35
Returns:
36
Project: Loaded project instance
37
38
Raises:
39
ProjectNotFound: If project directory doesn't contain brownie project
40
"""
41
42
def from_brownie_mix(path: str, project_name: str = None, ignore_existing: bool = False) -> Project:
43
"""
44
Create project from brownie-mix template.
45
46
Args:
47
path: Brownie-mix repository path or name
48
project_name: Name for the new project
49
ignore_existing: Don't raise error if directory exists
50
51
Returns:
52
Project: Project created from template
53
"""
54
55
def check_for_project(path: str = ".") -> bool:
56
"""
57
Check if directory contains a brownie project.
58
59
Args:
60
path: Directory path to check
61
62
Returns:
63
bool: True if directory contains brownie project
64
"""
65
66
def get_loaded_projects() -> list:
67
"""
68
Get list of currently loaded projects.
69
70
Returns:
71
list: List of loaded Project instances
72
"""
73
```
74
75
### Source Compilation
76
77
Functions for compiling smart contract source code with support for multiple Solidity and Vyper versions.
78
79
```python { .api }
80
def compile_source(
81
source: str,
82
solc_version: str = None,
83
vyper_version: str = None,
84
**kwargs
85
) -> TempProject:
86
"""
87
Compile contract source code without a project.
88
89
Args:
90
source: Contract source code
91
solc_version: Solidity compiler version
92
vyper_version: Vyper compiler version
93
**kwargs: Additional compiler options
94
95
Returns:
96
TempProject: Temporary project with compiled contracts
97
98
Raises:
99
CompilerError: If compilation fails
100
IncompatibleSolcVersion: If Solidity version unsupported
101
IncompatibleVyperVersion: If Vyper version unsupported
102
"""
103
104
def run(script_path: str, method_name: str = None, *args, **kwargs):
105
"""
106
Run a project script.
107
108
Args:
109
script_path: Path to script file
110
method_name: Specific method to run (main if None)
111
*args: Arguments to pass to script
112
**kwargs: Keyword arguments to pass to script
113
114
Returns:
115
Any: Return value from script execution
116
"""
117
```
118
119
### Project Class
120
121
The main Project class manages project lifecycle, compilation, and artifact handling.
122
123
```python { .api }
124
class Project:
125
"""
126
Main project class for managing brownie projects.
127
128
Attributes:
129
_name (str): Project name
130
_path (Path): Project directory path
131
_active (bool): Whether project is currently active
132
_compiler_config (dict): Compiler configuration
133
_network_config (dict): Network configuration
134
"""
135
136
def __init__(self, name: str, project_path: Path):
137
"""
138
Initialize project instance.
139
140
Args:
141
name: Project name
142
project_path: Path to project directory
143
"""
144
145
def load_config(self) -> None:
146
"""Load project configuration from brownie-config.yaml."""
147
148
def compile(self, **kwargs) -> None:
149
"""
150
Compile all project contracts.
151
152
Args:
153
**kwargs: Compiler options
154
- contracts: List of specific contracts to compile
155
- optimizer: Optimizer settings
156
- solc_version: Solidity version override
157
- vyper_version: Vyper version override
158
"""
159
160
def close(self, raises: bool = True) -> None:
161
"""
162
Close project and clean up resources.
163
164
Args:
165
raises: Raise exception if project not active
166
"""
167
168
def __getattr__(self, name: str):
169
"""Access contract containers by name."""
170
171
def __getitem__(self, name: str):
172
"""Access contract containers by name (dict-style)."""
173
174
def __iter__(self):
175
"""Iterate over contract containers."""
176
177
def __contains__(self, name: str) -> bool:
178
"""Check if contract exists in project."""
179
180
def __len__(self) -> int:
181
"""Get number of contract containers."""
182
183
def dict(self) -> dict:
184
"""Get dictionary of contract containers."""
185
186
def keys(self) -> list:
187
"""Get list of contract names."""
188
189
def interface(self):
190
"""Access to interface containers."""
191
```
192
193
### Temporary Project
194
195
Temporary projects handle ad-hoc source compilation without full project structure.
196
197
```python { .api }
198
class TempProject:
199
"""
200
Temporary project for compiling source code without full project structure.
201
202
Used by compile_source() function for one-off compilation tasks.
203
"""
204
205
def __init__(self, name: str, contracts: dict):
206
"""
207
Initialize temporary project.
208
209
Args:
210
name: Temporary project name
211
contracts: Compiled contract data
212
"""
213
214
def __getattr__(self, name: str):
215
"""Access contract containers by name."""
216
217
def __getitem__(self, name: str):
218
"""Access contract containers by name (dict-style)."""
219
220
def close(self) -> None:
221
"""Clean up temporary project resources."""
222
```
223
224
### Build Artifacts Management
225
226
The Build class manages compilation artifacts, metadata, and dependency tracking.
227
228
```python { .api }
229
class Build:
230
"""
231
Build artifacts manager for handling compilation results and metadata.
232
233
Attributes:
234
_path (Path): Build directory path
235
_contracts (dict): Contract build artifacts
236
_interfaces (dict): Interface definitions
237
"""
238
239
def __init__(self, project_path: Path):
240
"""
241
Initialize build manager.
242
243
Args:
244
project_path: Project directory path
245
"""
246
247
def get(self, name: str) -> dict:
248
"""
249
Get build artifact for contract.
250
251
Args:
252
name: Contract name
253
254
Returns:
255
dict: Build artifact data
256
"""
257
258
def contains(self, name: str) -> bool:
259
"""
260
Check if build contains contract.
261
262
Args:
263
name: Contract name
264
265
Returns:
266
bool: True if contract exists in build
267
"""
268
269
def _compile(self, contracts: dict, compiler_data: dict, silent: bool = False) -> None:
270
"""
271
Compile contracts and store artifacts.
272
273
Args:
274
contracts: Contract source data
275
compiler_data: Compiler configuration
276
silent: Suppress compilation output
277
"""
278
279
def _generate_dependency_map(self) -> dict:
280
"""Generate dependency mapping for contracts."""
281
282
def _get_contract_dependencies(self, name: str) -> list:
283
"""
284
Get dependencies for specific contract.
285
286
Args:
287
name: Contract name
288
289
Returns:
290
list: List of dependency contract names
291
"""
292
```
293
294
### Source File Management
295
296
The Sources class manages project source files and change tracking for incremental compilation.
297
298
```python { .api }
299
class Sources:
300
"""
301
Source file manager with change tracking for incremental compilation.
302
303
Attributes:
304
_contracts (dict): Contract source files
305
_interfaces (dict): Interface source files
306
_libraries (dict): Library source files
307
"""
308
309
def __init__(self, project_path: Path):
310
"""
311
Initialize source manager.
312
313
Args:
314
project_path: Project directory path
315
"""
316
317
def get_contract_list(self) -> list:
318
"""
319
Get list of contract source files.
320
321
Returns:
322
list: Contract file paths
323
"""
324
325
def get_interface_list(self) -> list:
326
"""
327
Get list of interface source files.
328
329
Returns:
330
list: Interface file paths
331
"""
332
333
def get_interface_sources(self) -> dict:
334
"""
335
Get interface source code.
336
337
Returns:
338
dict: Interface name to source mapping
339
"""
340
341
def get_source_path(self, contract_name: str) -> Path:
342
"""
343
Get source file path for contract.
344
345
Args:
346
contract_name: Contract name
347
348
Returns:
349
Path: Source file path
350
"""
351
352
def get_contract_names(self) -> list:
353
"""
354
Get list of contract names.
355
356
Returns:
357
list: Contract names
358
"""
359
360
def check_for_changed_files(self, build_artifacts: dict) -> bool:
361
"""
362
Check if source files have changed since last compilation.
363
364
Args:
365
build_artifacts: Previous build artifacts
366
367
Returns:
368
bool: True if files have changed
369
"""
370
```
371
372
### Contract Source Flattening
373
374
The Flattener class provides contract source flattening for verification and deployment.
375
376
```python { .api }
377
class Flattener:
378
"""
379
Contract source flattening utility for verification and deployment.
380
"""
381
382
def __init__(self, contract_name: str, project_path: Path):
383
"""
384
Initialize flattener for specific contract.
385
386
Args:
387
contract_name: Contract to flatten
388
project_path: Project directory path
389
"""
390
391
def flatten(self, output_path: str = None) -> str:
392
"""
393
Flatten contract source and all dependencies.
394
395
Args:
396
output_path: Output file path (return string if None)
397
398
Returns:
399
str: Flattened source code
400
"""
401
```
402
403
## Usage Examples
404
405
### Project Creation
406
407
```python
408
from brownie import project
409
410
# Create new project
411
new_project = project.new('./my-defi-project', name='MyDefiProject')
412
print(f"Created project: {new_project._name}")
413
414
# Create from brownie-mix template
415
token_project = project.from_brownie_mix('token')
416
417
# Load existing project
418
existing_project = project.load('./existing-project')
419
print(f"Loaded project with {len(existing_project)} contracts")
420
```
421
422
### Contract Compilation
423
424
```python
425
from brownie import project
426
427
# Load and compile project
428
p = project.load()
429
p.compile()
430
431
# Compile specific contracts
432
p.compile(contracts=['Token', 'Exchange'])
433
434
# Compile with optimizer
435
p.compile(optimizer={'enabled': True, 'runs': 200})
436
437
# Compile ad-hoc source
438
source_code = '''
439
pragma solidity ^0.8.0;
440
contract SimpleStorage {
441
uint256 public data;
442
function setData(uint256 _data) public { data = _data; }
443
}
444
'''
445
446
temp_project = project.compile_source(source_code)
447
contract = temp_project.SimpleStorage.deploy({'from': accounts[0]})
448
```
449
450
### Project Structure and Contracts
451
452
```python
453
from brownie import project, accounts
454
455
# Load project
456
p = project.load()
457
458
# Check available contracts
459
print(f"Available contracts: {list(p.keys())}")
460
print(f"Total contracts: {len(p)}")
461
462
# Check if contract exists
463
if 'Token' in p:
464
print("Token contract available")
465
466
# Access contract containers
467
token_container = p.Token
468
exchange_container = p['Exchange']
469
470
# Deploy contracts
471
account = accounts[0]
472
token = p.Token.deploy("MyToken", "MTK", 18, 1000000, {'from': account})
473
exchange = p.Exchange.deploy(token.address, {'from': account})
474
475
# Access deployed contracts
476
deployed_tokens = list(p.Token)
477
print(f"Deployed {len(deployed_tokens)} token contracts")
478
```
479
480
### Script Execution
481
482
```python
483
from brownie import project
484
485
# Run main script
486
project.run('scripts/deploy.py')
487
488
# Run specific function
489
project.run('scripts/deploy.py', 'deploy_token', 'MyToken', 'MTK')
490
491
# Run with arguments
492
project.run('scripts/manage.py', 'transfer_tokens',
493
recipient='0x742d35Cc6634C0532925a3b8D8D944d0Cdbc1234',
494
amount=1000)
495
```
496
497
### Build Artifact Management
498
499
```python
500
from brownie import project
501
502
p = project.load()
503
504
# Access build information
505
build = p._build
506
token_artifact = build.get('Token')
507
508
print(f"Token ABI: {token_artifact['abi']}")
509
print(f"Token bytecode: {token_artifact['bytecode'][:100]}...")
510
511
# Check dependencies
512
if build.contains('Exchange'):
513
deps = build._get_contract_dependencies('Exchange')
514
print(f"Exchange dependencies: {deps}")
515
```
516
517
### Interface Management
518
519
```python
520
from brownie import project
521
522
p = project.load()
523
524
# Access interface containers
525
erc20_interface = p.interface.IERC20
526
527
# Connect to existing contract using interface
528
usdc_contract = erc20_interface.at('0xA0b86a33E6442496c5D58f95EF3CE-1234')
529
530
# Check balance using interface
531
balance = usdc_contract.balanceOf(accounts[0])
532
print(f"USDC balance: {balance}")
533
```
534
535
### Source File Analysis
536
537
```python
538
from brownie import project
539
540
p = project.load()
541
sources = p._sources
542
543
# Get contract information
544
contract_list = sources.get_contract_list()
545
print(f"Contract files: {contract_list}")
546
547
contract_names = sources.get_contract_names()
548
print(f"Contract names: {contract_names}")
549
550
# Get source path
551
token_path = sources.get_source_path('Token')
552
print(f"Token source: {token_path}")
553
554
# Check for changes
555
build_artifacts = p._build._contracts
556
has_changes = sources.check_for_changed_files(build_artifacts)
557
if has_changes:
558
print("Source files have changed, recompilation needed")
559
```
560
561
### Contract Flattening
562
563
```python
564
from brownie import project
565
566
p = project.load()
567
568
# Flatten contract for verification
569
flattener = project.Flattener('Token', p._path)
570
flattened_source = flattener.flatten()
571
572
# Save to file
573
flattener.flatten('./flattened/Token_flattened.sol')
574
print("Contract flattened and saved")
575
```
576
577
### Project Configuration
578
579
```python
580
from brownie import project
581
582
p = project.load()
583
584
# Load custom configuration
585
p.load_config()
586
587
# Access compiler configuration
588
compiler_config = p._compiler_config
589
print(f"Solc version: {compiler_config.get('solc', {}).get('version')}")
590
print(f"Optimizer enabled: {compiler_config.get('solc', {}).get('optimizer', {}).get('enabled')}")
591
592
# Access network configuration
593
network_config = p._network_config
594
print(f"Networks: {list(network_config.keys())}")
595
```
596
597
### Multi-Project Workflow
598
599
```python
600
from brownie import project
601
602
# Load multiple projects
603
token_project = project.load('./token-project')
604
exchange_project = project.load('./exchange-project')
605
606
# Check loaded projects
607
loaded_projects = project.get_loaded_projects()
608
print(f"Loaded {len(loaded_projects)} projects")
609
610
# Work with specific project
611
token = token_project.Token.deploy({'from': accounts[0]})
612
exchange = exchange_project.Exchange.deploy(token.address, {'from': accounts[0]})
613
614
# Close projects when done
615
token_project.close()
616
exchange_project.close()
617
```
618
619
### Development Workflow
620
621
```python
622
from brownie import project, network, accounts
623
624
# Setup development environment
625
network.connect('development')
626
p = project.load()
627
628
try:
629
# Compile contracts
630
p.compile()
631
632
# Deploy core contracts
633
account = accounts[0]
634
project.run('scripts/deploy_core.py')
635
636
# Run tests
637
project.run('scripts/run_tests.py')
638
639
# Deploy additional contracts
640
project.run('scripts/deploy_features.py')
641
642
print("Development workflow completed successfully")
643
644
except Exception as e:
645
print(f"Error in development workflow: {e}")
646
647
finally:
648
# Clean up
649
p.close()
650
network.disconnect()
651
```
652
653
## Type Definitions
654
655
```python { .api }
656
# Type aliases for project operations
657
ProjectType = Union[Project, TempProject]
658
ContractArtifact = Dict[str, Any]
659
CompilerConfig = Dict[str, Any]
660
BuildData = Dict[str, ContractArtifact]
661
SourceData = Dict[str, str]
662
DependencyMap = Dict[str, List[str]]
663
```