Source code for solidbyte.compile.artifacts

import json
from typing import Union, Optional, Any, Dict, Set
from pathlib import Path
from attrdict import AttrDict
from ..common.utils import to_path, to_path_or_cwd
from ..common.exceptions import SolidbyteException
from ..common.logging import getLogger

log = getLogger(__name__)

# Typing
PS = Union[Path, str]

# Module defs
ARTIFACT_CACHE: Set[Any] = set()


[docs]class CompiledContract: """ A representation of a compiled contract. Attributes: - :py:attr:`name` (:code:`str`) - The name of the contract - :py:attr:`artifact_path` (:class:`pathlib.Path`) - The Path to the contract's artifact directory - :py:attr:`paths` (:class:`attrdict.AttrDict`) - Paths to eact artifact file - :py:attr:`abi` (:code:`dict`) - A Python dict of the contract's ABI - :py:attr:`bytecode` (:code:`str`) - The contract's compiled bytecode """
[docs] def __init__(self, name: str, artifact_path: PS) -> None: self.name = name self.artifact_path: PS = to_path(artifact_path) self.paths: AttrDict = AttrDict({ 'abi': self.artifact_path.joinpath('{}.abi'.format(self.name)), 'bytecode': self.artifact_path.joinpath('{}.bin'.format(self.name)), }) self.abi: Optional[Dict] = None self.bytecode: Optional[str] = None if not self._load_artifacts(): log.warning("Loading of {} artifacts failed.".format(self.name))
def __getitem__(self, key: str) -> Optional[Any]: """ Mostly for backwards compat, but allow this to be treated like a dict """ if not hasattr(self, key): raise KeyError("Key {} not found".format(key)) return getattr(self, key) def _load_artifacts(self) -> bool: """ Load the artifact files """ # Load the bytecode with self.paths.bytecode.open() as _file: log.debug("Reading file {}...".format(self.paths.bytecode)) self.bytecode = _file.read() # Load the ABI with self.paths.abi.open() as _file: log.debug("Reading file {}...".format(self.paths.abi)) abi_str = _file.read() self.abi = json.loads(abi_str) return bool(self.abi or self.bytecode)
[docs]def available_contract_names(project_dir: PS) -> Set[str]: """ Return the names of all compiled contracts """ project_dir = to_path_or_cwd(project_dir) builddir = project_dir.joinpath('build') if not builddir.is_dir(): raise SolidbyteException("My word. The build directory appears to be missing.") c_names = set() for d in builddir.iterdir(): if d.is_dir() and ( d.joinpath('{}.abi'.format(d.name)).is_file() or d.joinpath('{}.bin'.format(d.name)).is_file() ): c_names.add(d.name) return c_names
[docs]def contract_artifacts(name: str, project_dir: PS = None) -> CompiledContract: """ Return a :class:`solidbyte.compile.artifacts.CompiledContract` object with the artifacts for a contract """ project_dir = to_path_or_cwd(project_dir) builddir = project_dir.joinpath('build') artifact_path = builddir.joinpath(name) cc = CompiledContract(name=name, artifact_path=artifact_path) return cc
[docs]def artifacts(project_dir: PS) -> Set[CompiledContract]: """ Get an :class:`solidbyte.compile.artifacts.CompiledContract` object for all compiled contracts """ project_dir = to_path_or_cwd(project_dir) contracts = available_contract_names(project_dir) artifacts = set() for contract in contracts: artifacts.add(contract_artifacts(contract, project_dir)) return artifacts