Brownie智能合约框架
Brownie is a Python-based development and testing framework for smart contracts targeting the Ethereum Virtual Machine.
Brownie文档
安装Brownie:pip install eth-brownie
创建新项目
- 有两种方式可以初始化一个新项目
- 创建一个空项目:
brownie init
- 创建一个有模板的项目,如:
brownie bake react
- 创建一个空项目:
项目结构
-
初始化项目之后,文件夹会生成以下几个文件夹
文件夹 内容 contracts 智能合约源代码。每次运行Brownie,都会自动检查该文件夹中是否存在变动的文件,如果有,就会自动重新编译 interfaces 接口源代码 scripts 部署和交互脚本。脚本通过 brownie run
执行tests 测试脚本。脚本通过 brownie test
执行;使用的测试框架为Pytestbuild(不应修改或删除其中的内容) 项目数据,如编译产物和单元测试结果 reports(不应修改或删除其中的内容) 用于GUI的JSON报告
编译合约
当运行brownie compie
时,Brownie会自动检查contracts文件夹中是否存在文件发生变动,若没有文件发生变动,则不会进行该次编译,如果要强制进行编译,则可以使用:brownie compile --all
只要contracts文件夹中存在无法编译的文件,就无法运行brownie,如果希望将某个文件夹或者某个文件排除在编译之外,就在其名称前加_
-
Brownie支持Solidity(>=0.4.22)和Vyper(>=0.1.0-beta.16),文件的扩展名会决定使用哪种编译器
- Solidity: .sol
- Vyper: .vy
-
interfaces文件夹在以下两种情况特别有用:
- 使用Vyper时,接口不一定是可编译的源代码,因此不能包含在contracts文件夹中。
- 在同一个项目中使用Solidity和Vyper时,或使用Solidity的多个版本时,兼容性问题会阻止合约直接相互引用。
Interfaces文件夹支持Solidity(.sol)和Vyper(.vy).Vyper合约也可以直接导入JSON编码的ABI(.json)文件
可以在brownie-config.yaml文件中对编译进行相关设置,如果未设置或设置无法生效,Brownie会采用默认设置,有关编译的默认设置如下:
1 | compiler: |
修改编译设置后,会使得项目全部重新编译
如果没有在配置文件中设定编译器版本,Brownie会自动根据合约的version pragma来选择编译器版本
EVM Version:当使用>=0.5.13的Solidity或者使用Vyper时,Brownie会自动将EVM version设置为istanbul,当然,也可以手动在brownie-config.yaml文件中进行设置
Solidity编译器允许路径重新映射,Brownie通过配置文件中的compiler.solc.remappings字段进行设置,案例如下:
1 | compiler: |
Brownie不会检测项目文件夹以外的文件是否发生变动,如果被引用的文件在项目文件夹之外,那么当该文件发生变动时,需要手动重新编译
如果使用了如下映射:
1 | compiler: |
那么以下两种导包方式都将是同样的:
1 | import "@openzeppelin/contracts/math/SafeMath.sol"; |
可以在brownie console或者python代码中安装不同版本的编译器:
1 | from brownie.project.compiler import install_solc |
包管理器
可以通过以下命令调用包管理器:brownie pm
查看当前安装的包:brownie pm list
将包的内容复制到另一个文件夹中:brownie pm clone [package] [path]
,如果不指定路径,则会复制到当前目录,例如:brownie pm clone aragon/aragonOS@4.0.0
Brownie支持从ethPM和Github安装包
要从Github安装包,您必须使用包ID,包ID由组织名称、存储库和版本标签组成,包ID不区分大小写,类似这样:
[ORGANIZATION]/[REPOSITORY]@[VERSION]
如果要安装OpenZeppelin contracts的3.0.0版本:brownie pm install OpenZeppelin/openzeppelin-contracts@3.0.0
ethPM(以太坊包管理器):是一个去中心化的包管理器,用于分发EVM智能合约和项目。
要获得ethPM软件包,您必须知道软件包名称和可用的注册表地址。此信息通过注册表URI传递。注册表URI使用以下格式:
ethpm://[CONTRACT_ADDRESS]:[CHAIN_ID]/[PACKAGE_NAME]@[VERSION]
安装由SnakeCharmersZeppelin注册表提供的OpenZeppelin的Math包:
brownie pm install ethpm://zeppelin.snakecharmers.eth:1/math@1.0.0
导入已经安装的包,例如从OpenZeppelin contracts导入SafeMath:import "OpenZeppelin/openzeppelin-contracts@3.0.0/contracts/math/SafeMath.sol";
可以在配置文件中先声明依赖,Brownie会在编译项目之前尝试安装任何列出的依赖项,例如:
1 | dependencies: |
部署
部署完成后,Brownie将在build/deployment/文件夹中维护一个map.json文件,该文件列出了实时网络上所有已部署的合约,并按链和合约名称排序。每个合约的列表按部署的区块编号排序,最新的部署排在最前面
Brownie会保存有关实时网络上合约部署的信息。部署合约后,生成的ProjectContract实例在未来的Brownie会话中仍然可用
- 以下操作不会删除本地存储的部署数据:
- 断开并重新连接到同一网络
- 关闭并重新加载项目
- 退出并重新加载Brownie
- 修改合约的源代码 - Brownie仍然保留已部署版本的源代码
- 以下操作将删除项目中本地存储的部署数据:
- 调用
ContractContainer.remove
将删除已删除的ProjectContract实例的部署信息 - 删除或重命名项目中的合同源文件将导致Brownie删除已删除合同的所有部署信息
- 删除build/deployments/目录将删除有关已部署合约的所有信息
- 调用
Brownie为etherscan支持的所有网络上的solidity合约提供自动源代码验证功能。要在部署时验证合约,请添加publish_source=True
参数,如:Token.deploy("My Real Token", "RLT", 18, 1e28, {'from': acct}, publish_source=True)
交互
Brownie支持对已经部署的合约进行交互,交互手段分为控制台交互和脚本交互
1 | 进入控制台交互模式 |
网络
- Brownie可用于开发和实时环境
- 开发环境是用于测试和调试的本地临时网络。Brownie使用Ganache作为开发环境
- 实时环境是一个非本地的、持久的区块链。该术语用于指代以太坊主网和测试网
常用的网络命令:
1 | 获取帮助 |
如果要修改默认网络,可以在配置文件中修改,具体如下:
1 | networks: |
要与实时网络交互,必须连接到一个节点。可以运行自己的节点,也可以连接到托管节点。Alchemy和Infura提供了对以太坊节点的公共访问
Ganache允许您通过从实时网络分叉来创建开发网络
账户
常用的账户命令:
1 | 获取帮助 |
在代码中加载账户:
1 | # 加载brownie账户列表里的账户 |
配置文件
需要先在项目根目录创建brownie-config.yaml,然后就可以通过编辑该配置文件来修改Brownie的默认行为
要引用brownie-config.yaml中配置的参数,需要先导包,然后用索引的方式得到
1 | from brownie import config |
可以在配置文件中加载环境变量,如:
1 | wallets: |
测试
文件命名规则:test_xxx.py或者xxx_test.py
函数命名规则:test_xxx
测试分为三个步骤:Arrange,Act,Assert,一个测试函数可以进行两次assert
1 | 进行测试 |
1 | # 案例1 |