用brownie开发测试 solidity
新建一个brownie项目:
brownie init
新增文件:
requirements-dev.txt
PyYAML==5.4.1
ape-safe==0.2.1
click==8.1.3
eth-abi==2.1.1
eth-brownie==1.19.0
gnosis-py==3.9.5
hexbytes==0.2.2
pytest==6.2.5
python-dotenv==0.16.0
web3==5.29.1
pytest-dotenv==0.5.2
brownie-config.yaml
project_structure:build: buildcontracts: contractsinterfaces: interfacesreports: reportsscripts: scriptstests: testsnetworks:default: developmentdevelopment:gas_limit: maxgas_buffer: 1gas_price: 0max_fee: nullpriority_fee: nullreverting_tx_gas_limit: maxdefault_contract_owner: truecmd_settings: nullcobo-chain-dev:host: http://localhost:8545cobo-chain-sandbox:host: http://cobo_chain_evm.rpc.cobo.onelive:gas_limit: autogas_buffer: 1.1gas_price: automax_fee: nullpriority_fee: nullreverting_tx_gas_limit: falsedefault_contract_owner: falsecompiler:evm_version: istanbulsolc:version: 0.8.14optimizer:enabled: trueruns: 200remappings:- "@openzeppelin=OpenZeppelin/openzeppelin-contracts@4.7.2"vyper:version: nullconsole:show_colors: truecolor_style: monokaiauto_suggest: truecompletions: trueediting_mode: emacsreports:exclude_paths: nullexclude_contracts: nullonly_include_project: truehypothesis:deadline: nullmax_examples: 50report_multiple_bugs: Falsestateful_step_count: 10phases:explicit: truereuse: truegenerate: truetarget: trueshrink: trueautofetch_sources: false
dependencies: null
dev_deployment_artifacts: false
development:- name: Ganache-CLIid: developmentcmd: ganache-clihost: http://127.0.0.1timeout: 120cmd_settings:port: 8545gas_limit: 12000000accounts: 10evm_version: istanbul
命令行 test-chain 本地测试
brownie networks add Ethereum test-local host=http://localhost:8545 chainid=9000
在指定network 环境部署相关factory
brownie run scripts/deploy_factory.py --network test-local
在指定network 环境部署相关router,config等合约(这个命令会有上面的命令打印出来)
brownie run scripts/deploy_module.py deploy_module 0xbd1D2224e65e7Ce89Ea0F8237B4deE38CCBe13Cb 0x65c7225A5E29ef20B974197362b587985077cE95 --network test-chain-local
在指定network 环境 初始化 config 等相关数据(这个命令会有上面的命令打印出来)
brownie run scripts/init_config.py init_config 0x10F05a76659D230ab0E48071f4f3ff4E9daC639c boss_name boss_address --network test-local
在指定network 环境 查询相关配置(这个命令会有上面的命令打印出来)
brownie run scripts/init_config.py get_config 0xac19dAd5060cE759c663710744175c36806e5C08 boss_name --network test-local
其他:
deploy_module.py
import json
import argparse
from brownie.convert import to_bytesfrom brownie import (FlowConfigFactory,FlowConfig
)from .utils import get_account,get_network
from .base import router_bindconfig_module_name = to_bytes("config".encode('utf-8'), type_str="bytes32")def deploy_module(router_factory_address, config_factory_address):router_factory = FlowOrgRouterFactory.at(router_factory_address)config_factory = FlowConfigFactory.at(config_factory_address)accounts = get_account()router_owners = [accounts[9].address, accounts[8].address]rig_creator = accounts[1]router_bind_contract_func="bindModule(bytes32,address)"router_owner9=accounts[9]router_module = router_bind(router_factory, config_factory, router_owners, rig_creator, router_bind_contract_func, router_owner9, config_module_name)print("\n***next step init_config cmd:")print(f"brownie run scripts/init_config.py init_config router_address key value --network network, eg:")print(f"brownie run scripts/init_config.py init_config {router_module.address} boss_name boss_address --network {get_network()}")
deploy_factory.py
import jsonfrom brownie import (FlowConfigFactory,FlowConfig,
)from .utils import get_account,get_networkdef deploy_factory():accounts = get_account()print("<<<<<<<<<<<<<<")test_creator = accounts[0]print(f"test_creator {test_creator}")print("Deploying FlowOrgRouterFactory")router_factory = FlowOrgRouterFactory.deploy({"from": test_creator})print(f"FlowOrgRouterFactory deployed at {router_factory}")print("Deploying FlowConfigFactory")config_factory = FlowConfigFactory.deploy({"from": test_creator})print(f"FlowConfigFactory deployed at {config_factory}")print("\n\n***next step deploy_module cmd:")print(f"brownie run scripts/deploy_module.py deploy_module router_factory_address config_factory_address --network network, eg:")print(f"brownie run scripts/deploy_module.py deploy_module {router_factory} {config_factory} --network {get_network()}")return (router_factory, config_factory)def main():deploy_factory()
init_context.py
import json
import argparsefrom brownie.convert import to_bytesfrom brownie import (FlowContext
)from .utils import get_account,get_networkimport sys
sys.path.append("..")
from tests.utils import (contract_func_build
)config_module_name = to_bytes("config".encode('utf-8'), type_str="bytes32")set_config_contract_func="setConfig(bytes32,string)"def deploy_context():accounts = get_account()print("<<<<<<<<<<<<<<")test_creator = accounts[0]print(f"test_creator {test_creator}")print("Deploying FlowContext")context = FlowContext.deploy({"from": test_creator})print(f"FlowContext deployed at {context}")print("\n\n***next step generate_get_sender_address cmd:")print(f"brownie run scripts/init_context.py generate_get_sender_address context_address --network network, eg:")print(f"brownie run scripts/init_context.py generate_get_sender_address {context} --network {get_network()}")def generate_get_sender_address(context_address):data1 = contract_func_build("getSenderAddress()")#print(f"$expression=call(\\\"{config_address}\\\",\\\"{data1.hex()}\\\")")print(f"$expression=call('{context_address}','0x{data1.hex()}')")