moody.libeb API documentation

# Module `moody.libeb`

Expand source code

    import codecs
    import json
    import os
    import subprocess
    import time
    from threading import Lock
    from typing import List, Tuple, Optional

    # ========================== Of course
    from hexbytes import HexBytes
    from web3 import Web3, HTTPProvider
    from web3.contract import Contract as Web3Contract
    from web3.datastructures import AttributeDict
    from web3.exceptions import TransactionNotFound, ContractLogicError, InvalidAddress, TimeExhausted
    from web3.logs import DISCARD
    from web3.middleware import geth_poa_middleware
    from web3.types import BlockData

    # ========================== Of course
    from . import Bolors, Evm, DefaultKeys, root_base_path
    from .buildercompile.remotecompile import BuildRemoteLinuxCommand
    from .buildercompile.transpile import BuildLang
    from .conf import Config
    from .exceptions import FoundUndeployedLibraries
    from .paths import Paths

    def web3_provider(address: str) -> Web3:
        try:
            if address.startswith('http'):  # HTTP
                return Web3(Web3.HTTPProvider(address))
            if address.startswith('ws'):  # WebSocket
                return Web3(Web3.WebsocketProvider(address))
            return Web3(Web3.IPCProvider(address))
        except FileNotFoundError:
            raise ValueError("Failed to initialize web3 provider (is eth_node set?)") from None

    w3_lock = Lock()
    event_lock = Lock()
    statement = 'End : {}, IO File {}'

    def extract_tx_by_address(address, block: BlockData) -> list:
        # Note: block attribute dict has to be generated with full_transactions=True flag
        return [tx for tx in block.transactions if tx.to and address.lower() == tx.to.lower()]

    def event_log(tx_hash: str, events: List[str], provider: Web3, contract: Web3Contract) -> Tuple[str, Optional[AttributeDict]]:
        """
        Extracts logs of @event from tx_hash if present
        :param tx_hash:
        :param events: Case sensitive events name
        :param provider:
        :param contract: Web3 Contract
        :return: event name and log represented in 'AttributeDict' or 'None' if not found
        """
        try:
            receipt = provider.eth.getTransactionReceipt(tx_hash)
        except TransactionNotFound:
            time.sleep(3000)  # hard coded sleep for 3 seconds... maybe this will help?
            # retry
            try:
                receipt = provider.eth.getTransactionReceipt(tx_hash)
            except TransactionNotFound:
                return '', None

        for event in events:
            # we discard warning as we do best effort to find wanted event, not always there
            # as we listen to the entire contract tx, might
            log = getattr(contract.events, event)().processReceipt(receipt, DISCARD)
            if log:
                data_index = 0
                return event, log[data_index]
        # todo: fix this - seems like some weird return
        return '', None

    def normalize_address(address: str):
        """Converts address to address acceptable by web3"""
        return Web3.toChecksumAddress(address.lower())

    def Logd(anystr: any):
        print(anystr)

    def writeFile(content, filename):
        fo = open(filename, "w")
        fo.write(content)
        fo.close()
        print(statement.format(time.ctime(), filename))

    class HexJsonEncoder(json.JSONEncoder):
        def default(self, obj):
            if isinstance(obj, HexBytes):
                return obj.hex()
            return super().default(obj)

    def _parseValue(val):
        # check for nested dict structures to iterate through
        if 'dict' in str(type(val)).lower():
            return toDict(val)
        # convert 'HexBytes' type to 'str'
        elif 'HexBytes' in str(type(val)):
            return val.hex()
        else:
            return val

    def toDict(dictToParse):
        # convert any 'AttributeDict' type found to 'dict'
        parsedDict = dict(dictToParse)
        for key, val in parsedDict.items():
            if 'list' in str(type(val)):
                parsedDict[key] = [_parseValue(x) for x in val]
            else:
                parsedDict[key] = _parseValue(val)
        return parsedDict

    import re

    regex1 = r"\/\/*.*"

    class IDos:
        def hasContractName(self, name: str) -> bool:
            pass

        def getAddr(self, keyname: str) -> str:
            pass

        def isAddress(self, add: str) -> bool:
            pass

    class BinOp:
        """
        The binary operation for the ops. Taking care the operations for library linking and the related stuffs.
        """

        def __init__(self, bin_content: str, file_name: str):
            self.bin_raw = bin_content
            self.bin_knifed = bin_content
            self.bin_undeploy_lib = dict()
            self.file_name = file_name
            self.debug = False

        def setDebug(self, de: bool):
            self.debug = de

        def GetRawBin(self) -> str:
            return self.bin_raw

        def GetKnifedBin(self) -> str:
            return self.bin_knifed

        def checkBinForUndeployLib(self) -> bool:
            matches = re.finditer(regex1, self.bin_raw, re.MULTILINE)
            found = False
            for matchNum, match in enumerate(matches, start=1):
                print("Library {matchNum} is found at {start}-{end}: {match}".format(matchNum=matchNum, start=match.start(), end=match.end(), match=match.group()))
                k, v = self.fromLine(match.group())
                self.bin_undeploy_lib[k] = v
                found = True
            return found

        def fromLine(self, input_line: str) -> Tuple[str, str]:
            class_name = input_line.split(":")[1]
            return class_name, input_line

        def _placehd(self, instruction_line: str) -> str:
            return "__{}__".format(str(instruction_line).split("->")[0].strip(" //"))

        def anaylze(self, databank: IDos) -> bool:
            if len(self.bin_undeploy_lib) == 0:
                print("🚧 Nothing to process")
                return False

            for class_name, instruction_line in self.bin_undeploy_lib.items():
                if databank.hasContractName(class_name) is True:
                    print(f"💽 Found support Class {class_name} - deployment address")
                    if databank.isAddress(databank.getAddr(class_name)):
                        self._knifeBinClass(class_name, self._placehd(instruction_line), databank.getAddr(class_name))
                    else:
                        print("🧊 The found library address is not valid - {}, {}".format(class_name, databank.getAddr(class_name)))
                        raise FoundUndeployedLibraries
                else:
                    print("⚠️ Unfound library Error- {}, please make sure you have this library deployed.".format(class_name))
                    raise FoundUndeployedLibraries

            self.bin_knifed = self.bin_knifed.splitlines(True)[0]
            self.bin_knifed = self.bin_knifed.replace("\n", "")
            # self.bin_knifed = "0x" + self.bin_knifed
            if self.debug is True:
                print(f"After processed bin file - {self.file_name}.bin (should be done now)")
                print(self.bin_knifed)
                # print(self.bin_raw)
                print("File content end ##")
            else:
                print(f"After processed bin file - {self.file_name}.bin")

            return True

        def _knifeBinClass(self, c: str, k: str, address: str) -> None:
            # address_step_1 = address.lower()
            address_step_2 = address.replace("0x", "")
            self.bin_knifed = self.bin_knifed.replace(k, address_step_2)
            print(f"🍡 Linked successfully for Solidity Class {c} with {address}")

    class SolWeb3Tool(object):
        """
        This is the tool to build operation of the compiling solidity contract source code
        Try to make some improvement of code to make better access
        This is the artifact manager as we know it
        """
        OUTPUT_BUILD = "build"
        WORKSPACE_PATH = ""
        solfolder = ""
        file_name = "xxx.sol"
        prefixname = ""
        statement = 'End : {}, IO File {}'

        def __init__(self):
            self._abi = None
            self._bin = None
            self._meta = None
            self.combined_data = None
            self._key = None

        def setBuildNameSpace(self, path: str) -> "SolWeb3Tool":
            self.OUTPUT_BUILD = path
            return self

        def setBasePath(self, path: str) -> "SolWeb3Tool":
            self.WORKSPACE_PATH = path
            return self

        def GetCodeClassFromBuild(self, class_name: str) -> "SolWeb3Tool":
            """
            get the independent files and content from the file system
            :param class_name:
            :return:
            """
            p1bin = os.path.join(self.WORKSPACE_PATH, self.OUTPUT_BUILD, "{}.bin".format(class_name))
            p2abi = os.path.join(self.WORKSPACE_PATH, self.OUTPUT_BUILD, "{}.abi".format(class_name))
            metafile = os.path.join(self.WORKSPACE_PATH, self.OUTPUT_BUILD, "{}_meta.json".format(class_name))
            self._bin = codecs.open(p1bin, 'r', 'utf-8-sig').read()
            self._abi = json.load(codecs.open(p2abi, 'r', 'utf-8-sig'))
            self._meta = json.load(codecs.open(metafile, 'r', 'utf-8-sig'))
            return self

        def GetMetadata(self) -> dict:
            return self._meta

        def GetSourceFileRead(self, file_name: str) -> str:
            asfile = os.path.join(self.WORKSPACE_PATH, file_name)
            return codecs.open(asfile, 'r', 'utf-8-sig').read()

        def GetMetaCompilerVer(self, full: bool = False) -> dict:
            if "compiler" not in self._meta:
                print("key compiler is not found")
                return dict()
            if "version" not in self._meta["compiler"]:
                print("key version is not found")
                return dict()

            return self._meta["compiler"]["version"]

        def GetMetaSettings(self) -> dict:
            if "settings" not in self._meta:
                print("key settings is not found")
                return dict()

            return self._meta["settings"]

        def GetCombinedFile(self) -> "SolWeb3Tool":
            pathc = os.path.join(self.WORKSPACE_PATH, self.OUTPUT_BUILD, "combined.json")
            try:
                pathcli = codecs.open(pathc, 'r', 'utf-8-sig')
                self.combined_data = json.load(pathcli)
            except Exception as e:
                print("Problems from loading items from the file: ", e)
            return self

        def byClassName(self, path: str, classname: str) -> str:
            # generating the string with path and class name
            return "{prefix}:{name}".format(prefix=path, name=classname)

        def GetCodeTag(self, fullname) -> [str, str]:
            """
            Search for the abi session and the bin session from the meta source file
            from combined.json
            :param fullname: initial file name
            :return: abi code and the bin code
            """
            return self.combined_data["contracts"][fullname]["abi"], self.combined_data["contracts"][fullname]["bin"]

        def GetCode(self, path: str, classname: str) -> [str, str]:
            """
            Search for the abi session and the bin session from the meta source file
            get the code and abi from combined.json
            :param path:
            :param classname:
            :return:
            """
            return self.GetCodeTag(self.byClassName(path, classname))

        def CompileBash(self) -> None:
            """
            This is the remote command to execute the solc_remote bash file
            using remote compile method to compile the sol files
            all works will be done with the remote server or using the docker
            """
            list_files = subprocess.run(["{}/solc_remote".format(self.WORKSPACE_PATH)])
            print("The exit code was: %d" % list_files.returncode)

        @property
        def abi(self) -> str:
            return self._abi

        @property
        def bin(self) -> str:
            return self._bin

        @property
        def workspace(self) -> str:
            return self.WORKSPACE_PATH

        def StoreTxResult(self, tx_result_data: any, filepath: str) -> None:
            """
            Having the result of the transaction data to be stored in an external JSON file.
            :param tx_result_data: input data
            :param filepath: the file name path
            :return: nothing to return
            """
            predump = toDict(tx_result_data)
            writeFile(json.dumps(predump, ensure_ascii=False), filepath)

    class MiliDoS(IDos):
        """
        This is the base package function core for all the related operations to execute
        The center hub of the progress source code is in here
        """

        EVM_VERSION = Evm.BERLIN

        def __init__(self, _nodeCfg: Config):
            # the hidden list
            self._contract_dict = dict()
            self._sol_list = list()
            # publicly accessible
            self.project_workspace_root = ""
            self.accountAddr = None
            self.pathfinder = None
            self.artifact_manager = None
            self._sol_link = None
            self.is_deploy = False
            self.is_internal = False
            self.deployed_address = False
            self.last_class = ""
            self.list_type = "list_address"
            self.network_cfg = _nodeCfg
            self.w3 = web3_provider(_nodeCfg.rpc_url)
            self._optimizations = 200
            result = self.w3.isConnected()
            if not result:
                print(f"try to connect {self.network_cfg.network_name}  {Bolors.WARNING} {self.network_cfg.rpc_url}: {result} {Bolors.RESET}")
                exit(0)
                return
            else:
                print(f"You are now connected to {Bolors.OK} {self.network_cfg.network_name} {self.network_cfg.rpc_url} {Bolors.RESET}")

        def withPOA(self) -> "MiliDoS":
            """
            the normal usual term to fix some POA related problems
            :return:
            """
            self.w3.middleware_onion.inject(geth_poa_middleware, layer=0)
            return self

        def isAddress(self, address: str) -> bool:
            """
            Verification of the valid EVM address
            :param address:
            :return:
            """
            return self.w3.isAddress(address)

        def connect(self, workspace: str, history: any) -> None:

            """
            connect the existing deployed contract
            :param workspace: the workspace directory
            :param history: the deployed history folder under the deploy_history
            :return:
            """
            self.is_deploy = False
            self.artifact_manager = SolWeb3Tool()
            if history is False:
                self.pathfinder = Paths(workspace).setDefaultPath().Network(self.network_cfg.network_name)
            else:
                self.pathfinder = Paths(workspace).SetUseHistory(history).Network(self.network_cfg.network_name)

            self.ready_io(True)

        def SetupContract(self):
            pass

        def after_deployment_initialize_settings(self):
            """
            setup contract starting params
            setup the starting time using bang
            setup the first member
            :return:
            """
            pass

        def setWorkspace(self, path: str, readio: bool = True) -> "MiliDoS":
            self.project_workspace_root = path
            self.artifact_manager = SolWeb3Tool()
            self.pathfinder = Paths(path).setDefaultPath().Network(self.network_cfg.network_name)
            if readio:
                self.ready_io(True)
            return self

        def setClassSolNames(self, to_compile_contract_list: list) -> "MiliDoS":
            self._sol_list = to_compile_contract_list
            return self

        def setClassSolLinks(self, compile_links: list) -> "MiliDoS":
            self._sol_link = compile_links
            return self

        def setEvm(self, version_evm: str) -> "MiliDoS":
            """
            the specify the version of the ethereum virtual machine
            :param version_evm: the version of the EVM
            :return:
            """
            self.EVM_VERSION = version_evm
            return self

        def setOptimizationRuns(self, runs: int) -> "MiliDoS":
            self._optimizations = runs
            return self

        def remoteCompile(self, ver: str) -> "MiliDoS":
            """
            all parameters will be inserted automatically according to the previous setup
            :param ver:
            :return:
            """
            if ver == "":
                print("there is no solidity version specified")
                exit(0)
            self.pathfinder.setSolVersion(ver)
            self.pathfinder.setEvm(self.EVM_VERSION)
            BuildRemoteLinuxCommand(self.pathfinder, self._optimizations, self._sol_list, self._sol_link)
            return self

        def localTranspile(self, dapp_ts_folder: str = None) -> "MiliDoS":
            """
            :param dapp_ts_folder: the destination is follow by this path {dapp_ts_folder}/src/api/abi/xxx.ts
            if this valuable is None then there will not be any copy files to the destination
            :return: instance of moody
            """
            self.pathfinder.updateTargetDappFolder(dapp_ts_folder)
            BuildLang(self.pathfinder, self._sol_list)
            return self

        def get_block(self, block_identifier, full_transactions: bool = False):
            """
            to see the block information
            :param block_identifier:
            :param full_transactions:
            :return: instance of moody
            """
            with w3_lock:
                res = self.w3.eth.getBlock(block_identifier, full_transactions)
            return res

        def erc20_contract(self):
            cTool = SolWeb3Tool()
            cTool.setBuildNameSpace("artifact").GetCodeClassFromBuild("ERC20")
            return self.w3.eth.contract(abi=cTool.abi)

        def estimate_gas_price(self):
            return self.w3.eth.gasPrice

        def send_contract_tx(self, contract: Web3Contract, function_name: str, from_acc: str,
                             private_key: bytes, gas: int = 0, gas_price: int = 0, _value: int = 0,
                             args: Tuple = ()):
            """
            Creates the contract tx and signs it with private_key to be transmitted as raw tx
            """

            tx = getattr(contract.functions, function_name)(*args).buildTransaction(
                {
                    'from': from_acc,
                    'chainId': self.w3.eth.chainId,
                    # gas_price is in gwei
                    'gasPrice': gas_price * 1e9 if gas_price else self.estimate_gas_price(),
                    'gas': gas or None,
                    'nonce': self.w3.eth.getTransactionCount(from_acc, block_identifier='pending'),
                    'value': _value
                })
            signed_txn = self.w3.eth.account.sign_transaction(tx, private_key)
            return self.w3.eth.sendRawTransaction(signed_txn.rawTransaction)

        def contract_event_in_range(self, contract, event_name: str, from_block: int = 0, to_block: Optional[int] = None) -> None:
            """
            scans the blockchain, and yields blocks that has contract tx with the provided event
            Note: Be cautions with the range provided, as the logic creates query for each block which could be a bottleneck.
            :param from_block: starting block, defaults to 0
            :param to_block: end block, defaults to 'latest'
            :param provider:
            :param logger:
            :param contract:
            :param event_name: name of the contract emit event you wish to be notified of
            """
            if to_block is None:
                to_block = self.w3.eth.blockNumber

            with w3_lock:

                if isinstance(self.w3.provider, HTTPProvider):
                    for block_num in range(from_block, to_block + 1):
                        block = self.w3.eth.getBlock(block_num, full_transactions=True)
                        contract_transactions = extract_tx_by_address(contract.address, block)

                        if not contract_transactions:
                            continue
                        for tx in contract_transactions:
                            _, log = event_log(tx_hash=tx.hash, events=[event_name], provider=self.w3, contract=contract.tracked_contract)
                            if log is None:
                                continue
                            yield log
                else:
                    event = getattr(contract.tracked_contract.events, event_name)
                    event_filter = event.createFilter(fromBlock=from_block, toBlock=to_block)

                    for tx in event_filter.get_new_entries():
                        _, log = event_log(tx_hash=tx.hash, events=[event_name], provider=self.w3, contract=contract.tracked_contract)

                        if log is None:
                            continue

                        yield log

        def AuthByMemo(self, phrase: str = None) -> "MiliDoS":
            keyLo = self.w3.eth.account.from_mnemonic(phrase)
            # self.w3.eth.defaultAccount = keyoo.address
            self.w3.eth.account = keyLo
            # self.w3.eth.get_transaction_count
            # self.w3.eth.accounts[0] = keyLo.address
            # self.w3.eth.defaultAccount(f"0x{keyLo.key}")
            is_address = self.w3.isAddress(keyLo.address)
            # self.w3.isChecksumAddress(keyLo.address)
            self.accountAddr = keyLo.address
            print(f"🔫 You are now using {keyLo.address} and it is a {'valid key' if is_address else 'invalid key'}")

            return self

        def Auth(self, private_key_line: str = None) -> "MiliDoS":
            """
            switching the operating address to a different one that is given by the private key
            :param private_key_line: the input private key
            :return:
            """
            if private_key_line is None:
                private_key_line = DefaultKeys.k0

            # f"0x{private_key_line}"
            keyLo = self.w3.eth.account.from_key(f"0x{private_key_line}")
            # self.w3.eth.defaultAccount = keyoo.address
            self.w3.eth.account = keyLo
            # self.w3.eth.get_transaction_count
            # self.w3.eth.accounts[0] = keyLo.address
            # self.w3.eth.defaultAccount(f"0x{keyLo.key}")
            is_address = self.w3.isAddress(keyLo.address)
            # self.w3.isChecksumAddress(keyLo.address)
            self.accountAddr = keyLo.address
            print(f"🔫 You are now using {keyLo.address} and it is a {'valid key' if is_address else 'invalid key'}")

            return self

        def estimateGas(self, class_name: str) -> int:
            """
            only for testing the contract deploy gas requirement
            :param class_name:
            :return:
            """
            # estimate_gas
            solc_artifact = SolWeb3Tool()
            solc_artifact.setBasePath(self.project_workspace_root)
            solc_artifact = solc_artifact.GetCodeClassFromBuild(class_name)
            nr = self.w3.eth.contract(abi=solc_artifact.abi, bytecode=solc_artifact.bin)
            gas_est_amount = nr.constructor().estimateGas()
            price = self.w3.eth.generate_gas_price()
            # source: https://ethereum.stackexchange.com/questions/84943/what-is-the-equivalent-of-buildtransaction-of-web3py-in-web3js
            print(f"Price: {price}")
            return gas_est_amount

        def OverrideGasConfig(self, gas: int, gas_price: int) -> None:
            """
            the override the configuration for the gas amount and the gas price
            :param gas: int
            :param gas_price: int
            :return: NONE
            """
            self.network_cfg.gas = gas
            self.network_cfg.gasPrice = gas_price

        def OverrideChainConfig(self, one: int, wait: int) -> None:
            """
            Lets have the configuration done now.
            :param one: ONE coin to measure
            :param wait: the waiting time from each block confirmation
            :return:
            """
            self.network_cfg.wait_time = wait
            self.network_cfg.one = one

        @property
        def gas(self) -> int:
            return self.network_cfg.gas

        @property
        def gasPrice(self) -> int:
            return self.network_cfg.gasPrice

        @property
        def one(self) -> int:
            """
            ONE platform coin will be decoded to be...
            :return: int
            """
            return self.network_cfg.one

        @property
        def waitSec(self) -> int:
            return self.network_cfg.wait_time

        @property
        def LinkVRFHashKey(self) -> str:
            if self.network_cfg.link_keyhash is None:
                raise ValueError("Link VRF Hash Key is endorsed on this network")
            else:
                return self.network_cfg.link_keyhash

        @property
        def LinkVRFCoordinator(self) -> str:
            if self.network_cfg.link_vrf_coordinator is None:
                raise ValueError("Link VRF is endorsed on this network")
            else:
                return self.network_cfg.link_vrf_coordinator

        @property
        def LinkTokenAddress(self) -> str:
            if self.network_cfg.link_token is None:
                raise ValueError("Link Token is endorsed on this network")
            else:
                return self.network_cfg.link_token

        def _checkErrorForTxReceipt(self, receipt: any, class_name: str, jsonfile: str) -> None:
            if "contractAddress" not in receipt:
                print(f"⚠️ Error from deploy contract and no valid address found for {class_name}.")
                raise InvalidAddress

            if "transactionHash" not in receipt:
                print(f"⚠️ The deployment is failed because there is no valid address found from {class_name}. Please check for internal errors from deployment has {receipt.transactionHash}")
                raise InvalidAddress

            hash = str(receipt.transactionHash)
            preaddress = str(receipt.contractAddress)
            if self.isAddress(preaddress) is False:
                print(f"⚠️ The deployment is failed because there is no valid address found from {class_name}. Please check for internal errors from deployment hash from {jsonfile}")
                raise InvalidAddress

        def provide_artifact_extends(self, class_name: str) -> SolWeb3Tool:
            """
            Following the class name of the contract
            :param class_name:
            :return:
            """
            if not self.artifact_manager:
                print("❌ Root path is not setup. please setup the workspace first.")
                exit(2)

            sol = self.artifact_manager
            sol.setBasePath(self.project_workspace_root)
            sol.setBuildNameSpace("build")
            sol = sol.GetCodeClassFromBuild(class_name)
            self.artifact_manager = sol
            return sol

        def provide_artifact_implemented(self, class_name: str) -> SolWeb3Tool:
            """
            Use the internal available class names. Please see the internal class name list
            :param class_name:
            :return:
            """
            if not self.artifact_manager:
                print("❌ Root path is not setup. please setup the workspace first.")
                exit(2)

            sol = self.artifact_manager
            sol.setBasePath(root_base_path)
            sol.setBuildNameSpace("artifacts")
            sol = sol.GetCodeClassFromBuild(class_name)
            self.artifact_manager = sol
            return sol

        def deployImple(self, class_name: str, params: list = [], gas_price: int = 0, gas_limit: int = 0) -> bool:
            """
            Deployment of implemented abi and code
            :param class_name:
            :param params:
            :param gas_price:
            :param gas_limit:
            :return:
            """
            contract_nv = None
            try:
                solc_artifact = self.provide_artifact_implemented(class_name)
                bin = BinOp(solc_artifact.bin, class_name)
                if bin.checkBinForUndeployLib() is True:
                    bin.setDebug(True)
                    # try to find the needed libraries in address..
                    bin.anaylze(self)
                    contract_nv = self.w3.eth.contract(abi=solc_artifact.abi, bytecode=bin.GetKnifedBin())
                else:
                    contract_nv = self.w3.eth.contract(abi=solc_artifact.abi, bytecode=bin.GetRawBin())

            except FileNotFoundError:
                print("💢 bin or abi file is not found.")
                exit(3)
            except FoundUndeployedLibraries:
                exit(4)
            except ContractLogicError as e:
                print(f"💢 Contract error {e}")
                exit(5)
            gasprice = self.gasPrice if gas_price == 0 else gas_price
            gas = self.gas if gas_limit == 0 else gas_limit
            if len(params) > 0:
                _transaction = contract_nv.constructor(*params).buildTransaction({
                    "gasPrice": gasprice,
                    "gas": gas
                })
            else:
                _transaction = contract_nv.constructor().buildTransaction({
                    "gasPrice": gasprice,
                    "gas": gas
                })
            self.artifact_manager.setBasePath(self.project_workspace_root)
            return self._endingdeployment(_transaction, class_name)

        def deploy(self, class_name: str, params: list = [], gas_price: int = 0, gas_limit: int = 0) -> bool:
            """
            This is using the faster way to deploy files by using the specific abi and bin files.
            If all these parameters to be ignored then these things will be taken from other available
            valuables for gas price and gas limit
            :param class_name: the input class name
            :param params: the parameters
            :param gas_price: the gas price
            :param gas_limit: the gas limit
            :return:
            """
            contract_nv = None
            try:
                solc_artifact = self.provide_artifact_extends(class_name)
                bin = BinOp(solc_artifact.bin, class_name)
                if bin.checkBinForUndeployLib() is True:
                    bin.setDebug(True)
                    # try to find the needed libraries in address..
                    bin.anaylze(self)
                    contract_nv = self.w3.eth.contract(abi=solc_artifact.abi, bytecode=bin.GetKnifedBin())
                else:
                    contract_nv = self.w3.eth.contract(abi=solc_artifact.abi, bytecode=bin.GetRawBin())

            except FileNotFoundError:
                print("💢 bin or abi file is not found.")
                exit(3)
            except FoundUndeployedLibraries:
                exit(4)
            except ContractLogicError as e:
                print(f"💢 Contract error {e}")
                exit(5)

            gasprice = self.gasPrice if gas_price == 0 else gas_price
            gas = self.gas if gas_limit == 0 else gas_limit
            if len(params) > 0:
                _transaction = contract_nv.constructor(*params).buildTransaction({
                    "gasPrice": gasprice,
                    "gas": gas
                })
            else:
                _transaction = contract_nv.constructor().buildTransaction({
                    "gasPrice": gasprice,
                    "gas": gas
                })
            return self._endingdeployment(_transaction, class_name)

        def _endingdeployment(self, _transaction: any, class_name: str) -> bool:
            try:
                _transaction['nonce'] = self.w3.eth.getTransactionCount(self.accountAddr)
                _transaction['to'] = None
                # _transaction['gas'] = self.gas if gas_limit == 0 else gas_limit
                # _transaction['gasPrice'] = self.gasPrice if gas_price == 0 else gas_price
                # _transaction['gas'] = 2200000000,
                print("ok --- ", _transaction)
                # Get correct transaction nonce for sender from the node
                print(f"========🖍 Signing {class_name}, gas:{_transaction['gas']}, price:{_transaction['gasPrice']} ...")
                signed = self.w3.eth.account.sign_transaction(_transaction)

                txHash = self.w3.eth.sendRawTransaction(signed.rawTransaction)
                # print(f"Contract '{class_name}' deployed; Waiting to transaction receipt")
                print(f"========Wait for Block Confirmation - {class_name} ☕️")
                tx_receipt = self.w3.eth.waitForTransactionReceipt(txHash)
                print("========TX Pre-Result ✅")
                print(tx_receipt)
                print(f"========Broadcast Result ✅ -> {Paths.showCurrentDeployedClass(class_name)}")

                self._checkErrorForTxReceipt(tx_receipt, class_name, Paths.showCurrentDeployedClass(class_name))
                fresh_address = tx_receipt.contractAddress
                self._contract_dict[class_name] = fresh_address
                self.deployed_address = fresh_address

                self._contract_dict["kv_{}".format(class_name)] = dict(
                    by=self.accountAddr,
                )

                print("📦 Address saved to ✅ {} -> {}".format(fresh_address, class_name))
                print(f"🔍 You can check with the explorer for more detail: {Bolors.WARNING} {self.network_cfg.block_explorer}{Bolors.RESET}")

                self.artifact_manager.StoreTxResult(tx_receipt, self.pathfinder.classObject(class_name))
                self.complete_deployment()
                return True
            except InvalidAddress:
                return False
            except ContractLogicError as e:
                print(f"Error: {e}")
                return False
            except TimeExhausted:
                print("After 120 seconds, the boardcast block is not in the chain.")
                return False
            except ValueError as te:
                if "code" in te:
                    code = int(te["code"])
                    if code == -32000:
                        print("NOT ENOUGH GAS - insufficient funds for gas")
                        return False
                print(te)
                return False

        @property
        def __list_key_label(self) -> str:
            return "{}_{}".format(self.list_type, self.last_class)

        @property
        def __kv_label(self) -> str:
            return "kv_{}".format(self.last_class)

        def getAddr(self, keyname: str) -> str:
            """example: TT67rPNwgmpeimvHUMVzFfKsjL9GZ1wGw8"""
            return self._contract_dict.get(keyname)

        def getAllAddress(self) -> dict:
            return self._contract_dict

        def preview_all_addresses(self) -> None:
            print(self._contract_dict)

        def is_deployment(self) -> bool:
            return self.is_deploy

        def ready_io(self, show_address: bool = False):
            """try to load up the file from the existing path"""
            try:
                self._contract_dict = self.pathfinder.LoadDeploymentFile()
                print("📦 Review the loaded deployment data from ... ")
                if show_address:
                    self.preview_all_addresses()
            except FileNotFoundError:
                print("💢 Deployment File is not found ...")
            except TypeError as e:
                print(e)

        def setTargetClass(self, classname: str) -> "MiliDoS":
            self.last_class = classname
            return self

        def setTargetListName(self, listname: str) -> "MiliDoS":
            self.list_type = listname
            return self

        def setKV(self, key: str, value: any) -> "MiliDoS":

            if self.__kv_label not in self._contract_dict:
                self._contract_dict[self.__kv_label] = dict()

            self._contract_dict[self.__kv_label][key] = value
            return self

        def hasAddressInList(self, address: str) -> bool:
            if self.__list_key_label not in self._contract_dict:
                return False
            try:
                v = self._contract_dict[self.__list_key_label].index(address)
                return True
            except ValueError:
                return False

        def pushAddress(self, address: str, unique: bool = True) -> bool:
            if self.__list_key_label not in self._contract_dict:
                self._contract_dict[self.__list_key_label] = list()

            if unique is True:
                try:
                    found_index = self._contract_dict[self.__list_key_label].index(address)
                    return False
                except ValueError:
                    self._contract_dict[self.__list_key_label].append(address)
                    return True
                except IndexError:
                    self._contract_dict[self.__list_key_label].append(address)
                    return True
            else:
                self._contract_dict[self.__list_key_label].append(address)
                return True

        def removeAddress(self, address: str) -> bool:
            if self.__list_key_label not in self._contract_dict:
                return False
            self._contract_dict[self.__list_key_label].remove(address)
            return True

        def iterList(self) -> iter:
            if self.__list_key_label not in self._contract_dict:
                raise Exception("there is no list in the map")
            return iter(self._contract_dict[self.__list_key_label])

        def hasList(self) -> bool:
            if self.__list_key_label not in self._contract_dict:
                return False
            return len(self._contract_dict[self.__list_key_label]) > 0

        def hasField(self, key: str) -> bool:
            if self.__kv_label not in self._contract_dict:
                self._contract_dict[self.__kv_label] = dict()

            if key not in self._contract_dict[self.__kv_label]:
                return False
            else:
                return True

        def hasContractName(self, name: str) -> bool:
            return name in self._contract_dict

        def getString(self, key: str) -> str:
            return str(self.getVal(key))

        def getInt(self, key: str) -> int:
            return int(self.getVal(key))

        def getBytesArray(self, key: str) -> bytearray:
            return bytearray(self.getVal(key))

        def getBytes(self, key: str) -> bytes:
            return bytes(self.getVal(key))

        def getFloat(self, key: str) -> float:
            return float(self.getVal(key))

        def getVal(self, key: str) -> any:
            if self.__kv_label not in self._contract_dict:
                self._contract_dict[self.__kv_label] = dict()

            if key in self._contract_dict[self.__kv_label]:
                return self._contract_dict[self.__kv_label][key]

            return ""

        def complete_deployment(self) -> None:
            """store up the deployed contrcat addresses to the local file storage"""
            self.artifact_manager.StoreTxResult(self._contract_dict, self.pathfinder.SaveDeployConfig)

        def SaveConfig(self) -> None:
            self.complete_deployment()

## Functions

`def Logd(anystr: )`
  Expand source code

      def Logd(anystr: any):
          print(anystr)

`def event_log(tx_hash: str, events: List[str], provider: web3.main.Web3, contract: web3.contract.Contract) ‑> Tuple[str, Union[web3.datastructures.AttributeDict, NoneType]]`

  Extracts logs of @event from tx_hash if present :param tx_hash: :param events: Case sensitive events name :param provider: :param contract: Web3 Contract :return: event name and log represented in 'AttributeDict' or 'None' if not found

  Expand source code

      def event_log(tx_hash: str, events: List[str], provider: Web3, contract: Web3Contract) -> Tuple[str, Optional[AttributeDict]]:
          """
          Extracts logs of @event from tx_hash if present
          :param tx_hash:
          :param events: Case sensitive events name
          :param provider:
          :param contract: Web3 Contract
          :return: event name and log represented in 'AttributeDict' or 'None' if not found
          """
          try:
              receipt = provider.eth.getTransactionReceipt(tx_hash)
          except TransactionNotFound:
              time.sleep(3000)  # hard coded sleep for 3 seconds... maybe this will help?
              # retry
              try:
                  receipt = provider.eth.getTransactionReceipt(tx_hash)
              except TransactionNotFound:
                  return '', None

          for event in events:
              # we discard warning as we do best effort to find wanted event, not always there
              # as we listen to the entire contract tx, might
              log = getattr(contract.events, event)().processReceipt(receipt, DISCARD)
              if log:
                  data_index = 0
                  return event, log[data_index]
          # todo: fix this - seems like some weird return
          return '', None

`def extract_tx_by_address(address, block: web3.types.BlockData) ‑> list`
  Expand source code

      def extract_tx_by_address(address, block: BlockData) -> list:
          # Note: block attribute dict has to be generated with full_transactions=True flag
          return [tx for tx in block.transactions if tx.to and address.lower() == tx.to.lower()]

`def normalize_address(address: str)`

  Converts address to address acceptable by web3

  Expand source code

      def normalize_address(address: str):
          """Converts address to address acceptable by web3"""
          return Web3.toChecksumAddress(address.lower())

`def toDict(dictToParse)`
  Expand source code

      def toDict(dictToParse):
          # convert any 'AttributeDict' type found to 'dict'
          parsedDict = dict(dictToParse)
          for key, val in parsedDict.items():
              if 'list' in str(type(val)):
                  parsedDict[key] = [_parseValue(x) for x in val]
              else:
                  parsedDict[key] = _parseValue(val)
          return parsedDict

`def web3_provider(address: str) ‑> web3.main.Web3`
  Expand source code

      def web3_provider(address: str) -> Web3:
          try:
              if address.startswith('http'):  # HTTP
                  return Web3(Web3.HTTPProvider(address))
              if address.startswith('ws'):  # WebSocket
                  return Web3(Web3.WebsocketProvider(address))
              return Web3(Web3.IPCProvider(address))
          except FileNotFoundError:
              raise ValueError("Failed to initialize web3 provider (is eth_node set?)") from None

`def writeFile(content, filename)`
  Expand source code

      def writeFile(content, filename):
          fo = open(filename, "w")
          fo.write(content)
          fo.close()
          print(statement.format(time.ctime(), filename))

## Classes

`class BinOp (bin_content: str, file_name: str)`

  The binary operation for the ops. Taking care the operations for library linking and the related stuffs.

  Expand source code

      class BinOp:
          """
          The binary operation for the ops. Taking care the operations for library linking and the related stuffs.
          """

          def __init__(self, bin_content: str, file_name: str):
              self.bin_raw = bin_content
              self.bin_knifed = bin_content
              self.bin_undeploy_lib = dict()
              self.file_name = file_name
              self.debug = False

          def setDebug(self, de: bool):
              self.debug = de

          def GetRawBin(self) -> str:
              return self.bin_raw

          def GetKnifedBin(self) -> str:
              return self.bin_knifed

          def checkBinForUndeployLib(self) -> bool:
              matches = re.finditer(regex1, self.bin_raw, re.MULTILINE)
              found = False
              for matchNum, match in enumerate(matches, start=1):
                  print("Library {matchNum} is found at {start}-{end}: {match}".format(matchNum=matchNum, start=match.start(), end=match.end(), match=match.group()))
                  k, v = self.fromLine(match.group())
                  self.bin_undeploy_lib[k] = v
                  found = True
              return found

          def fromLine(self, input_line: str) -> Tuple[str, str]:
              class_name = input_line.split(":")[1]
              return class_name, input_line

          def _placehd(self, instruction_line: str) -> str:
              return "__{}__".format(str(instruction_line).split("->")[0].strip(" //"))

          def anaylze(self, databank: IDos) -> bool:
              if len(self.bin_undeploy_lib) == 0:
                  print("🚧 Nothing to process")
                  return False

              for class_name, instruction_line in self.bin_undeploy_lib.items():
                  if databank.hasContractName(class_name) is True:
                      print(f"💽 Found support Class {class_name} - deployment address")
                      if databank.isAddress(databank.getAddr(class_name)):
                          self._knifeBinClass(class_name, self._placehd(instruction_line), databank.getAddr(class_name))
                      else:
                          print("🧊 The found library address is not valid - {}, {}".format(class_name, databank.getAddr(class_name)))
                          raise FoundUndeployedLibraries
                  else:
                      print("⚠️ Unfound library Error- {}, please make sure you have this library deployed.".format(class_name))
                      raise FoundUndeployedLibraries

              self.bin_knifed = self.bin_knifed.splitlines(True)[0]
              self.bin_knifed = self.bin_knifed.replace("\n", "")
              # self.bin_knifed = "0x" + self.bin_knifed
              if self.debug is True:
                  print(f"After processed bin file - {self.file_name}.bin (should be done now)")
                  print(self.bin_knifed)
                  # print(self.bin_raw)
                  print("File content end ##")
              else:
                  print(f"After processed bin file - {self.file_name}.bin")

              return True

          def _knifeBinClass(self, c: str, k: str, address: str) -> None:
              # address_step_1 = address.lower()
              address_step_2 = address.replace("0x", "")
              self.bin_knifed = self.bin_knifed.replace(k, address_step_2)
              print(f"🍡 Linked successfully for Solidity Class {c} with {address}")

  ### Methods

  `def GetKnifedBin(self) ‑> str`
    Expand source code

        def GetKnifedBin(self) -> str:
            return self.bin_knifed

  `def GetRawBin(self) ‑> str`
    Expand source code

        def GetRawBin(self) -> str:
            return self.bin_raw

  `def anaylze(self, databank: IDos) ‑> bool`
    Expand source code

        def anaylze(self, databank: IDos) -> bool:
            if len(self.bin_undeploy_lib) == 0:
                print("🚧 Nothing to process")
                return False

            for class_name, instruction_line in self.bin_undeploy_lib.items():
                if databank.hasContractName(class_name) is True:
                    print(f"💽 Found support Class {class_name} - deployment address")
                    if databank.isAddress(databank.getAddr(class_name)):
                        self._knifeBinClass(class_name, self._placehd(instruction_line), databank.getAddr(class_name))
                    else:
                        print("🧊 The found library address is not valid - {}, {}".format(class_name, databank.getAddr(class_name)))
                        raise FoundUndeployedLibraries
                else:
                    print("⚠️ Unfound library Error- {}, please make sure you have this library deployed.".format(class_name))
                    raise FoundUndeployedLibraries

            self.bin_knifed = self.bin_knifed.splitlines(True)[0]
            self.bin_knifed = self.bin_knifed.replace("\n", "")
            # self.bin_knifed = "0x" + self.bin_knifed
            if self.debug is True:
                print(f"After processed bin file - {self.file_name}.bin (should be done now)")
                print(self.bin_knifed)
                # print(self.bin_raw)
                print("File content end ##")
            else:
                print(f"After processed bin file - {self.file_name}.bin")

            return True

  `def checkBinForUndeployLib(self) ‑> bool`
    Expand source code

        def checkBinForUndeployLib(self) -> bool:
            matches = re.finditer(regex1, self.bin_raw, re.MULTILINE)
            found = False
            for matchNum, match in enumerate(matches, start=1):
                print("Library {matchNum} is found at {start}-{end}: {match}".format(matchNum=matchNum, start=match.start(), end=match.end(), match=match.group()))
                k, v = self.fromLine(match.group())
                self.bin_undeploy_lib[k] = v
                found = True
            return found

  `def fromLine(self, input_line: str) ‑> Tuple[str, str]`
    Expand source code

        def fromLine(self, input_line: str) -> Tuple[str, str]:
            class_name = input_line.split(":")[1]
            return class_name, input_line

  `def setDebug(self, de: bool)`
    Expand source code

        def setDebug(self, de: bool):
            self.debug = de

`class HexJsonEncoder (*, skipkeys=False, ensure_ascii=True, check_circular=True, allow_nan=True, sort_keys=False, indent=None, separators=None, default=None)`

  Extensible JSON http://json.org encoder for Python data structures.

  Supports the following objects and types by default:

  +-------------------+---------------+ | Python | JSON | +===================+===============+ | dict | object | +-------------------+---------------+ | list, tuple | array | +-------------------+---------------+ | str | string | +-------------------+---------------+ | int, float | number | +-------------------+---------------+ | True | true | +-------------------+---------------+ | False | false | +-------------------+---------------+ | None | null | +-------------------+---------------+

  To extend this to recognize other objects, subclass and implement a `.default()` method with another method that returns a serializable object for `o` if possible, otherwise it should call the superclass implementation (to raise `TypeError`).

  Constructor for JSONEncoder, with sensible defaults.

  If skipkeys is false, then it is a TypeError to attempt encoding of keys that are not str, int, float or None. If skipkeys is True, such items are simply skipped.

  If ensure_ascii is true, the output is guaranteed to be str objects with all incoming non-ASCII characters escaped. If ensure_ascii is false, the output can contain non-ASCII characters.

  If check_circular is true, then lists, dicts, and custom encoded objects will be checked for circular references during encoding to prevent an infinite recursion (which would cause an OverflowError). Otherwise, no such check takes place.

  If allow_nan is true, then NaN, Infinity, and -Infinity will be encoded as such. This behavior is not JSON specification compliant, but is consistent with most JavaScript based encoders and decoders. Otherwise, it will be a ValueError to encode such floats.

  If sort_keys is true, then the output of dictionaries will be sorted by key; this is useful for regression tests to ensure that JSON serializations can be compared on a day-to-day basis.

  If indent is a non-negative integer, then JSON array elements and object members will be pretty-printed with that indent level. An indent level of 0 will only insert newlines. None is the most compact representation.

  If specified, separators should be an (item_separator, key_separator) tuple. The default is (', ', ': ') if indent is `None` and (',', ': ') otherwise. To get the most compact JSON representation, you should specify (',', ':') to eliminate whitespace.

  If specified, default is a function that gets called for objects that can't otherwise be serialized. It should return a JSON encodable version of the object or raise a `TypeError`.

  Expand source code

      class HexJsonEncoder(json.JSONEncoder):
          def default(self, obj):
              if isinstance(obj, HexBytes):
                  return obj.hex()
              return super().default(obj)

  ### Ancestors

  - json.encoder.JSONEncoder

  ### Methods

  `def default(self, obj)`

    Implement this method in a subclass such that it returns a serializable object for `o`, or calls the base implementation (to raise a `TypeError`).

    For example, to support arbitrary iterators, you could implement default like this::

        def default(self, o):
            try:
                iterable = iter(o)
            except TypeError:
                pass
            else:
                return list(iterable)
            # Let the base class default method raise the TypeError
            return JSONEncoder.default(self, o)

    Expand source code

        def default(self, obj):
            if isinstance(obj, HexBytes):
                return obj.hex()
            return super().default(obj)

`class IDos`
  Expand source code

      class IDos:
          def hasContractName(self, name: str) -> bool:
              pass

          def getAddr(self, keyname: str) -> str:
              pass

          def isAddress(self, add: str) -> bool:
              pass

  ### Subclasses

  - MiliDoS

  ### Methods

  `def getAddr(self, keyname: str) ‑> str`
    Expand source code

        def getAddr(self, keyname: str) -> str:
            pass

  `def hasContractName(self, name: str) ‑> bool`
    Expand source code

        def hasContractName(self, name: str) -> bool:
            pass

  `def isAddress(self, add: str) ‑> bool`
    Expand source code

        def isAddress(self, add: str) -> bool:
            pass

`class MiliDoS (_nodeCfg: Config)`

  This is the base package function core for all the related operations to execute The center hub of the progress source code is in here

  Expand source code

      class MiliDoS(IDos):
          """
          This is the base package function core for all the related operations to execute
          The center hub of the progress source code is in here
          """

          EVM_VERSION = Evm.BERLIN

          def __init__(self, _nodeCfg: Config):
              # the hidden list
              self._contract_dict = dict()
              self._sol_list = list()
              # publicly accessible
              self.project_workspace_root = ""
              self.accountAddr = None
              self.pathfinder = None
              self.artifact_manager = None
              self._sol_link = None
              self.is_deploy = False
              self.is_internal = False
              self.deployed_address = False
              self.last_class = ""
              self.list_type = "list_address"
              self.network_cfg = _nodeCfg
              self.w3 = web3_provider(_nodeCfg.rpc_url)
              self._optimizations = 200
              result = self.w3.isConnected()
              if not result:
                  print(f"try to connect {self.network_cfg.network_name}  {Bolors.WARNING} {self.network_cfg.rpc_url}: {result} {Bolors.RESET}")
                  exit(0)
                  return
              else:
                  print(f"You are now connected to {Bolors.OK} {self.network_cfg.network_name} {self.network_cfg.rpc_url} {Bolors.RESET}")

          def withPOA(self) -> "MiliDoS":
              """
              the normal usual term to fix some POA related problems
              :return:
              """
              self.w3.middleware_onion.inject(geth_poa_middleware, layer=0)
              return self

          def isAddress(self, address: str) -> bool:
              """
              Verification of the valid EVM address
              :param address:
              :return:
              """
              return self.w3.isAddress(address)

          def connect(self, workspace: str, history: any) -> None:

              """
              connect the existing deployed contract
              :param workspace: the workspace directory
              :param history: the deployed history folder under the deploy_history
              :return:
              """
              self.is_deploy = False
              self.artifact_manager = SolWeb3Tool()
              if history is False:
                  self.pathfinder = Paths(workspace).setDefaultPath().Network(self.network_cfg.network_name)
              else:
                  self.pathfinder = Paths(workspace).SetUseHistory(history).Network(self.network_cfg.network_name)

              self.ready_io(True)

          def SetupContract(self):
              pass

          def after_deployment_initialize_settings(self):
              """
              setup contract starting params
              setup the starting time using bang
              setup the first member
              :return:
              """
              pass

          def setWorkspace(self, path: str, readio: bool = True) -> "MiliDoS":
              self.project_workspace_root = path
              self.artifact_manager = SolWeb3Tool()
              self.pathfinder = Paths(path).setDefaultPath().Network(self.network_cfg.network_name)
              if readio:
                  self.ready_io(True)
              return self

          def setClassSolNames(self, to_compile_contract_list: list) -> "MiliDoS":
              self._sol_list = to_compile_contract_list
              return self

          def setClassSolLinks(self, compile_links: list) -> "MiliDoS":
              self._sol_link = compile_links
              return self

          def setEvm(self, version_evm: str) -> "MiliDoS":
              """
              the specify the version of the ethereum virtual machine
              :param version_evm: the version of the EVM
              :return:
              """
              self.EVM_VERSION = version_evm
              return self

          def setOptimizationRuns(self, runs: int) -> "MiliDoS":
              self._optimizations = runs
              return self

          def remoteCompile(self, ver: str) -> "MiliDoS":
              """
              all parameters will be inserted automatically according to the previous setup
              :param ver:
              :return:
              """
              if ver == "":
                  print("there is no solidity version specified")
                  exit(0)
              self.pathfinder.setSolVersion(ver)
              self.pathfinder.setEvm(self.EVM_VERSION)
              BuildRemoteLinuxCommand(self.pathfinder, self._optimizations, self._sol_list, self._sol_link)
              return self

          def localTranspile(self, dapp_ts_folder: str = None) -> "MiliDoS":
              """
              :param dapp_ts_folder: the destination is follow by this path {dapp_ts_folder}/src/api/abi/xxx.ts
              if this valuable is None then there will not be any copy files to the destination
              :return: instance of moody
              """
              self.pathfinder.updateTargetDappFolder(dapp_ts_folder)
              BuildLang(self.pathfinder, self._sol_list)
              return self

          def get_block(self, block_identifier, full_transactions: bool = False):
              """
              to see the block information
              :param block_identifier:
              :param full_transactions:
              :return: instance of moody
              """
              with w3_lock:
                  res = self.w3.eth.getBlock(block_identifier, full_transactions)
              return res

          def erc20_contract(self):
              cTool = SolWeb3Tool()
              cTool.setBuildNameSpace("artifact").GetCodeClassFromBuild("ERC20")
              return self.w3.eth.contract(abi=cTool.abi)

          def estimate_gas_price(self):
              return self.w3.eth.gasPrice

          def send_contract_tx(self, contract: Web3Contract, function_name: str, from_acc: str,
                               private_key: bytes, gas: int = 0, gas_price: int = 0, _value: int = 0,
                               args: Tuple = ()):
              """
              Creates the contract tx and signs it with private_key to be transmitted as raw tx
              """

              tx = getattr(contract.functions, function_name)(*args).buildTransaction(
                  {
                      'from': from_acc,
                      'chainId': self.w3.eth.chainId,
                      # gas_price is in gwei
                      'gasPrice': gas_price * 1e9 if gas_price else self.estimate_gas_price(),
                      'gas': gas or None,
                      'nonce': self.w3.eth.getTransactionCount(from_acc, block_identifier='pending'),
                      'value': _value
                  })
              signed_txn = self.w3.eth.account.sign_transaction(tx, private_key)
              return self.w3.eth.sendRawTransaction(signed_txn.rawTransaction)

          def contract_event_in_range(self, contract, event_name: str, from_block: int = 0, to_block: Optional[int] = None) -> None:
              """
              scans the blockchain, and yields blocks that has contract tx with the provided event
              Note: Be cautions with the range provided, as the logic creates query for each block which could be a bottleneck.
              :param from_block: starting block, defaults to 0
              :param to_block: end block, defaults to 'latest'
              :param provider:
              :param logger:
              :param contract:
              :param event_name: name of the contract emit event you wish to be notified of
              """
              if to_block is None:
                  to_block = self.w3.eth.blockNumber

              with w3_lock:

                  if isinstance(self.w3.provider, HTTPProvider):
                      for block_num in range(from_block, to_block + 1):
                          block = self.w3.eth.getBlock(block_num, full_transactions=True)
                          contract_transactions = extract_tx_by_address(contract.address, block)

                          if not contract_transactions:
                              continue
                          for tx in contract_transactions:
                              _, log = event_log(tx_hash=tx.hash, events=[event_name], provider=self.w3, contract=contract.tracked_contract)
                              if log is None:
                                  continue
                              yield log
                  else:
                      event = getattr(contract.tracked_contract.events, event_name)
                      event_filter = event.createFilter(fromBlock=from_block, toBlock=to_block)

                      for tx in event_filter.get_new_entries():
                          _, log = event_log(tx_hash=tx.hash, events=[event_name], provider=self.w3, contract=contract.tracked_contract)

                          if log is None:
                              continue

                          yield log

          def AuthByMemo(self, phrase: str = None) -> "MiliDoS":
              keyLo = self.w3.eth.account.from_mnemonic(phrase)
              # self.w3.eth.defaultAccount = keyoo.address
              self.w3.eth.account = keyLo
              # self.w3.eth.get_transaction_count
              # self.w3.eth.accounts[0] = keyLo.address
              # self.w3.eth.defaultAccount(f"0x{keyLo.key}")
              is_address = self.w3.isAddress(keyLo.address)
              # self.w3.isChecksumAddress(keyLo.address)
              self.accountAddr = keyLo.address
              print(f"🔫 You are now using {keyLo.address} and it is a {'valid key' if is_address else 'invalid key'}")

              return self

          def Auth(self, private_key_line: str = None) -> "MiliDoS":
              """
              switching the operating address to a different one that is given by the private key
              :param private_key_line: the input private key
              :return:
              """
              if private_key_line is None:
                  private_key_line = DefaultKeys.k0

              # f"0x{private_key_line}"
              keyLo = self.w3.eth.account.from_key(f"0x{private_key_line}")
              # self.w3.eth.defaultAccount = keyoo.address
              self.w3.eth.account = keyLo
              # self.w3.eth.get_transaction_count
              # self.w3.eth.accounts[0] = keyLo.address
              # self.w3.eth.defaultAccount(f"0x{keyLo.key}")
              is_address = self.w3.isAddress(keyLo.address)
              # self.w3.isChecksumAddress(keyLo.address)
              self.accountAddr = keyLo.address
              print(f"🔫 You are now using {keyLo.address} and it is a {'valid key' if is_address else 'invalid key'}")

              return self

          def estimateGas(self, class_name: str) -> int:
              """
              only for testing the contract deploy gas requirement
              :param class_name:
              :return:
              """
              # estimate_gas
              solc_artifact = SolWeb3Tool()
              solc_artifact.setBasePath(self.project_workspace_root)
              solc_artifact = solc_artifact.GetCodeClassFromBuild(class_name)
              nr = self.w3.eth.contract(abi=solc_artifact.abi, bytecode=solc_artifact.bin)
              gas_est_amount = nr.constructor().estimateGas()
              price = self.w3.eth.generate_gas_price()
              # source: https://ethereum.stackexchange.com/questions/84943/what-is-the-equivalent-of-buildtransaction-of-web3py-in-web3js
              print(f"Price: {price}")
              return gas_est_amount

          def OverrideGasConfig(self, gas: int, gas_price: int) -> None:
              """
              the override the configuration for the gas amount and the gas price
              :param gas: int
              :param gas_price: int
              :return: NONE
              """
              self.network_cfg.gas = gas
              self.network_cfg.gasPrice = gas_price

          def OverrideChainConfig(self, one: int, wait: int) -> None:
              """
              Lets have the configuration done now.
              :param one: ONE coin to measure
              :param wait: the waiting time from each block confirmation
              :return:
              """
              self.network_cfg.wait_time = wait
              self.network_cfg.one = one

          @property
          def gas(self) -> int:
              return self.network_cfg.gas

          @property
          def gasPrice(self) -> int:
              return self.network_cfg.gasPrice

          @property
          def one(self) -> int:
              """
              ONE platform coin will be decoded to be...
              :return: int
              """
              return self.network_cfg.one

          @property
          def waitSec(self) -> int:
              return self.network_cfg.wait_time

          @property
          def LinkVRFHashKey(self) -> str:
              if self.network_cfg.link_keyhash is None:
                  raise ValueError("Link VRF Hash Key is endorsed on this network")
              else:
                  return self.network_cfg.link_keyhash

          @property
          def LinkVRFCoordinator(self) -> str:
              if self.network_cfg.link_vrf_coordinator is None:
                  raise ValueError("Link VRF is endorsed on this network")
              else:
                  return self.network_cfg.link_vrf_coordinator

          @property
          def LinkTokenAddress(self) -> str:
              if self.network_cfg.link_token is None:
                  raise ValueError("Link Token is endorsed on this network")
              else:
                  return self.network_cfg.link_token

          def _checkErrorForTxReceipt(self, receipt: any, class_name: str, jsonfile: str) -> None:
              if "contractAddress" not in receipt:
                  print(f"⚠️ Error from deploy contract and no valid address found for {class_name}.")
                  raise InvalidAddress

              if "transactionHash" not in receipt:
                  print(f"⚠️ The deployment is failed because there is no valid address found from {class_name}. Please check for internal errors from deployment has {receipt.transactionHash}")
                  raise InvalidAddress

              hash = str(receipt.transactionHash)
              preaddress = str(receipt.contractAddress)
              if self.isAddress(preaddress) is False:
                  print(f"⚠️ The deployment is failed because there is no valid address found from {class_name}. Please check for internal errors from deployment hash from {jsonfile}")
                  raise InvalidAddress

          def provide_artifact_extends(self, class_name: str) -> SolWeb3Tool:
              """
              Following the class name of the contract
              :param class_name:
              :return:
              """
              if not self.artifact_manager:
                  print("❌ Root path is not setup. please setup the workspace first.")
                  exit(2)

              sol = self.artifact_manager
              sol.setBasePath(self.project_workspace_root)
              sol.setBuildNameSpace("build")
              sol = sol.GetCodeClassFromBuild(class_name)
              self.artifact_manager = sol
              return sol

          def provide_artifact_implemented(self, class_name: str) -> SolWeb3Tool:
              """
              Use the internal available class names. Please see the internal class name list
              :param class_name:
              :return:
              """
              if not self.artifact_manager:
                  print("❌ Root path is not setup. please setup the workspace first.")
                  exit(2)

              sol = self.artifact_manager
              sol.setBasePath(root_base_path)
              sol.setBuildNameSpace("artifacts")
              sol = sol.GetCodeClassFromBuild(class_name)
              self.artifact_manager = sol
              return sol

          def deployImple(self, class_name: str, params: list = [], gas_price: int = 0, gas_limit: int = 0) -> bool:
              """
              Deployment of implemented abi and code
              :param class_name:
              :param params:
              :param gas_price:
              :param gas_limit:
              :return:
              """
              contract_nv = None
              try:
                  solc_artifact = self.provide_artifact_implemented(class_name)
                  bin = BinOp(solc_artifact.bin, class_name)
                  if bin.checkBinForUndeployLib() is True:
                      bin.setDebug(True)
                      # try to find the needed libraries in address..
                      bin.anaylze(self)
                      contract_nv = self.w3.eth.contract(abi=solc_artifact.abi, bytecode=bin.GetKnifedBin())
                  else:
                      contract_nv = self.w3.eth.contract(abi=solc_artifact.abi, bytecode=bin.GetRawBin())

              except FileNotFoundError:
                  print("💢 bin or abi file is not found.")
                  exit(3)
              except FoundUndeployedLibraries:
                  exit(4)
              except ContractLogicError as e:
                  print(f"💢 Contract error {e}")
                  exit(5)
              gasprice = self.gasPrice if gas_price == 0 else gas_price
              gas = self.gas if gas_limit == 0 else gas_limit
              if len(params) > 0:
                  _transaction = contract_nv.constructor(*params).buildTransaction({
                      "gasPrice": gasprice,
                      "gas": gas
                  })
              else:
                  _transaction = contract_nv.constructor().buildTransaction({
                      "gasPrice": gasprice,
                      "gas": gas
                  })
              self.artifact_manager.setBasePath(self.project_workspace_root)
              return self._endingdeployment(_transaction, class_name)

          def deploy(self, class_name: str, params: list = [], gas_price: int = 0, gas_limit: int = 0) -> bool:
              """
              This is using the faster way to deploy files by using the specific abi and bin files.
              If all these parameters to be ignored then these things will be taken from other available
              valuables for gas price and gas limit
              :param class_name: the input class name
              :param params: the parameters
              :param gas_price: the gas price
              :param gas_limit: the gas limit
              :return:
              """
              contract_nv = None
              try:
                  solc_artifact = self.provide_artifact_extends(class_name)
                  bin = BinOp(solc_artifact.bin, class_name)
                  if bin.checkBinForUndeployLib() is True:
                      bin.setDebug(True)
                      # try to find the needed libraries in address..
                      bin.anaylze(self)
                      contract_nv = self.w3.eth.contract(abi=solc_artifact.abi, bytecode=bin.GetKnifedBin())
                  else:
                      contract_nv = self.w3.eth.contract(abi=solc_artifact.abi, bytecode=bin.GetRawBin())

              except FileNotFoundError:
                  print("💢 bin or abi file is not found.")
                  exit(3)
              except FoundUndeployedLibraries:
                  exit(4)
              except ContractLogicError as e:
                  print(f"💢 Contract error {e}")
                  exit(5)

              gasprice = self.gasPrice if gas_price == 0 else gas_price
              gas = self.gas if gas_limit == 0 else gas_limit
              if len(params) > 0:
                  _transaction = contract_nv.constructor(*params).buildTransaction({
                      "gasPrice": gasprice,
                      "gas": gas
                  })
              else:
                  _transaction = contract_nv.constructor().buildTransaction({
                      "gasPrice": gasprice,
                      "gas": gas
                  })
              return self._endingdeployment(_transaction, class_name)

          def _endingdeployment(self, _transaction: any, class_name: str) -> bool:
              try:
                  _transaction['nonce'] = self.w3.eth.getTransactionCount(self.accountAddr)
                  _transaction['to'] = None
                  # _transaction['gas'] = self.gas if gas_limit == 0 else gas_limit
                  # _transaction['gasPrice'] = self.gasPrice if gas_price == 0 else gas_price
                  # _transaction['gas'] = 2200000000,
                  print("ok --- ", _transaction)
                  # Get correct transaction nonce for sender from the node
                  print(f"========🖍 Signing {class_name}, gas:{_transaction['gas']}, price:{_transaction['gasPrice']} ...")
                  signed = self.w3.eth.account.sign_transaction(_transaction)

                  txHash = self.w3.eth.sendRawTransaction(signed.rawTransaction)
                  # print(f"Contract '{class_name}' deployed; Waiting to transaction receipt")
                  print(f"========Wait for Block Confirmation - {class_name} ☕️")
                  tx_receipt = self.w3.eth.waitForTransactionReceipt(txHash)
                  print("========TX Pre-Result ✅")
                  print(tx_receipt)
                  print(f"========Broadcast Result ✅ -> {Paths.showCurrentDeployedClass(class_name)}")

                  self._checkErrorForTxReceipt(tx_receipt, class_name, Paths.showCurrentDeployedClass(class_name))
                  fresh_address = tx_receipt.contractAddress
                  self._contract_dict[class_name] = fresh_address
                  self.deployed_address = fresh_address

                  self._contract_dict["kv_{}".format(class_name)] = dict(
                      by=self.accountAddr,
                  )

                  print("📦 Address saved to ✅ {} -> {}".format(fresh_address, class_name))
                  print(f"🔍 You can check with the explorer for more detail: {Bolors.WARNING} {self.network_cfg.block_explorer}{Bolors.RESET}")

                  self.artifact_manager.StoreTxResult(tx_receipt, self.pathfinder.classObject(class_name))
                  self.complete_deployment()
                  return True
              except InvalidAddress:
                  return False
              except ContractLogicError as e:
                  print(f"Error: {e}")
                  return False
              except TimeExhausted:
                  print("After 120 seconds, the boardcast block is not in the chain.")
                  return False
              except ValueError as te:
                  if "code" in te:
                      code = int(te["code"])
                      if code == -32000:
                          print("NOT ENOUGH GAS - insufficient funds for gas")
                          return False
                  print(te)
                  return False

          @property
          def __list_key_label(self) -> str:
              return "{}_{}".format(self.list_type, self.last_class)

          @property
          def __kv_label(self) -> str:
              return "kv_{}".format(self.last_class)

          def getAddr(self, keyname: str) -> str:
              """example: TT67rPNwgmpeimvHUMVzFfKsjL9GZ1wGw8"""
              return self._contract_dict.get(keyname)

          def getAllAddress(self) -> dict:
              return self._contract_dict

          def preview_all_addresses(self) -> None:
              print(self._contract_dict)

          def is_deployment(self) -> bool:
              return self.is_deploy

          def ready_io(self, show_address: bool = False):
              """try to load up the file from the existing path"""
              try:
                  self._contract_dict = self.pathfinder.LoadDeploymentFile()
                  print("📦 Review the loaded deployment data from ... ")
                  if show_address:
                      self.preview_all_addresses()
              except FileNotFoundError:
                  print("💢 Deployment File is not found ...")
              except TypeError as e:
                  print(e)

          def setTargetClass(self, classname: str) -> "MiliDoS":
              self.last_class = classname
              return self

          def setTargetListName(self, listname: str) -> "MiliDoS":
              self.list_type = listname
              return self

          def setKV(self, key: str, value: any) -> "MiliDoS":

              if self.__kv_label not in self._contract_dict:
                  self._contract_dict[self.__kv_label] = dict()

              self._contract_dict[self.__kv_label][key] = value
              return self

          def hasAddressInList(self, address: str) -> bool:
              if self.__list_key_label not in self._contract_dict:
                  return False
              try:
                  v = self._contract_dict[self.__list_key_label].index(address)
                  return True
              except ValueError:
                  return False

          def pushAddress(self, address: str, unique: bool = True) -> bool:
              if self.__list_key_label not in self._contract_dict:
                  self._contract_dict[self.__list_key_label] = list()

              if unique is True:
                  try:
                      found_index = self._contract_dict[self.__list_key_label].index(address)
                      return False
                  except ValueError:
                      self._contract_dict[self.__list_key_label].append(address)
                      return True
                  except IndexError:
                      self._contract_dict[self.__list_key_label].append(address)
                      return True
              else:
                  self._contract_dict[self.__list_key_label].append(address)
                  return True

          def removeAddress(self, address: str) -> bool:
              if self.__list_key_label not in self._contract_dict:
                  return False
              self._contract_dict[self.__list_key_label].remove(address)
              return True

          def iterList(self) -> iter:
              if self.__list_key_label not in self._contract_dict:
                  raise Exception("there is no list in the map")
              return iter(self._contract_dict[self.__list_key_label])

          def hasList(self) -> bool:
              if self.__list_key_label not in self._contract_dict:
                  return False
              return len(self._contract_dict[self.__list_key_label]) > 0

          def hasField(self, key: str) -> bool:
              if self.__kv_label not in self._contract_dict:
                  self._contract_dict[self.__kv_label] = dict()

              if key not in self._contract_dict[self.__kv_label]:
                  return False
              else:
                  return True

          def hasContractName(self, name: str) -> bool:
              return name in self._contract_dict

          def getString(self, key: str) -> str:
              return str(self.getVal(key))

          def getInt(self, key: str) -> int:
              return int(self.getVal(key))

          def getBytesArray(self, key: str) -> bytearray:
              return bytearray(self.getVal(key))

          def getBytes(self, key: str) -> bytes:
              return bytes(self.getVal(key))

          def getFloat(self, key: str) -> float:
              return float(self.getVal(key))

          def getVal(self, key: str) -> any:
              if self.__kv_label not in self._contract_dict:
                  self._contract_dict[self.__kv_label] = dict()

              if key in self._contract_dict[self.__kv_label]:
                  return self._contract_dict[self.__kv_label][key]

              return ""

          def complete_deployment(self) -> None:
              """store up the deployed contrcat addresses to the local file storage"""
              self.artifact_manager.StoreTxResult(self._contract_dict, self.pathfinder.SaveDeployConfig)

          def SaveConfig(self) -> None:
              self.complete_deployment()

  ### Ancestors

  - IDos

  ### Subclasses

  - BusExpress
  - ContractTool
  - ERC20H

  ### Class variables

  `var EVM_VERSION`

  ### Instance variables

  `var LinkTokenAddress : str`
    Expand source code

        @property
        def LinkTokenAddress(self) -> str:
            if self.network_cfg.link_token is None:
                raise ValueError("Link Token is endorsed on this network")
            else:
                return self.network_cfg.link_token

  `var LinkVRFCoordinator : str`
    Expand source code

        @property
        def LinkVRFCoordinator(self) -> str:
            if self.network_cfg.link_vrf_coordinator is None:
                raise ValueError("Link VRF is endorsed on this network")
            else:
                return self.network_cfg.link_vrf_coordinator

  `var LinkVRFHashKey : str`
    Expand source code

        @property
        def LinkVRFHashKey(self) -> str:
            if self.network_cfg.link_keyhash is None:
                raise ValueError("Link VRF Hash Key is endorsed on this network")
            else:
                return self.network_cfg.link_keyhash

  `var gas : int`
    Expand source code

        @property
        def gas(self) -> int:
            return self.network_cfg.gas

  `var gasPrice : int`
    Expand source code

        @property
        def gasPrice(self) -> int:
            return self.network_cfg.gasPrice

  `var one : int`

    ONE platform coin will be decoded to be… :return: int

    Expand source code

        @property
        def one(self) -> int:
            """
            ONE platform coin will be decoded to be...
            :return: int
            """
            return self.network_cfg.one

  `var waitSec : int`
    Expand source code

        @property
        def waitSec(self) -> int:
            return self.network_cfg.wait_time

  ### Methods

  `def Auth(self, private_key_line: str = None) ‑> MiliDoS`

    switching the operating address to a different one that is given by the private key :param private_key_line: the input private key :return:

    Expand source code

        def Auth(self, private_key_line: str = None) -> "MiliDoS":
            """
            switching the operating address to a different one that is given by the private key
            :param private_key_line: the input private key
            :return:
            """
            if private_key_line is None:
                private_key_line = DefaultKeys.k0

            # f"0x{private_key_line}"
            keyLo = self.w3.eth.account.from_key(f"0x{private_key_line}")
            # self.w3.eth.defaultAccount = keyoo.address
            self.w3.eth.account = keyLo
            # self.w3.eth.get_transaction_count
            # self.w3.eth.accounts[0] = keyLo.address
            # self.w3.eth.defaultAccount(f"0x{keyLo.key}")
            is_address = self.w3.isAddress(keyLo.address)
            # self.w3.isChecksumAddress(keyLo.address)
            self.accountAddr = keyLo.address
            print(f"🔫 You are now using {keyLo.address} and it is a {'valid key' if is_address else 'invalid key'}")

            return self

  `def AuthByMemo(self, phrase: str = None) ‑> MiliDoS`
    Expand source code

        def AuthByMemo(self, phrase: str = None) -> "MiliDoS":
            keyLo = self.w3.eth.account.from_mnemonic(phrase)
            # self.w3.eth.defaultAccount = keyoo.address
            self.w3.eth.account = keyLo
            # self.w3.eth.get_transaction_count
            # self.w3.eth.accounts[0] = keyLo.address
            # self.w3.eth.defaultAccount(f"0x{keyLo.key}")
            is_address = self.w3.isAddress(keyLo.address)
            # self.w3.isChecksumAddress(keyLo.address)
            self.accountAddr = keyLo.address
            print(f"🔫 You are now using {keyLo.address} and it is a {'valid key' if is_address else 'invalid key'}")

            return self

  `def OverrideChainConfig(self, one: int, wait: int) ‑> NoneType`

    Lets have the configuration done now. :param one: ONE coin to measure :param wait: the waiting time from each block confirmation :return:

    Expand source code

        def OverrideChainConfig(self, one: int, wait: int) -> None:
            """
            Lets have the configuration done now.
            :param one: ONE coin to measure
            :param wait: the waiting time from each block confirmation
            :return:
            """
            self.network_cfg.wait_time = wait
            self.network_cfg.one = one

  `def OverrideGasConfig(self, gas: int, gas_price: int) ‑> NoneType`

    the override the configuration for the gas amount and the gas price :param gas: int :param gas_price: int :return: NONE

    Expand source code

        def OverrideGasConfig(self, gas: int, gas_price: int) -> None:
            """
            the override the configuration for the gas amount and the gas price
            :param gas: int
            :param gas_price: int
            :return: NONE
            """
            self.network_cfg.gas = gas
            self.network_cfg.gasPrice = gas_price

  `def SaveConfig(self) ‑> NoneType`
    Expand source code

        def SaveConfig(self) -> None:
            self.complete_deployment()

  `def SetupContract(self)`
    Expand source code

        def SetupContract(self):
            pass

  `def after_deployment_initialize_settings(self)`

    setup contract starting params setup the starting time using bang setup the first member :return:

    Expand source code

        def after_deployment_initialize_settings(self):
            """
            setup contract starting params
            setup the starting time using bang
            setup the first member
            :return:
            """
            pass

  `def complete_deployment(self) ‑> NoneType`

    store up the deployed contrcat addresses to the local file storage

    Expand source code

        def complete_deployment(self) -> None:
            """store up the deployed contrcat addresses to the local file storage"""
            self.artifact_manager.StoreTxResult(self._contract_dict, self.pathfinder.SaveDeployConfig)

  `def connect(self, workspace: str, history: ) ‑> NoneType`

    connect the existing deployed contract :param workspace: the workspace directory :param history: the deployed history folder under the deploy_history :return:

    Expand source code

        def connect(self, workspace: str, history: any) -> None:

            """
            connect the existing deployed contract
            :param workspace: the workspace directory
            :param history: the deployed history folder under the deploy_history
            :return:
            """
            self.is_deploy = False
            self.artifact_manager = SolWeb3Tool()
            if history is False:
                self.pathfinder = Paths(workspace).setDefaultPath().Network(self.network_cfg.network_name)
            else:
                self.pathfinder = Paths(workspace).SetUseHistory(history).Network(self.network_cfg.network_name)

            self.ready_io(True)

  `def contract_event_in_range(self, contract, event_name: str, from_block: int = 0, to_block: Union[int, NoneType] = None) ‑> NoneType`

    scans the blockchain, and yields blocks that has contract tx with the provided event Note: Be cautions with the range provided, as the logic creates query for each block which could be a bottleneck. :param from_block: starting block, defaults to 0 :param to_block: end block, defaults to 'latest' :param provider: :param logger: :param contract: :param event_name: name of the contract emit event you wish to be notified of

    Expand source code

        def contract_event_in_range(self, contract, event_name: str, from_block: int = 0, to_block: Optional[int] = None) -> None:
            """
            scans the blockchain, and yields blocks that has contract tx with the provided event
            Note: Be cautions with the range provided, as the logic creates query for each block which could be a bottleneck.
            :param from_block: starting block, defaults to 0
            :param to_block: end block, defaults to 'latest'
            :param provider:
            :param logger:
            :param contract:
            :param event_name: name of the contract emit event you wish to be notified of
            """
            if to_block is None:
                to_block = self.w3.eth.blockNumber

            with w3_lock:

                if isinstance(self.w3.provider, HTTPProvider):
                    for block_num in range(from_block, to_block + 1):
                        block = self.w3.eth.getBlock(block_num, full_transactions=True)
                        contract_transactions = extract_tx_by_address(contract.address, block)

                        if not contract_transactions:
                            continue
                        for tx in contract_transactions:
                            _, log = event_log(tx_hash=tx.hash, events=[event_name], provider=self.w3, contract=contract.tracked_contract)
                            if log is None:
                                continue
                            yield log
                else:
                    event = getattr(contract.tracked_contract.events, event_name)
                    event_filter = event.createFilter(fromBlock=from_block, toBlock=to_block)

                    for tx in event_filter.get_new_entries():
                        _, log = event_log(tx_hash=tx.hash, events=[event_name], provider=self.w3, contract=contract.tracked_contract)

                        if log is None:
                            continue

                        yield log

  `def deploy(self, class_name: str, params: list = [], gas_price: int = 0, gas_limit: int = 0) ‑> bool`

    This is using the faster way to deploy files by using the specific abi and bin files. If all these parameters to be ignored then these things will be taken from other available valuables for gas price and gas limit :param class_name: the input class name :param params: the parameters :param gas_price: the gas price :param gas_limit: the gas limit :return:

    Expand source code

        def deploy(self, class_name: str, params: list = [], gas_price: int = 0, gas_limit: int = 0) -> bool:
            """
            This is using the faster way to deploy files by using the specific abi and bin files.
            If all these parameters to be ignored then these things will be taken from other available
            valuables for gas price and gas limit
            :param class_name: the input class name
            :param params: the parameters
            :param gas_price: the gas price
            :param gas_limit: the gas limit
            :return:
            """
            contract_nv = None
            try:
                solc_artifact = self.provide_artifact_extends(class_name)
                bin = BinOp(solc_artifact.bin, class_name)
                if bin.checkBinForUndeployLib() is True:
                    bin.setDebug(True)
                    # try to find the needed libraries in address..
                    bin.anaylze(self)
                    contract_nv = self.w3.eth.contract(abi=solc_artifact.abi, bytecode=bin.GetKnifedBin())
                else:
                    contract_nv = self.w3.eth.contract(abi=solc_artifact.abi, bytecode=bin.GetRawBin())

            except FileNotFoundError:
                print("💢 bin or abi file is not found.")
                exit(3)
            except FoundUndeployedLibraries:
                exit(4)
            except ContractLogicError as e:
                print(f"💢 Contract error {e}")
                exit(5)

            gasprice = self.gasPrice if gas_price == 0 else gas_price
            gas = self.gas if gas_limit == 0 else gas_limit
            if len(params) > 0:
                _transaction = contract_nv.constructor(*params).buildTransaction({
                    "gasPrice": gasprice,
                    "gas": gas
                })
            else:
                _transaction = contract_nv.constructor().buildTransaction({
                    "gasPrice": gasprice,
                    "gas": gas
                })
            return self._endingdeployment(_transaction, class_name)

  `def deployImple(self, class_name: str, params: list = [], gas_price: int = 0, gas_limit: int = 0) ‑> bool`

    Deployment of implemented abi and code :param class_name: :param params: :param gas_price: :param gas_limit: :return:

    Expand source code

        def deployImple(self, class_name: str, params: list = [], gas_price: int = 0, gas_limit: int = 0) -> bool:
            """
            Deployment of implemented abi and code
            :param class_name:
            :param params:
            :param gas_price:
            :param gas_limit:
            :return:
            """
            contract_nv = None
            try:
                solc_artifact = self.provide_artifact_implemented(class_name)
                bin = BinOp(solc_artifact.bin, class_name)
                if bin.checkBinForUndeployLib() is True:
                    bin.setDebug(True)
                    # try to find the needed libraries in address..
                    bin.anaylze(self)
                    contract_nv = self.w3.eth.contract(abi=solc_artifact.abi, bytecode=bin.GetKnifedBin())
                else:
                    contract_nv = self.w3.eth.contract(abi=solc_artifact.abi, bytecode=bin.GetRawBin())

            except FileNotFoundError:
                print("💢 bin or abi file is not found.")
                exit(3)
            except FoundUndeployedLibraries:
                exit(4)
            except ContractLogicError as e:
                print(f"💢 Contract error {e}")
                exit(5)
            gasprice = self.gasPrice if gas_price == 0 else gas_price
            gas = self.gas if gas_limit == 0 else gas_limit
            if len(params) > 0:
                _transaction = contract_nv.constructor(*params).buildTransaction({
                    "gasPrice": gasprice,
                    "gas": gas
                })
            else:
                _transaction = contract_nv.constructor().buildTransaction({
                    "gasPrice": gasprice,
                    "gas": gas
                })
            self.artifact_manager.setBasePath(self.project_workspace_root)
            return self._endingdeployment(_transaction, class_name)

  `def erc20_contract(self)`
    Expand source code

        def erc20_contract(self):
            cTool = SolWeb3Tool()
            cTool.setBuildNameSpace("artifact").GetCodeClassFromBuild("ERC20")
            return self.w3.eth.contract(abi=cTool.abi)

  `def estimateGas(self, class_name: str) ‑> int`

    only for testing the contract deploy gas requirement :param class_name: :return:

    Expand source code

        def estimateGas(self, class_name: str) -> int:
            """
            only for testing the contract deploy gas requirement
            :param class_name:
            :return:
            """
            # estimate_gas
            solc_artifact = SolWeb3Tool()
            solc_artifact.setBasePath(self.project_workspace_root)
            solc_artifact = solc_artifact.GetCodeClassFromBuild(class_name)
            nr = self.w3.eth.contract(abi=solc_artifact.abi, bytecode=solc_artifact.bin)
            gas_est_amount = nr.constructor().estimateGas()
            price = self.w3.eth.generate_gas_price()
            # source: https://ethereum.stackexchange.com/questions/84943/what-is-the-equivalent-of-buildtransaction-of-web3py-in-web3js
            print(f"Price: {price}")
            return gas_est_amount

  `def estimate_gas_price(self)`
    Expand source code

        def estimate_gas_price(self):
            return self.w3.eth.gasPrice

  `def getAddr(self, keyname: str) ‑> str`

    example: TT67rPNwgmpeimvHUMVzFfKsjL9GZ1wGw8

    Expand source code

        def getAddr(self, keyname: str) -> str:
            """example: TT67rPNwgmpeimvHUMVzFfKsjL9GZ1wGw8"""
            return self._contract_dict.get(keyname)

  `def getAllAddress(self) ‑> dict`
    Expand source code

        def getAllAddress(self) -> dict:
            return self._contract_dict

  `def getBytes(self, key: str) ‑> bytes`
    Expand source code

        def getBytes(self, key: str) -> bytes:
            return bytes(self.getVal(key))

  `def getBytesArray(self, key: str) ‑> bytearray`
    Expand source code

        def getBytesArray(self, key: str) -> bytearray:
            return bytearray(self.getVal(key))

  `def getFloat(self, key: str) ‑> float`
    Expand source code

        def getFloat(self, key: str) -> float:
            return float(self.getVal(key))

  `def getInt(self, key: str) ‑> int`
    Expand source code

        def getInt(self, key: str) -> int:
            return int(self.getVal(key))

  `def getString(self, key: str) ‑> str`
    Expand source code

        def getString(self, key: str) -> str:
            return str(self.getVal(key))

  `def getVal(self, key: str) ‑>`
    Expand source code

        def getVal(self, key: str) -> any:
            if self.__kv_label not in self._contract_dict:
                self._contract_dict[self.__kv_label] = dict()

            if key in self._contract_dict[self.__kv_label]:
                return self._contract_dict[self.__kv_label][key]

            return ""

  `def get_block(self, block_identifier, full_transactions: bool = False)`

    to see the block information :param block_identifier: :param full_transactions: :return: instance of moody

    Expand source code

        def get_block(self, block_identifier, full_transactions: bool = False):
            """
            to see the block information
            :param block_identifier:
            :param full_transactions:
            :return: instance of moody
            """
            with w3_lock:
                res = self.w3.eth.getBlock(block_identifier, full_transactions)
            return res

  `def hasAddressInList(self, address: str) ‑> bool`
    Expand source code

        def hasAddressInList(self, address: str) -> bool:
            if self.__list_key_label not in self._contract_dict:
                return False
            try:
                v = self._contract_dict[self.__list_key_label].index(address)
                return True
            except ValueError:
                return False

  `def hasContractName(self, name: str) ‑> bool`
    Expand source code

        def hasContractName(self, name: str) -> bool:
            return name in self._contract_dict

  `def hasField(self, key: str) ‑> bool`
    Expand source code

        def hasField(self, key: str) -> bool:
            if self.__kv_label not in self._contract_dict:
                self._contract_dict[self.__kv_label] = dict()

            if key not in self._contract_dict[self.__kv_label]:
                return False
            else:
                return True

  `def hasList(self) ‑> bool`
    Expand source code

        def hasList(self) -> bool:
            if self.__list_key_label not in self._contract_dict:
                return False
            return len(self._contract_dict[self.__list_key_label]) > 0

  `def isAddress(self, address: str) ‑> bool`

    Verification of the valid EVM address :param address: :return:

    Expand source code

        def isAddress(self, address: str) -> bool:
            """
            Verification of the valid EVM address
            :param address:
            :return:
            """
            return self.w3.isAddress(address)

  `def is_deployment(self) ‑> bool`
    Expand source code

        def is_deployment(self) -> bool:
            return self.is_deploy

  `def iterList(self) ‑>`
    Expand source code

        def iterList(self) -> iter:
            if self.__list_key_label not in self._contract_dict:
                raise Exception("there is no list in the map")
            return iter(self._contract_dict[self.__list_key_label])

  `def localTranspile(self, dapp_ts_folder: str = None) ‑> MiliDoS`

    :param dapp_ts_folder: the destination is follow by this path {dapp_ts_folder}/src/api/abi/xxx.ts if this valuable is None then there will not be any copy files to the destination :return: instance of moody

    Expand source code

        def localTranspile(self, dapp_ts_folder: str = None) -> "MiliDoS":
            """
            :param dapp_ts_folder: the destination is follow by this path {dapp_ts_folder}/src/api/abi/xxx.ts
            if this valuable is None then there will not be any copy files to the destination
            :return: instance of moody
            """
            self.pathfinder.updateTargetDappFolder(dapp_ts_folder)
            BuildLang(self.pathfinder, self._sol_list)
            return self

  `def preview_all_addresses(self) ‑> NoneType`
    Expand source code

        def preview_all_addresses(self) -> None:
            print(self._contract_dict)

  `def provide_artifact_extends(self, class_name: str) ‑> SolWeb3Tool`

    Following the class name of the contract :param class_name: :return:

    Expand source code

        def provide_artifact_extends(self, class_name: str) -> SolWeb3Tool:
            """
            Following the class name of the contract
            :param class_name:
            :return:
            """
            if not self.artifact_manager:
                print("❌ Root path is not setup. please setup the workspace first.")
                exit(2)

            sol = self.artifact_manager
            sol.setBasePath(self.project_workspace_root)
            sol.setBuildNameSpace("build")
            sol = sol.GetCodeClassFromBuild(class_name)
            self.artifact_manager = sol
            return sol

  `def provide_artifact_implemented(self, class_name: str) ‑> SolWeb3Tool`

    Use the internal available class names. Please see the internal class name list :param class_name: :return:

    Expand source code

        def provide_artifact_implemented(self, class_name: str) -> SolWeb3Tool:
            """
            Use the internal available class names. Please see the internal class name list
            :param class_name:
            :return:
            """
            if not self.artifact_manager:
                print("❌ Root path is not setup. please setup the workspace first.")
                exit(2)

            sol = self.artifact_manager
            sol.setBasePath(root_base_path)
            sol.setBuildNameSpace("artifacts")
            sol = sol.GetCodeClassFromBuild(class_name)
            self.artifact_manager = sol
            return sol

  `def pushAddress(self, address: str, unique: bool = True) ‑> bool`
    Expand source code

        def pushAddress(self, address: str, unique: bool = True) -> bool:
            if self.__list_key_label not in self._contract_dict:
                self._contract_dict[self.__list_key_label] = list()

            if unique is True:
                try:
                    found_index = self._contract_dict[self.__list_key_label].index(address)
                    return False
                except ValueError:
                    self._contract_dict[self.__list_key_label].append(address)
                    return True
                except IndexError:
                    self._contract_dict[self.__list_key_label].append(address)
                    return True
            else:
                self._contract_dict[self.__list_key_label].append(address)
                return True

  `def ready_io(self, show_address: bool = False)`

    try to load up the file from the existing path

    Expand source code

        def ready_io(self, show_address: bool = False):
            """try to load up the file from the existing path"""
            try:
                self._contract_dict = self.pathfinder.LoadDeploymentFile()
                print("📦 Review the loaded deployment data from ... ")
                if show_address:
                    self.preview_all_addresses()
            except FileNotFoundError:
                print("💢 Deployment File is not found ...")
            except TypeError as e:
                print(e)

  `def remoteCompile(self, ver: str) ‑> MiliDoS`

    all parameters will be inserted automatically according to the previous setup :param ver: :return:

    Expand source code

        def remoteCompile(self, ver: str) -> "MiliDoS":
            """
            all parameters will be inserted automatically according to the previous setup
            :param ver:
            :return:
            """
            if ver == "":
                print("there is no solidity version specified")
                exit(0)
            self.pathfinder.setSolVersion(ver)
            self.pathfinder.setEvm(self.EVM_VERSION)
            BuildRemoteLinuxCommand(self.pathfinder, self._optimizations, self._sol_list, self._sol_link)
            return self

  `def removeAddress(self, address: str) ‑> bool`
    Expand source code

        def removeAddress(self, address: str) -> bool:
            if self.__list_key_label not in self._contract_dict:
                return False
            self._contract_dict[self.__list_key_label].remove(address)
            return True

  `def send_contract_tx(self, contract: web3.contract.Contract, function_name: str, from_acc: str, private_key: bytes, gas: int = 0, gas_price: int = 0, args: Tuple = ())`

    Creates the contract tx and signs it with private_key to be transmitted as raw tx

    Expand source code

        def send_contract_tx(self, contract: Web3Contract, function_name: str, from_acc: str,
                             private_key: bytes, gas: int = 0, gas_price: int = 0, _value: int = 0,
                             args: Tuple = ()):
            """
            Creates the contract tx and signs it with private_key to be transmitted as raw tx
            """

            tx = getattr(contract.functions, function_name)(*args).buildTransaction(
                {
                    'from': from_acc,
                    'chainId': self.w3.eth.chainId,
                    # gas_price is in gwei
                    'gasPrice': gas_price * 1e9 if gas_price else self.estimate_gas_price(),
                    'gas': gas or None,
                    'nonce': self.w3.eth.getTransactionCount(from_acc, block_identifier='pending'),
                    'value': _value
                })
            signed_txn = self.w3.eth.account.sign_transaction(tx, private_key)
            return self.w3.eth.sendRawTransaction(signed_txn.rawTransaction)

  `def setClassSolLinks(self, compile_links: list) ‑> MiliDoS`
    Expand source code

        def setClassSolLinks(self, compile_links: list) -> "MiliDoS":
            self._sol_link = compile_links
            return self

  `def setClassSolNames(self, to_compile_contract_list: list) ‑> MiliDoS`
    Expand source code

        def setClassSolNames(self, to_compile_contract_list: list) -> "MiliDoS":
            self._sol_list = to_compile_contract_list
            return self

  `def setEvm(self, version_evm: str) ‑> MiliDoS`

    the specify the version of the ethereum virtual machine :param version_evm: the version of the EVM :return:

    Expand source code

        def setEvm(self, version_evm: str) -> "MiliDoS":
            """
            the specify the version of the ethereum virtual machine
            :param version_evm: the version of the EVM
            :return:
            """
            self.EVM_VERSION = version_evm
            return self

  `def setKV(self, key: str, value: ) ‑> MiliDoS`
    Expand source code

        def setKV(self, key: str, value: any) -> "MiliDoS":

            if self.__kv_label not in self._contract_dict:
                self._contract_dict[self.__kv_label] = dict()

            self._contract_dict[self.__kv_label][key] = value
            return self

  `def setOptimizationRuns(self, runs: int) ‑> MiliDoS`
    Expand source code

        def setOptimizationRuns(self, runs: int) -> "MiliDoS":
            self._optimizations = runs
            return self

  `def setTargetClass(self, classname: str) ‑> MiliDoS`
    Expand source code

        def setTargetClass(self, classname: str) -> "MiliDoS":
            self.last_class = classname
            return self

  `def setTargetListName(self, listname: str) ‑> MiliDoS`
    Expand source code

        def setTargetListName(self, listname: str) -> "MiliDoS":
            self.list_type = listname
            return self

  `def setWorkspace(self, path: str, readio: bool = True) ‑> MiliDoS`
    Expand source code

        def setWorkspace(self, path: str, readio: bool = True) -> "MiliDoS":
            self.project_workspace_root = path
            self.artifact_manager = SolWeb3Tool()
            self.pathfinder = Paths(path).setDefaultPath().Network(self.network_cfg.network_name)
            if readio:
                self.ready_io(True)
            return self

  `def withPOA(self) ‑> MiliDoS`

    the normal usual term to fix some POA related problems :return:

    Expand source code

        def withPOA(self) -> "MiliDoS":
            """
            the normal usual term to fix some POA related problems
            :return:
            """
            self.w3.middleware_onion.inject(geth_poa_middleware, layer=0)
            return self

`class SolWeb3Tool`

  This is the tool to build operation of the compiling solidity contract source code Try to make some improvement of code to make better access This is the artifact manager as we know it

  Expand source code

      class SolWeb3Tool(object):
          """
          This is the tool to build operation of the compiling solidity contract source code
          Try to make some improvement of code to make better access
          This is the artifact manager as we know it
          """
          OUTPUT_BUILD = "build"
          WORKSPACE_PATH = ""
          solfolder = ""
          file_name = "xxx.sol"
          prefixname = ""
          statement = 'End : {}, IO File {}'

          def __init__(self):
              self._abi = None
              self._bin = None
              self._meta = None
              self.combined_data = None
              self._key = None

          def setBuildNameSpace(self, path: str) -> "SolWeb3Tool":
              self.OUTPUT_BUILD = path
              return self

          def setBasePath(self, path: str) -> "SolWeb3Tool":
              self.WORKSPACE_PATH = path
              return self

          def GetCodeClassFromBuild(self, class_name: str) -> "SolWeb3Tool":
              """
              get the independent files and content from the file system
              :param class_name:
              :return:
              """
              p1bin = os.path.join(self.WORKSPACE_PATH, self.OUTPUT_BUILD, "{}.bin".format(class_name))
              p2abi = os.path.join(self.WORKSPACE_PATH, self.OUTPUT_BUILD, "{}.abi".format(class_name))
              metafile = os.path.join(self.WORKSPACE_PATH, self.OUTPUT_BUILD, "{}_meta.json".format(class_name))
              self._bin = codecs.open(p1bin, 'r', 'utf-8-sig').read()
              self._abi = json.load(codecs.open(p2abi, 'r', 'utf-8-sig'))
              self._meta = json.load(codecs.open(metafile, 'r', 'utf-8-sig'))
              return self

          def GetMetadata(self) -> dict:
              return self._meta

          def GetSourceFileRead(self, file_name: str) -> str:
              asfile = os.path.join(self.WORKSPACE_PATH, file_name)
              return codecs.open(asfile, 'r', 'utf-8-sig').read()

          def GetMetaCompilerVer(self, full: bool = False) -> dict:
              if "compiler" not in self._meta:
                  print("key compiler is not found")
                  return dict()
              if "version" not in self._meta["compiler"]:
                  print("key version is not found")
                  return dict()

              return self._meta["compiler"]["version"]

          def GetMetaSettings(self) -> dict:
              if "settings" not in self._meta:
                  print("key settings is not found")
                  return dict()

              return self._meta["settings"]

          def GetCombinedFile(self) -> "SolWeb3Tool":
              pathc = os.path.join(self.WORKSPACE_PATH, self.OUTPUT_BUILD, "combined.json")
              try:
                  pathcli = codecs.open(pathc, 'r', 'utf-8-sig')
                  self.combined_data = json.load(pathcli)
              except Exception as e:
                  print("Problems from loading items from the file: ", e)
              return self

          def byClassName(self, path: str, classname: str) -> str:
              # generating the string with path and class name
              return "{prefix}:{name}".format(prefix=path, name=classname)

          def GetCodeTag(self, fullname) -> [str, str]:
              """
              Search for the abi session and the bin session from the meta source file
              from combined.json
              :param fullname: initial file name
              :return: abi code and the bin code
              """
              return self.combined_data["contracts"][fullname]["abi"], self.combined_data["contracts"][fullname]["bin"]

          def GetCode(self, path: str, classname: str) -> [str, str]:
              """
              Search for the abi session and the bin session from the meta source file
              get the code and abi from combined.json
              :param path:
              :param classname:
              :return:
              """
              return self.GetCodeTag(self.byClassName(path, classname))

          def CompileBash(self) -> None:
              """
              This is the remote command to execute the solc_remote bash file
              using remote compile method to compile the sol files
              all works will be done with the remote server or using the docker
              """
              list_files = subprocess.run(["{}/solc_remote".format(self.WORKSPACE_PATH)])
              print("The exit code was: %d" % list_files.returncode)

          @property
          def abi(self) -> str:
              return self._abi

          @property
          def bin(self) -> str:
              return self._bin

          @property
          def workspace(self) -> str:
              return self.WORKSPACE_PATH

          def StoreTxResult(self, tx_result_data: any, filepath: str) -> None:
              """
              Having the result of the transaction data to be stored in an external JSON file.
              :param tx_result_data: input data
              :param filepath: the file name path
              :return: nothing to return
              """
              predump = toDict(tx_result_data)
              writeFile(json.dumps(predump, ensure_ascii=False), filepath)

  ### Class variables

  `var OUTPUT_BUILD`
  `var WORKSPACE_PATH`
  `var file_name`
  `var prefixname`
  `var solfolder`
  `var statement`

  ### Instance variables

  `var abi : str`
    Expand source code

        @property
        def abi(self) -> str:
            return self._abi

  `var bin : str`
    Expand source code

        @property
        def bin(self) -> str:
            return self._bin

  `var workspace : str`
    Expand source code

        @property
        def workspace(self) -> str:
            return self.WORKSPACE_PATH

  ### Methods

  `def CompileBash(self) ‑> NoneType`

    This is the remote command to execute the solc_remote bash file using remote compile method to compile the sol files all works will be done with the remote server or using the docker

    Expand source code

        def CompileBash(self) -> None:
            """
            This is the remote command to execute the solc_remote bash file
            using remote compile method to compile the sol files
            all works will be done with the remote server or using the docker
            """
            list_files = subprocess.run(["{}/solc_remote".format(self.WORKSPACE_PATH)])
            print("The exit code was: %d" % list_files.returncode)

  `def GetCode(self, path: str, classname: str) ‑> [, ]`

    Search for the abi session and the bin session from the meta source file get the code and abi from combined.json :param path: :param classname: :return:

    Expand source code

        def GetCode(self, path: str, classname: str) -> [str, str]:
            """
            Search for the abi session and the bin session from the meta source file
            get the code and abi from combined.json
            :param path:
            :param classname:
            :return:
            """
            return self.GetCodeTag(self.byClassName(path, classname))

  `def GetCodeClassFromBuild(self, class_name: str) ‑> SolWeb3Tool`

    get the independent files and content from the file system :param class_name: :return:

    Expand source code

        def GetCodeClassFromBuild(self, class_name: str) -> "SolWeb3Tool":
            """
            get the independent files and content from the file system
            :param class_name:
            :return:
            """
            p1bin = os.path.join(self.WORKSPACE_PATH, self.OUTPUT_BUILD, "{}.bin".format(class_name))
            p2abi = os.path.join(self.WORKSPACE_PATH, self.OUTPUT_BUILD, "{}.abi".format(class_name))
            metafile = os.path.join(self.WORKSPACE_PATH, self.OUTPUT_BUILD, "{}_meta.json".format(class_name))
            self._bin = codecs.open(p1bin, 'r', 'utf-8-sig').read()
            self._abi = json.load(codecs.open(p2abi, 'r', 'utf-8-sig'))
            self._meta = json.load(codecs.open(metafile, 'r', 'utf-8-sig'))
            return self

  `def GetCodeTag(self, fullname) ‑> [, ]`

    Search for the abi session and the bin session from the meta source file from combined.json :param fullname: initial file name :return: abi code and the bin code

    Expand source code

        def GetCodeTag(self, fullname) -> [str, str]:
            """
            Search for the abi session and the bin session from the meta source file
            from combined.json
            :param fullname: initial file name
            :return: abi code and the bin code
            """
            return self.combined_data["contracts"][fullname]["abi"], self.combined_data["contracts"][fullname]["bin"]

  `def GetCombinedFile(self) ‑> SolWeb3Tool`
    Expand source code

        def GetCombinedFile(self) -> "SolWeb3Tool":
            pathc = os.path.join(self.WORKSPACE_PATH, self.OUTPUT_BUILD, "combined.json")
            try:
                pathcli = codecs.open(pathc, 'r', 'utf-8-sig')
                self.combined_data = json.load(pathcli)
            except Exception as e:
                print("Problems from loading items from the file: ", e)
            return self

  `def GetMetaCompilerVer(self, full: bool = False) ‑> dict`
    Expand source code

        def GetMetaCompilerVer(self, full: bool = False) -> dict:
            if "compiler" not in self._meta:
                print("key compiler is not found")
                return dict()
            if "version" not in self._meta["compiler"]:
                print("key version is not found")
                return dict()

            return self._meta["compiler"]["version"]

  `def GetMetaSettings(self) ‑> dict`
    Expand source code

        def GetMetaSettings(self) -> dict:
            if "settings" not in self._meta:
                print("key settings is not found")
                return dict()

            return self._meta["settings"]

  `def GetMetadata(self) ‑> dict`
    Expand source code

        def GetMetadata(self) -> dict:
            return self._meta

  `def GetSourceFileRead(self, file_name: str) ‑> str`
    Expand source code

        def GetSourceFileRead(self, file_name: str) -> str:
            asfile = os.path.join(self.WORKSPACE_PATH, file_name)
            return codecs.open(asfile, 'r', 'utf-8-sig').read()

  `def StoreTxResult(self, tx_result_data: , filepath: str) ‑> NoneType`

    Having the result of the transaction data to be stored in an external JSON file. :param tx_result_data: input data :param filepath: the file name path :return: nothing to return

    Expand source code

        def StoreTxResult(self, tx_result_data: any, filepath: str) -> None:
            """
            Having the result of the transaction data to be stored in an external JSON file.
            :param tx_result_data: input data
            :param filepath: the file name path
            :return: nothing to return
            """
            predump = toDict(tx_result_data)
            writeFile(json.dumps(predump, ensure_ascii=False), filepath)

  `def byClassName(self, path: str, classname: str) ‑> str`
    Expand source code

        def byClassName(self, path: str, classname: str) -> str:
            # generating the string with path and class name
            return "{prefix}:{name}".format(prefix=path, name=classname)

  `def setBasePath(self, path: str) ‑> SolWeb3Tool`
    Expand source code

        def setBasePath(self, path: str) -> "SolWeb3Tool":
            self.WORKSPACE_PATH = path
            return self

  `def setBuildNameSpace(self, path: str) ‑> SolWeb3Tool`
    Expand source code

        def setBuildNameSpace(self, path: str) -> "SolWeb3Tool":
            self.OUTPUT_BUILD = path
            return self