用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: build
contracts: contracts
interfaces: interfaces
reports: reports
scripts: scripts
tests: tests
networks:
default: development
development:
gas_limit: max
gas_buffer: 1
gas_price: 0
max_fee: null
priority_fee: null
reverting_tx_gas_limit: max
default_contract_owner: true
cmd_settings: null
test-chain-dev:
host: http://localhost:8545
live:
gas_limit: auto
gas_buffer: 1.1
gas_price: auto
max_fee: null
priority_fee: null
reverting_tx_gas_limit: false
default_contract_owner: false
compiler:
evm_version: istanbul
solc:
version: 0.8.14
optimizer:
enabled: true
runs: 200
remappings:
- "@openzeppelin=OpenZeppelin/openzeppelin-contracts@4.7.2"
vyper:
version: null
console:
show_colors: true
color_style: monokai
auto_suggest: true
completions: true
editing_mode: emacs
reports:
exclude_paths: null
exclude_contracts: null
only_include_project: true
hypothesis:
deadline: null
max_examples: 50
report_multiple_bugs: False
stateful_step_count: 10
phases:
explicit: true
reuse: true
generate: true
target: true
shrink: true
autofetch_sources: false
dependencies: null
dev_deployment_artifacts: false
development:
- name: Ganache-CLI
id: development
cmd: ganache-cli
host: http://127.0.0.1
timeout: 120
cmd_settings:
port: 8545
gas_limit: 12000000
accounts: 10
evm_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_bytes
from brownie import (
FlowConfigFactory,
FlowConfig
)
from .utils import get_account,get_network
from .base import router_bind
config_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 json
from brownie import (
FlowConfigFactory,
FlowConfig,
)
from .utils import get_account,get_network
def 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 argparse
from brownie.convert import to_bytes
from brownie import (
FlowContext
)
from .utils import get_account,get_network
import 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()}')")