kopia lustrzana https://github.com/bugout-dev/dao
moonworm-generated Python interface for diamond contracts
rodzic
e1038671f0
commit
db1437bafb
|
@ -131,3 +131,4 @@ dmypy.json
|
|||
# Custom
|
||||
.dao/
|
||||
.secrets/
|
||||
.vscode/
|
||||
|
|
|
@ -0,0 +1,176 @@
|
|||
# Code generated by moonworm : https://github.com/bugout-dev/moonworm
|
||||
# Moonworm version : 0.1.6
|
||||
|
||||
import argparse
|
||||
import json
|
||||
import os
|
||||
from pathlib import Path
|
||||
from typing import Any, Dict, List, Optional, Union
|
||||
|
||||
from brownie import Contract, network, project
|
||||
from brownie.network.contract import ContractContainer
|
||||
from eth_typing.evm import ChecksumAddress
|
||||
|
||||
|
||||
PROJECT_DIRECTORY = os.path.abspath(os.path.join(os.path.dirname(__file__), ".."))
|
||||
BUILD_DIRECTORY = os.path.join(PROJECT_DIRECTORY, "build", "contracts")
|
||||
|
||||
|
||||
def boolean_argument_type(raw_value: str) -> bool:
|
||||
TRUE_VALUES = ["1", "t", "y", "true", "yes"]
|
||||
FALSE_VALUES = ["0", "f", "n", "false", "no"]
|
||||
|
||||
if raw_value.lower() in TRUE_VALUES:
|
||||
return True
|
||||
elif raw_value.lower() in FALSE_VALUES:
|
||||
return False
|
||||
|
||||
raise ValueError(
|
||||
f"Invalid boolean argument: {raw_value}. Value must be one of: {','.join(TRUE_VALUES + FALSE_VALUES)}"
|
||||
)
|
||||
|
||||
|
||||
def bytes_argument_type(raw_value: str) -> bytes:
|
||||
return raw_value.encode()
|
||||
|
||||
|
||||
def get_abi_json(abi_name: str) -> List[Dict[str, Any]]:
|
||||
abi_full_path = os.path.join(BUILD_DIRECTORY, f"{abi_name}.json")
|
||||
if not os.path.isfile(abi_full_path):
|
||||
raise IOError(
|
||||
f"File does not exist: {abi_full_path}. Maybe you have to compile the smart contracts?"
|
||||
)
|
||||
|
||||
with open(abi_full_path, "r") as ifp:
|
||||
build = json.load(ifp)
|
||||
|
||||
abi_json = build.get("abi")
|
||||
if abi_json is None:
|
||||
raise ValueError(f"Could not find ABI definition in: {abi_full_path}")
|
||||
|
||||
return abi_json
|
||||
|
||||
|
||||
def contract_from_build(abi_name: str) -> ContractContainer:
|
||||
# This is workaround because brownie currently doesn't support loading the same project multiple
|
||||
# times. This causes problems when using multiple contracts from the same project in the same
|
||||
# python project.
|
||||
PROJECT = project.main.Project("moonworm", Path(PROJECT_DIRECTORY))
|
||||
|
||||
abi_full_path = os.path.join(BUILD_DIRECTORY, f"{abi_name}.json")
|
||||
if not os.path.isfile(abi_full_path):
|
||||
raise IOError(
|
||||
f"File does not exist: {abi_full_path}. Maybe you have to compile the smart contracts?"
|
||||
)
|
||||
|
||||
with open(abi_full_path, "r") as ifp:
|
||||
build = json.load(ifp)
|
||||
|
||||
return ContractContainer(PROJECT, build)
|
||||
|
||||
|
||||
class Diamond:
|
||||
def __init__(self, contract_address: Optional[ChecksumAddress]):
|
||||
self.contract_name = "Diamond"
|
||||
self.address = contract_address
|
||||
self.contract = None
|
||||
self.abi = get_abi_json("Diamond")
|
||||
if self.address is not None:
|
||||
self.contract: Optional[Contract] = Contract.from_abi(
|
||||
self.contract_name, self.address, self.abi
|
||||
)
|
||||
|
||||
def deploy(
|
||||
self,
|
||||
_contract_owner: ChecksumAddress,
|
||||
_diamond_cut_facet: ChecksumAddress,
|
||||
transaction_config,
|
||||
):
|
||||
contract_class = contract_from_build(self.contract_name)
|
||||
deployed_contract = contract_class.deploy(
|
||||
_contract_owner, _diamond_cut_facet, transaction_config
|
||||
)
|
||||
self.address = deployed_contract.address
|
||||
self.contract = deployed_contract
|
||||
|
||||
def assert_contract_is_instantiated(self) -> None:
|
||||
if self.contract is None:
|
||||
raise Exception("contract has not been instantiated")
|
||||
|
||||
|
||||
def get_transaction_config(args: argparse.Namespace) -> Dict[str, Any]:
|
||||
signer = network.accounts.load(args.sender, args.password)
|
||||
transaction_config: Dict[str, Any] = {"from": signer}
|
||||
if args.gas_price is not None:
|
||||
transaction_config["gas_price"] = args.gas_price
|
||||
if args.confirmations is not None:
|
||||
transaction_config["required_confs"] = args.confirmations
|
||||
return transaction_config
|
||||
|
||||
|
||||
def add_default_arguments(parser: argparse.ArgumentParser, transact: bool) -> None:
|
||||
parser.add_argument(
|
||||
"--network", required=True, help="Name of brownie network to connect to"
|
||||
)
|
||||
parser.add_argument(
|
||||
"--address", required=False, help="Address of deployed contract to connect to"
|
||||
)
|
||||
if not transact:
|
||||
return
|
||||
parser.add_argument(
|
||||
"--sender", required=True, help="Path to keystore file for transaction sender"
|
||||
)
|
||||
parser.add_argument(
|
||||
"--password",
|
||||
required=False,
|
||||
help="Password to keystore file (if you do not provide it, you will be prompted for it)",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--gas-price", default=None, help="Gas price at which to submit transaction"
|
||||
)
|
||||
parser.add_argument(
|
||||
"--confirmations",
|
||||
type=int,
|
||||
default=None,
|
||||
help="Number of confirmations to await before considering a transaction completed",
|
||||
)
|
||||
|
||||
|
||||
def handle_deploy(args: argparse.Namespace) -> None:
|
||||
network.connect(args.network)
|
||||
transaction_config = get_transaction_config(args)
|
||||
contract = Diamond(None)
|
||||
result = contract.deploy(
|
||||
_contract_owner=args.contract_owner_arg,
|
||||
_diamond_cut_facet=args.diamond_cut_facet_arg,
|
||||
transaction_config=transaction_config,
|
||||
)
|
||||
print(result)
|
||||
|
||||
|
||||
def generate_cli() -> argparse.ArgumentParser:
|
||||
parser = argparse.ArgumentParser(description="CLI for Diamond")
|
||||
parser.set_defaults(func=lambda _: parser.print_help())
|
||||
subcommands = parser.add_subparsers()
|
||||
|
||||
deploy_parser = subcommands.add_parser("deploy")
|
||||
add_default_arguments(deploy_parser, True)
|
||||
deploy_parser.add_argument(
|
||||
"--contract-owner-arg", required=True, help="Type: address"
|
||||
)
|
||||
deploy_parser.add_argument(
|
||||
"--diamond-cut-facet-arg", required=True, help="Type: address"
|
||||
)
|
||||
deploy_parser.set_defaults(func=handle_deploy)
|
||||
|
||||
return parser
|
||||
|
||||
|
||||
def main() -> None:
|
||||
parser = generate_cli()
|
||||
args = parser.parse_args()
|
||||
args.func(args)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
|
@ -0,0 +1,195 @@
|
|||
# Code generated by moonworm : https://github.com/bugout-dev/moonworm
|
||||
# Moonworm version : 0.1.6
|
||||
|
||||
import argparse
|
||||
import json
|
||||
import os
|
||||
from pathlib import Path
|
||||
from typing import Any, Dict, List, Optional, Union
|
||||
|
||||
from brownie import Contract, network, project
|
||||
from brownie.network.contract import ContractContainer
|
||||
from eth_typing.evm import ChecksumAddress
|
||||
|
||||
|
||||
PROJECT_DIRECTORY = os.path.abspath(os.path.join(os.path.dirname(__file__), ".."))
|
||||
BUILD_DIRECTORY = os.path.join(PROJECT_DIRECTORY, "build", "contracts")
|
||||
|
||||
|
||||
def boolean_argument_type(raw_value: str) -> bool:
|
||||
TRUE_VALUES = ["1", "t", "y", "true", "yes"]
|
||||
FALSE_VALUES = ["0", "f", "n", "false", "no"]
|
||||
|
||||
if raw_value.lower() in TRUE_VALUES:
|
||||
return True
|
||||
elif raw_value.lower() in FALSE_VALUES:
|
||||
return False
|
||||
|
||||
raise ValueError(
|
||||
f"Invalid boolean argument: {raw_value}. Value must be one of: {','.join(TRUE_VALUES + FALSE_VALUES)}"
|
||||
)
|
||||
|
||||
|
||||
def bytes_argument_type(raw_value: str) -> bytes:
|
||||
return raw_value.encode()
|
||||
|
||||
|
||||
def get_abi_json(abi_name: str) -> List[Dict[str, Any]]:
|
||||
abi_full_path = os.path.join(BUILD_DIRECTORY, f"{abi_name}.json")
|
||||
if not os.path.isfile(abi_full_path):
|
||||
raise IOError(
|
||||
f"File does not exist: {abi_full_path}. Maybe you have to compile the smart contracts?"
|
||||
)
|
||||
|
||||
with open(abi_full_path, "r") as ifp:
|
||||
build = json.load(ifp)
|
||||
|
||||
abi_json = build.get("abi")
|
||||
if abi_json is None:
|
||||
raise ValueError(f"Could not find ABI definition in: {abi_full_path}")
|
||||
|
||||
return abi_json
|
||||
|
||||
|
||||
def contract_from_build(abi_name: str) -> ContractContainer:
|
||||
# This is workaround because brownie currently doesn't support loading the same project multiple
|
||||
# times. This causes problems when using multiple contracts from the same project in the same
|
||||
# python project.
|
||||
PROJECT = project.main.Project("moonworm", Path(PROJECT_DIRECTORY))
|
||||
|
||||
abi_full_path = os.path.join(BUILD_DIRECTORY, f"{abi_name}.json")
|
||||
if not os.path.isfile(abi_full_path):
|
||||
raise IOError(
|
||||
f"File does not exist: {abi_full_path}. Maybe you have to compile the smart contracts?"
|
||||
)
|
||||
|
||||
with open(abi_full_path, "r") as ifp:
|
||||
build = json.load(ifp)
|
||||
|
||||
return ContractContainer(PROJECT, build)
|
||||
|
||||
|
||||
class DiamondCutFacet:
|
||||
def __init__(self, contract_address: Optional[ChecksumAddress]):
|
||||
self.contract_name = "DiamondCutFacet"
|
||||
self.address = contract_address
|
||||
self.contract = None
|
||||
self.abi = get_abi_json("DiamondCutFacet")
|
||||
if self.address is not None:
|
||||
self.contract: Optional[Contract] = Contract.from_abi(
|
||||
self.contract_name, self.address, self.abi
|
||||
)
|
||||
|
||||
def deploy(self, transaction_config):
|
||||
contract_class = contract_from_build(self.contract_name)
|
||||
deployed_contract = contract_class.deploy(transaction_config)
|
||||
self.address = deployed_contract.address
|
||||
self.contract = deployed_contract
|
||||
|
||||
def assert_contract_is_instantiated(self) -> None:
|
||||
if self.contract is None:
|
||||
raise Exception("contract has not been instantiated")
|
||||
|
||||
def diamond_cut(
|
||||
self,
|
||||
_diamond_cut: List,
|
||||
_init: ChecksumAddress,
|
||||
_calldata: bytes,
|
||||
transaction_config,
|
||||
) -> Any:
|
||||
self.assert_contract_is_instantiated()
|
||||
return self.contract.diamondCut(
|
||||
_diamond_cut, _init, _calldata, transaction_config
|
||||
)
|
||||
|
||||
|
||||
def get_transaction_config(args: argparse.Namespace) -> Dict[str, Any]:
|
||||
signer = network.accounts.load(args.sender, args.password)
|
||||
transaction_config: Dict[str, Any] = {"from": signer}
|
||||
if args.gas_price is not None:
|
||||
transaction_config["gas_price"] = args.gas_price
|
||||
if args.confirmations is not None:
|
||||
transaction_config["required_confs"] = args.confirmations
|
||||
return transaction_config
|
||||
|
||||
|
||||
def add_default_arguments(parser: argparse.ArgumentParser, transact: bool) -> None:
|
||||
parser.add_argument(
|
||||
"--network", required=True, help="Name of brownie network to connect to"
|
||||
)
|
||||
parser.add_argument(
|
||||
"--address", required=False, help="Address of deployed contract to connect to"
|
||||
)
|
||||
if not transact:
|
||||
return
|
||||
parser.add_argument(
|
||||
"--sender", required=True, help="Path to keystore file for transaction sender"
|
||||
)
|
||||
parser.add_argument(
|
||||
"--password",
|
||||
required=False,
|
||||
help="Password to keystore file (if you do not provide it, you will be prompted for it)",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--gas-price", default=None, help="Gas price at which to submit transaction"
|
||||
)
|
||||
parser.add_argument(
|
||||
"--confirmations",
|
||||
type=int,
|
||||
default=None,
|
||||
help="Number of confirmations to await before considering a transaction completed",
|
||||
)
|
||||
|
||||
|
||||
def handle_deploy(args: argparse.Namespace) -> None:
|
||||
network.connect(args.network)
|
||||
transaction_config = get_transaction_config(args)
|
||||
contract = DiamondCutFacet(None)
|
||||
result = contract.deploy(transaction_config=transaction_config)
|
||||
print(result)
|
||||
|
||||
|
||||
def handle_diamond_cut(args: argparse.Namespace) -> None:
|
||||
network.connect(args.network)
|
||||
contract = DiamondCutFacet(args.address)
|
||||
transaction_config = get_transaction_config(args)
|
||||
result = contract.diamond_cut(
|
||||
_diamond_cut=args.diamond_cut_arg,
|
||||
_init=args.init_arg,
|
||||
_calldata=args.calldata_arg,
|
||||
transaction_config=transaction_config,
|
||||
)
|
||||
print(result)
|
||||
|
||||
|
||||
def generate_cli() -> argparse.ArgumentParser:
|
||||
parser = argparse.ArgumentParser(description="CLI for DiamondCutFacet")
|
||||
parser.set_defaults(func=lambda _: parser.print_help())
|
||||
subcommands = parser.add_subparsers()
|
||||
|
||||
deploy_parser = subcommands.add_parser("deploy")
|
||||
add_default_arguments(deploy_parser, True)
|
||||
deploy_parser.set_defaults(func=handle_deploy)
|
||||
|
||||
diamond_cut_parser = subcommands.add_parser("diamond-cut")
|
||||
add_default_arguments(diamond_cut_parser, True)
|
||||
diamond_cut_parser.add_argument(
|
||||
"--diamond-cut-arg", required=True, help="Type: tuple[]", nargs="+"
|
||||
)
|
||||
diamond_cut_parser.add_argument("--init-arg", required=True, help="Type: address")
|
||||
diamond_cut_parser.add_argument(
|
||||
"--calldata-arg", required=True, help="Type: bytes", type=bytes_argument_type
|
||||
)
|
||||
diamond_cut_parser.set_defaults(func=handle_diamond_cut)
|
||||
|
||||
return parser
|
||||
|
||||
|
||||
def main() -> None:
|
||||
parser = generate_cli()
|
||||
args = parser.parse_args()
|
||||
args.func(args)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
|
@ -0,0 +1,175 @@
|
|||
# Code generated by moonworm : https://github.com/bugout-dev/moonworm
|
||||
# Moonworm version : 0.1.6
|
||||
|
||||
import argparse
|
||||
import json
|
||||
import os
|
||||
from pathlib import Path
|
||||
from typing import Any, Dict, List, Optional, Union
|
||||
|
||||
from brownie import Contract, network, project
|
||||
from brownie.network.contract import ContractContainer
|
||||
from eth_typing.evm import ChecksumAddress
|
||||
|
||||
|
||||
PROJECT_DIRECTORY = os.path.abspath(os.path.join(os.path.dirname(__file__), ".."))
|
||||
BUILD_DIRECTORY = os.path.join(PROJECT_DIRECTORY, "build", "contracts")
|
||||
|
||||
|
||||
def boolean_argument_type(raw_value: str) -> bool:
|
||||
TRUE_VALUES = ["1", "t", "y", "true", "yes"]
|
||||
FALSE_VALUES = ["0", "f", "n", "false", "no"]
|
||||
|
||||
if raw_value.lower() in TRUE_VALUES:
|
||||
return True
|
||||
elif raw_value.lower() in FALSE_VALUES:
|
||||
return False
|
||||
|
||||
raise ValueError(
|
||||
f"Invalid boolean argument: {raw_value}. Value must be one of: {','.join(TRUE_VALUES + FALSE_VALUES)}"
|
||||
)
|
||||
|
||||
|
||||
def bytes_argument_type(raw_value: str) -> bytes:
|
||||
return raw_value.encode()
|
||||
|
||||
|
||||
def get_abi_json(abi_name: str) -> List[Dict[str, Any]]:
|
||||
abi_full_path = os.path.join(BUILD_DIRECTORY, f"{abi_name}.json")
|
||||
if not os.path.isfile(abi_full_path):
|
||||
raise IOError(
|
||||
f"File does not exist: {abi_full_path}. Maybe you have to compile the smart contracts?"
|
||||
)
|
||||
|
||||
with open(abi_full_path, "r") as ifp:
|
||||
build = json.load(ifp)
|
||||
|
||||
abi_json = build.get("abi")
|
||||
if abi_json is None:
|
||||
raise ValueError(f"Could not find ABI definition in: {abi_full_path}")
|
||||
|
||||
return abi_json
|
||||
|
||||
|
||||
def contract_from_build(abi_name: str) -> ContractContainer:
|
||||
# This is workaround because brownie currently doesn't support loading the same project multiple
|
||||
# times. This causes problems when using multiple contracts from the same project in the same
|
||||
# python project.
|
||||
PROJECT = project.main.Project("moonworm", Path(PROJECT_DIRECTORY))
|
||||
|
||||
abi_full_path = os.path.join(BUILD_DIRECTORY, f"{abi_name}.json")
|
||||
if not os.path.isfile(abi_full_path):
|
||||
raise IOError(
|
||||
f"File does not exist: {abi_full_path}. Maybe you have to compile the smart contracts?"
|
||||
)
|
||||
|
||||
with open(abi_full_path, "r") as ifp:
|
||||
build = json.load(ifp)
|
||||
|
||||
return ContractContainer(PROJECT, build)
|
||||
|
||||
|
||||
class DiamondInit:
|
||||
def __init__(self, contract_address: Optional[ChecksumAddress]):
|
||||
self.contract_name = "DiamondInit"
|
||||
self.address = contract_address
|
||||
self.contract = None
|
||||
self.abi = get_abi_json("DiamondInit")
|
||||
if self.address is not None:
|
||||
self.contract: Optional[Contract] = Contract.from_abi(
|
||||
self.contract_name, self.address, self.abi
|
||||
)
|
||||
|
||||
def deploy(self, transaction_config):
|
||||
contract_class = contract_from_build(self.contract_name)
|
||||
deployed_contract = contract_class.deploy(transaction_config)
|
||||
self.address = deployed_contract.address
|
||||
self.contract = deployed_contract
|
||||
|
||||
def assert_contract_is_instantiated(self) -> None:
|
||||
if self.contract is None:
|
||||
raise Exception("contract has not been instantiated")
|
||||
|
||||
def init(self, transaction_config) -> Any:
|
||||
self.assert_contract_is_instantiated()
|
||||
return self.contract.init(transaction_config)
|
||||
|
||||
|
||||
def get_transaction_config(args: argparse.Namespace) -> Dict[str, Any]:
|
||||
signer = network.accounts.load(args.sender, args.password)
|
||||
transaction_config: Dict[str, Any] = {"from": signer}
|
||||
if args.gas_price is not None:
|
||||
transaction_config["gas_price"] = args.gas_price
|
||||
if args.confirmations is not None:
|
||||
transaction_config["required_confs"] = args.confirmations
|
||||
return transaction_config
|
||||
|
||||
|
||||
def add_default_arguments(parser: argparse.ArgumentParser, transact: bool) -> None:
|
||||
parser.add_argument(
|
||||
"--network", required=True, help="Name of brownie network to connect to"
|
||||
)
|
||||
parser.add_argument(
|
||||
"--address", required=False, help="Address of deployed contract to connect to"
|
||||
)
|
||||
if not transact:
|
||||
return
|
||||
parser.add_argument(
|
||||
"--sender", required=True, help="Path to keystore file for transaction sender"
|
||||
)
|
||||
parser.add_argument(
|
||||
"--password",
|
||||
required=False,
|
||||
help="Password to keystore file (if you do not provide it, you will be prompted for it)",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--gas-price", default=None, help="Gas price at which to submit transaction"
|
||||
)
|
||||
parser.add_argument(
|
||||
"--confirmations",
|
||||
type=int,
|
||||
default=None,
|
||||
help="Number of confirmations to await before considering a transaction completed",
|
||||
)
|
||||
|
||||
|
||||
def handle_deploy(args: argparse.Namespace) -> None:
|
||||
network.connect(args.network)
|
||||
transaction_config = get_transaction_config(args)
|
||||
contract = DiamondInit(None)
|
||||
result = contract.deploy(transaction_config=transaction_config)
|
||||
print(result)
|
||||
|
||||
|
||||
def handle_init(args: argparse.Namespace) -> None:
|
||||
network.connect(args.network)
|
||||
contract = DiamondInit(args.address)
|
||||
transaction_config = get_transaction_config(args)
|
||||
result = contract.init(transaction_config=transaction_config)
|
||||
print(result)
|
||||
|
||||
|
||||
def generate_cli() -> argparse.ArgumentParser:
|
||||
parser = argparse.ArgumentParser(description="CLI for DiamondInit")
|
||||
parser.set_defaults(func=lambda _: parser.print_help())
|
||||
subcommands = parser.add_subparsers()
|
||||
|
||||
deploy_parser = subcommands.add_parser("deploy")
|
||||
add_default_arguments(deploy_parser, True)
|
||||
deploy_parser.set_defaults(func=handle_deploy)
|
||||
|
||||
init_parser = subcommands.add_parser("init")
|
||||
add_default_arguments(init_parser, True)
|
||||
init_parser.set_defaults(func=handle_init)
|
||||
|
||||
return parser
|
||||
|
||||
|
||||
def main() -> None:
|
||||
parser = generate_cli()
|
||||
args = parser.parse_args()
|
||||
args.func(args)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
|
@ -0,0 +1,249 @@
|
|||
# Code generated by moonworm : https://github.com/bugout-dev/moonworm
|
||||
# Moonworm version : 0.1.6
|
||||
|
||||
import argparse
|
||||
import json
|
||||
import os
|
||||
from pathlib import Path
|
||||
from typing import Any, Dict, List, Optional, Union
|
||||
|
||||
from brownie import Contract, network, project
|
||||
from brownie.network.contract import ContractContainer
|
||||
from eth_typing.evm import ChecksumAddress
|
||||
|
||||
|
||||
PROJECT_DIRECTORY = os.path.abspath(os.path.join(os.path.dirname(__file__), ".."))
|
||||
BUILD_DIRECTORY = os.path.join(PROJECT_DIRECTORY, "build", "contracts")
|
||||
|
||||
|
||||
def boolean_argument_type(raw_value: str) -> bool:
|
||||
TRUE_VALUES = ["1", "t", "y", "true", "yes"]
|
||||
FALSE_VALUES = ["0", "f", "n", "false", "no"]
|
||||
|
||||
if raw_value.lower() in TRUE_VALUES:
|
||||
return True
|
||||
elif raw_value.lower() in FALSE_VALUES:
|
||||
return False
|
||||
|
||||
raise ValueError(
|
||||
f"Invalid boolean argument: {raw_value}. Value must be one of: {','.join(TRUE_VALUES + FALSE_VALUES)}"
|
||||
)
|
||||
|
||||
|
||||
def bytes_argument_type(raw_value: str) -> bytes:
|
||||
return raw_value.encode()
|
||||
|
||||
|
||||
def get_abi_json(abi_name: str) -> List[Dict[str, Any]]:
|
||||
abi_full_path = os.path.join(BUILD_DIRECTORY, f"{abi_name}.json")
|
||||
if not os.path.isfile(abi_full_path):
|
||||
raise IOError(
|
||||
f"File does not exist: {abi_full_path}. Maybe you have to compile the smart contracts?"
|
||||
)
|
||||
|
||||
with open(abi_full_path, "r") as ifp:
|
||||
build = json.load(ifp)
|
||||
|
||||
abi_json = build.get("abi")
|
||||
if abi_json is None:
|
||||
raise ValueError(f"Could not find ABI definition in: {abi_full_path}")
|
||||
|
||||
return abi_json
|
||||
|
||||
|
||||
def contract_from_build(abi_name: str) -> ContractContainer:
|
||||
# This is workaround because brownie currently doesn't support loading the same project multiple
|
||||
# times. This causes problems when using multiple contracts from the same project in the same
|
||||
# python project.
|
||||
PROJECT = project.main.Project("moonworm", Path(PROJECT_DIRECTORY))
|
||||
|
||||
abi_full_path = os.path.join(BUILD_DIRECTORY, f"{abi_name}.json")
|
||||
if not os.path.isfile(abi_full_path):
|
||||
raise IOError(
|
||||
f"File does not exist: {abi_full_path}. Maybe you have to compile the smart contracts?"
|
||||
)
|
||||
|
||||
with open(abi_full_path, "r") as ifp:
|
||||
build = json.load(ifp)
|
||||
|
||||
return ContractContainer(PROJECT, build)
|
||||
|
||||
|
||||
class DiamondLoupeFacet:
|
||||
def __init__(self, contract_address: Optional[ChecksumAddress]):
|
||||
self.contract_name = "DiamondLoupeFacet"
|
||||
self.address = contract_address
|
||||
self.contract = None
|
||||
self.abi = get_abi_json("DiamondLoupeFacet")
|
||||
if self.address is not None:
|
||||
self.contract: Optional[Contract] = Contract.from_abi(
|
||||
self.contract_name, self.address, self.abi
|
||||
)
|
||||
|
||||
def deploy(self, transaction_config):
|
||||
contract_class = contract_from_build(self.contract_name)
|
||||
deployed_contract = contract_class.deploy(transaction_config)
|
||||
self.address = deployed_contract.address
|
||||
self.contract = deployed_contract
|
||||
|
||||
def assert_contract_is_instantiated(self) -> None:
|
||||
if self.contract is None:
|
||||
raise Exception("contract has not been instantiated")
|
||||
|
||||
def facet_address(self, _function_selector: bytes) -> Any:
|
||||
self.assert_contract_is_instantiated()
|
||||
return self.contract.facetAddress.call(_function_selector)
|
||||
|
||||
def facet_addresses(self) -> Any:
|
||||
self.assert_contract_is_instantiated()
|
||||
return self.contract.facetAddresses.call()
|
||||
|
||||
def facet_function_selectors(self, _facet: ChecksumAddress) -> Any:
|
||||
self.assert_contract_is_instantiated()
|
||||
return self.contract.facetFunctionSelectors.call(_facet)
|
||||
|
||||
def facets(self) -> Any:
|
||||
self.assert_contract_is_instantiated()
|
||||
return self.contract.facets.call()
|
||||
|
||||
def supports_interface(self, _interface_id: bytes) -> Any:
|
||||
self.assert_contract_is_instantiated()
|
||||
return self.contract.supportsInterface.call(_interface_id)
|
||||
|
||||
|
||||
def get_transaction_config(args: argparse.Namespace) -> Dict[str, Any]:
|
||||
signer = network.accounts.load(args.sender, args.password)
|
||||
transaction_config: Dict[str, Any] = {"from": signer}
|
||||
if args.gas_price is not None:
|
||||
transaction_config["gas_price"] = args.gas_price
|
||||
if args.confirmations is not None:
|
||||
transaction_config["required_confs"] = args.confirmations
|
||||
return transaction_config
|
||||
|
||||
|
||||
def add_default_arguments(parser: argparse.ArgumentParser, transact: bool) -> None:
|
||||
parser.add_argument(
|
||||
"--network", required=True, help="Name of brownie network to connect to"
|
||||
)
|
||||
parser.add_argument(
|
||||
"--address", required=False, help="Address of deployed contract to connect to"
|
||||
)
|
||||
if not transact:
|
||||
return
|
||||
parser.add_argument(
|
||||
"--sender", required=True, help="Path to keystore file for transaction sender"
|
||||
)
|
||||
parser.add_argument(
|
||||
"--password",
|
||||
required=False,
|
||||
help="Password to keystore file (if you do not provide it, you will be prompted for it)",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--gas-price", default=None, help="Gas price at which to submit transaction"
|
||||
)
|
||||
parser.add_argument(
|
||||
"--confirmations",
|
||||
type=int,
|
||||
default=None,
|
||||
help="Number of confirmations to await before considering a transaction completed",
|
||||
)
|
||||
|
||||
|
||||
def handle_deploy(args: argparse.Namespace) -> None:
|
||||
network.connect(args.network)
|
||||
transaction_config = get_transaction_config(args)
|
||||
contract = DiamondLoupeFacet(None)
|
||||
result = contract.deploy(transaction_config=transaction_config)
|
||||
print(result)
|
||||
|
||||
|
||||
def handle_facet_address(args: argparse.Namespace) -> None:
|
||||
network.connect(args.network)
|
||||
contract = DiamondLoupeFacet(args.address)
|
||||
result = contract.facet_address(_function_selector=args.function_selector_arg)
|
||||
print(result)
|
||||
|
||||
|
||||
def handle_facet_addresses(args: argparse.Namespace) -> None:
|
||||
network.connect(args.network)
|
||||
contract = DiamondLoupeFacet(args.address)
|
||||
result = contract.facet_addresses()
|
||||
print(result)
|
||||
|
||||
|
||||
def handle_facet_function_selectors(args: argparse.Namespace) -> None:
|
||||
network.connect(args.network)
|
||||
contract = DiamondLoupeFacet(args.address)
|
||||
result = contract.facet_function_selectors(_facet=args.facet_arg)
|
||||
print(result)
|
||||
|
||||
|
||||
def handle_facets(args: argparse.Namespace) -> None:
|
||||
network.connect(args.network)
|
||||
contract = DiamondLoupeFacet(args.address)
|
||||
result = contract.facets()
|
||||
print(result)
|
||||
|
||||
|
||||
def handle_supports_interface(args: argparse.Namespace) -> None:
|
||||
network.connect(args.network)
|
||||
contract = DiamondLoupeFacet(args.address)
|
||||
result = contract.supports_interface(_interface_id=args.interface_id_arg)
|
||||
print(result)
|
||||
|
||||
|
||||
def generate_cli() -> argparse.ArgumentParser:
|
||||
parser = argparse.ArgumentParser(description="CLI for DiamondLoupeFacet")
|
||||
parser.set_defaults(func=lambda _: parser.print_help())
|
||||
subcommands = parser.add_subparsers()
|
||||
|
||||
deploy_parser = subcommands.add_parser("deploy")
|
||||
add_default_arguments(deploy_parser, True)
|
||||
deploy_parser.set_defaults(func=handle_deploy)
|
||||
|
||||
facet_address_parser = subcommands.add_parser("facet-address")
|
||||
add_default_arguments(facet_address_parser, False)
|
||||
facet_address_parser.add_argument(
|
||||
"--function-selector-arg",
|
||||
required=True,
|
||||
help="Type: bytes4",
|
||||
type=bytes_argument_type,
|
||||
)
|
||||
facet_address_parser.set_defaults(func=handle_facet_address)
|
||||
|
||||
facet_addresses_parser = subcommands.add_parser("facet-addresses")
|
||||
add_default_arguments(facet_addresses_parser, False)
|
||||
facet_addresses_parser.set_defaults(func=handle_facet_addresses)
|
||||
|
||||
facet_function_selectors_parser = subcommands.add_parser("facet-function-selectors")
|
||||
add_default_arguments(facet_function_selectors_parser, False)
|
||||
facet_function_selectors_parser.add_argument(
|
||||
"--facet-arg", required=True, help="Type: address"
|
||||
)
|
||||
facet_function_selectors_parser.set_defaults(func=handle_facet_function_selectors)
|
||||
|
||||
facets_parser = subcommands.add_parser("facets")
|
||||
add_default_arguments(facets_parser, False)
|
||||
facets_parser.set_defaults(func=handle_facets)
|
||||
|
||||
supports_interface_parser = subcommands.add_parser("supports-interface")
|
||||
add_default_arguments(supports_interface_parser, False)
|
||||
supports_interface_parser.add_argument(
|
||||
"--interface-id-arg",
|
||||
required=True,
|
||||
help="Type: bytes4",
|
||||
type=bytes_argument_type,
|
||||
)
|
||||
supports_interface_parser.set_defaults(func=handle_supports_interface)
|
||||
|
||||
return parser
|
||||
|
||||
|
||||
def main() -> None:
|
||||
parser = generate_cli()
|
||||
args = parser.parse_args()
|
||||
args.func(args)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
|
@ -0,0 +1,197 @@
|
|||
# Code generated by moonworm : https://github.com/bugout-dev/moonworm
|
||||
# Moonworm version : 0.1.6
|
||||
|
||||
import argparse
|
||||
import json
|
||||
import os
|
||||
from pathlib import Path
|
||||
from typing import Any, Dict, List, Optional, Union
|
||||
|
||||
from brownie import Contract, network, project
|
||||
from brownie.network.contract import ContractContainer
|
||||
from eth_typing.evm import ChecksumAddress
|
||||
|
||||
|
||||
PROJECT_DIRECTORY = os.path.abspath(os.path.join(os.path.dirname(__file__), ".."))
|
||||
BUILD_DIRECTORY = os.path.join(PROJECT_DIRECTORY, "build", "contracts")
|
||||
|
||||
|
||||
def boolean_argument_type(raw_value: str) -> bool:
|
||||
TRUE_VALUES = ["1", "t", "y", "true", "yes"]
|
||||
FALSE_VALUES = ["0", "f", "n", "false", "no"]
|
||||
|
||||
if raw_value.lower() in TRUE_VALUES:
|
||||
return True
|
||||
elif raw_value.lower() in FALSE_VALUES:
|
||||
return False
|
||||
|
||||
raise ValueError(
|
||||
f"Invalid boolean argument: {raw_value}. Value must be one of: {','.join(TRUE_VALUES + FALSE_VALUES)}"
|
||||
)
|
||||
|
||||
|
||||
def bytes_argument_type(raw_value: str) -> bytes:
|
||||
return raw_value.encode()
|
||||
|
||||
|
||||
def get_abi_json(abi_name: str) -> List[Dict[str, Any]]:
|
||||
abi_full_path = os.path.join(BUILD_DIRECTORY, f"{abi_name}.json")
|
||||
if not os.path.isfile(abi_full_path):
|
||||
raise IOError(
|
||||
f"File does not exist: {abi_full_path}. Maybe you have to compile the smart contracts?"
|
||||
)
|
||||
|
||||
with open(abi_full_path, "r") as ifp:
|
||||
build = json.load(ifp)
|
||||
|
||||
abi_json = build.get("abi")
|
||||
if abi_json is None:
|
||||
raise ValueError(f"Could not find ABI definition in: {abi_full_path}")
|
||||
|
||||
return abi_json
|
||||
|
||||
|
||||
def contract_from_build(abi_name: str) -> ContractContainer:
|
||||
# This is workaround because brownie currently doesn't support loading the same project multiple
|
||||
# times. This causes problems when using multiple contracts from the same project in the same
|
||||
# python project.
|
||||
PROJECT = project.main.Project("moonworm", Path(PROJECT_DIRECTORY))
|
||||
|
||||
abi_full_path = os.path.join(BUILD_DIRECTORY, f"{abi_name}.json")
|
||||
if not os.path.isfile(abi_full_path):
|
||||
raise IOError(
|
||||
f"File does not exist: {abi_full_path}. Maybe you have to compile the smart contracts?"
|
||||
)
|
||||
|
||||
with open(abi_full_path, "r") as ifp:
|
||||
build = json.load(ifp)
|
||||
|
||||
return ContractContainer(PROJECT, build)
|
||||
|
||||
|
||||
class OwnershipFacet:
|
||||
def __init__(self, contract_address: Optional[ChecksumAddress]):
|
||||
self.contract_name = "OwnershipFacet"
|
||||
self.address = contract_address
|
||||
self.contract = None
|
||||
self.abi = get_abi_json("OwnershipFacet")
|
||||
if self.address is not None:
|
||||
self.contract: Optional[Contract] = Contract.from_abi(
|
||||
self.contract_name, self.address, self.abi
|
||||
)
|
||||
|
||||
def deploy(self, transaction_config):
|
||||
contract_class = contract_from_build(self.contract_name)
|
||||
deployed_contract = contract_class.deploy(transaction_config)
|
||||
self.address = deployed_contract.address
|
||||
self.contract = deployed_contract
|
||||
|
||||
def assert_contract_is_instantiated(self) -> None:
|
||||
if self.contract is None:
|
||||
raise Exception("contract has not been instantiated")
|
||||
|
||||
def owner(self) -> Any:
|
||||
self.assert_contract_is_instantiated()
|
||||
return self.contract.owner.call()
|
||||
|
||||
def transfer_ownership(
|
||||
self, _new_owner: ChecksumAddress, transaction_config
|
||||
) -> Any:
|
||||
self.assert_contract_is_instantiated()
|
||||
return self.contract.transferOwnership(_new_owner, transaction_config)
|
||||
|
||||
|
||||
def get_transaction_config(args: argparse.Namespace) -> Dict[str, Any]:
|
||||
signer = network.accounts.load(args.sender, args.password)
|
||||
transaction_config: Dict[str, Any] = {"from": signer}
|
||||
if args.gas_price is not None:
|
||||
transaction_config["gas_price"] = args.gas_price
|
||||
if args.confirmations is not None:
|
||||
transaction_config["required_confs"] = args.confirmations
|
||||
return transaction_config
|
||||
|
||||
|
||||
def add_default_arguments(parser: argparse.ArgumentParser, transact: bool) -> None:
|
||||
parser.add_argument(
|
||||
"--network", required=True, help="Name of brownie network to connect to"
|
||||
)
|
||||
parser.add_argument(
|
||||
"--address", required=False, help="Address of deployed contract to connect to"
|
||||
)
|
||||
if not transact:
|
||||
return
|
||||
parser.add_argument(
|
||||
"--sender", required=True, help="Path to keystore file for transaction sender"
|
||||
)
|
||||
parser.add_argument(
|
||||
"--password",
|
||||
required=False,
|
||||
help="Password to keystore file (if you do not provide it, you will be prompted for it)",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--gas-price", default=None, help="Gas price at which to submit transaction"
|
||||
)
|
||||
parser.add_argument(
|
||||
"--confirmations",
|
||||
type=int,
|
||||
default=None,
|
||||
help="Number of confirmations to await before considering a transaction completed",
|
||||
)
|
||||
|
||||
|
||||
def handle_deploy(args: argparse.Namespace) -> None:
|
||||
network.connect(args.network)
|
||||
transaction_config = get_transaction_config(args)
|
||||
contract = OwnershipFacet(None)
|
||||
result = contract.deploy(transaction_config=transaction_config)
|
||||
print(result)
|
||||
|
||||
|
||||
def handle_owner(args: argparse.Namespace) -> None:
|
||||
network.connect(args.network)
|
||||
contract = OwnershipFacet(args.address)
|
||||
result = contract.owner()
|
||||
print(result)
|
||||
|
||||
|
||||
def handle_transfer_ownership(args: argparse.Namespace) -> None:
|
||||
network.connect(args.network)
|
||||
contract = OwnershipFacet(args.address)
|
||||
transaction_config = get_transaction_config(args)
|
||||
result = contract.transfer_ownership(
|
||||
_new_owner=args.new_owner_arg, transaction_config=transaction_config
|
||||
)
|
||||
print(result)
|
||||
|
||||
|
||||
def generate_cli() -> argparse.ArgumentParser:
|
||||
parser = argparse.ArgumentParser(description="CLI for OwnershipFacet")
|
||||
parser.set_defaults(func=lambda _: parser.print_help())
|
||||
subcommands = parser.add_subparsers()
|
||||
|
||||
deploy_parser = subcommands.add_parser("deploy")
|
||||
add_default_arguments(deploy_parser, True)
|
||||
deploy_parser.set_defaults(func=handle_deploy)
|
||||
|
||||
owner_parser = subcommands.add_parser("owner")
|
||||
add_default_arguments(owner_parser, False)
|
||||
owner_parser.set_defaults(func=handle_owner)
|
||||
|
||||
transfer_ownership_parser = subcommands.add_parser("transfer-ownership")
|
||||
add_default_arguments(transfer_ownership_parser, True)
|
||||
transfer_ownership_parser.add_argument(
|
||||
"--new-owner-arg", required=True, help="Type: address"
|
||||
)
|
||||
transfer_ownership_parser.set_defaults(func=handle_transfer_ownership)
|
||||
|
||||
return parser
|
||||
|
||||
|
||||
def main() -> None:
|
||||
parser = generate_cli()
|
||||
args = parser.parse_args()
|
||||
args.func(args)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
Ładowanie…
Reference in New Issue