moonworm/centipede/cli.py.template

150 wiersze
4.8 KiB
Plaintext

# Code generated by moonstream centipede : https://github.com/bugout-dev/centipede
# Centipede version : {centipede_version}
import argparse
import json
from typing import Any, Callable, Dict, List, Optional, Tuple
import os
from eth_typing.evm import Address, ChecksumAddress
import web3
from web3 import Web3
from web3.contract import Contract
from .web3_util import *
abi_path = os.path.join(os.path.dirname(__file__), "{abi_file_name}")
with open(abi_path, "r") as abi_file:
CONTRACT_ABI = json.load(abi_file)
CONTRACT_FUNCTIONS = {{}}
for abi_item in CONTRACT_ABI:
if abi_item["type"] == "function":
CONTRACT_FUNCTIONS[abi_item["name"]] = abi_item
if abi_item["type"] == "constructor":
CONTRACT_FUNCTIONS["constructor"] = abi_item
def init_web3(ipc_path: str) -> Web3:
return Web3(web3.HTTPProvider(ipc_path))
def init_contract(web3: Web3, abi: Dict[str, Any], address: Optional[str]) -> Contract:
checksum_address: Optional[ChecksumAddress] = None
if address is not None:
checksum_address = web3.toChecksumAddress(address)
return web3.eth.contract(address=checksum_address, abi=abi)
def make_function_call(contract: Contract, function_name: str, *args):
return contract.functions[function_name](*args).call()
def populate_subparser_with_common_args(
leaf_parser: argparse.ArgumentParser,
) -> None:
leaf_parser.add_argument(
"-w",
"--web3",
required=True,
help=f"Web3 IPC connection",
)
leaf_parser.add_argument(
"-c",
"--contract_address",
required=True,
help=f"contract_address",
)
def populate_deploy_subparser(
leaf_parser: argparse.ArgumentParser,
) -> None:
leaf_parser.add_argument(
"-w",
"--web3",
required=True,
help=f"Web3 IPC connection",
)
leaf_parser.add_argument(
"-b",
"--bytecode-path",
required=True,
help=f"Path to contract bytecode",
)
{cli_content}
def get_address_and_private_key():
try:
address, pk = read_keys_from_env()
except Exception as e:
print(f"{{str(e)}}, Reading from cli")
address, pk = read_keys_from_cli()
return address, pk
def handle_args(args: argparse.Namespace):
# Initializng contract
web3 = init_web3(args.web3)
kwargs = vars(args)
if args.subcommand == "call":
contract_address = web3.toChecksumAddress(args.contract_address)
contract = web3.eth.contract(address=contract_address, abi=CONTRACT_ABI)
function_name = kwargs["function_name"]
del kwargs["function_name"]
call_args = [
cast_to_python_type(f_arg["type"])(kwargs[f_arg["name"]])
for f_arg in CONTRACT_FUNCTIONS[function_name]["inputs"]
]
print(make_function_call(contract, function_name, *call_args))
if args.subcommand == "transact":
contract_address = web3.toChecksumAddress(args.contract_address)
contract = web3.eth.contract(address=contract_address, abi=CONTRACT_ABI)
function_name = kwargs["function_name"]
del kwargs["function_name"]
call_args = [
cast_to_python_type(f_arg["type"])(kwargs[f_arg["name"]])
for f_arg in CONTRACT_FUNCTIONS[function_name]["inputs"]
]
address, pk = get_address_and_private_key()
transaction = build_transaction(
web3, contract.functions[function_name](*call_args), address
)
print(f"Transaction:\n{{transaction}}")
answer = input("Sign and submit transaction? (y/Y for yes)")
if answer == "Y" or answer == "y":
transaction_hash = submit_transaction(web3, transaction, pk)
print("Transaction is submitted, waiting for transaction receipt...")
tx_receipt = wait_for_transaction_receipt(web3, transaction_hash)
print(f"Got receipt:\n{{tx_receipt}}")
if args.subcommand == "deploy":
with open(args.bytecode_path, "r") as ifp:
bytecode = ifp.read()
address, pk = get_address_and_private_key()
constructor_args = [
cast_to_python_type(f_arg["type"])(kwargs[f_arg["name"]])
for f_arg in CONTRACT_FUNCTIONS["constructor"]["inputs"]
]
print("Deploying contract")
tx_hash, contract_address = deploy_contract(
web3,
bytecode,
CONTRACT_ABI,
deployer=address,
deployer_private_key=pk,
constructor_arguments=constructor_args,
)
print(f"Tx hash of deployment: {{web3.toHex(tx_hash)}}")
print(f"Address of deployed_contract: {{contract_address}}")
def main() -> None:
parser = generate_argument_parser()
args = parser.parse_args()
handle_args(args)
if __name__ == "__main__":
main()