[KMS-ETH]- Agents hold reference to the deployers they represent; Condense contract base classes with shared methods beween agents.

pull/195/head^2
Kieran Prasch 2018-03-07 11:22:59 -08:00
parent 38f5da13fc
commit 0fb07715c4
3 changed files with 131 additions and 10 deletions

View File

@ -1,10 +1,27 @@
import random
from enum import Enum
from typing import Generator, List
from nkms_eth.base import ContractAgent
from typing import List
from typing import Set, Generator
from nkms_eth.actors import PolicyAuthor
from nkms_eth.base import ContractAgent
from nkms_eth.deployers import MinerEscrowDeployer, PolicyManagerDeployer
from nkms_eth.deployers import NuCypherKMSTokenDeployer
class NuCypherKMSTokenAgent(ContractAgent):
__deployer = NuCypherKMSTokenDeployer
_contract_name = __deployer.contract_name
def registrar(self):
"""Retrieve all known addresses for this contract"""
all_known_address = self._blockchain._chain.registrar.get_contract_address(self._contract_name)
return all_known_address
def check_balance(self, address: str) -> int:
"""Get the balance of a token address"""
return self.call().balanceOf(address)
class MinerAgent(ContractAgent):
@ -16,7 +33,8 @@ class MinerAgent(ContractAgent):
for a duration measured in periods.
"""
_contract_name = MinerEscrowDeployer.contract_name
__deployer = MinerEscrowDeployer
_contract_name = __deployer.contract_name
class MinerInfoField(Enum):
MINERS_LENGTH = 0
@ -56,12 +74,12 @@ class MinerAgent(ContractAgent):
Generates all miner addresses via cumulative sum on-network.
"""
count = self.call().getMinerInfo(self.MinerInfoField.MINERS_LENGTH.value, self.null_addr, 0).encode('latin-1')
count = self.blockchain._chain.web3.toInt(count)
count = self._blockchain._chain.web3.toInt(count)
for index in range(count):
addr = self.call().getMinerInfo(self.MinerInfoField.MINER.value, self.null_addr, index).encode('latin-1')
yield self.blockchain._chain.web3.toChecksumAddress(addr)
yield self._blockchain._chain.web3.toChecksumAddress(addr)
def sample(self, quantity: int=10, additional_ursulas: float=1.7, attempts: int=5, duration: int=10) -> List[str]:
"""

100
nkms_eth/base.py Normal file
View File

@ -0,0 +1,100 @@
from abc import ABC, abstractmethod
from nkms_eth.blockchain import TheBlockchain
class Actor(ABC):
def __init__(self, address):
if isinstance(address, bytes):
address = address.hex()
self.address = address
def __repr__(self):
class_name = self.__class__.__name__
r = "{}(address='{}')"
r.format(class_name, self.address)
return r
class ContractDeployer(ABC):
__contract_name = None
class ContractDeploymentError(Exception):
pass
def __init__(self, blockchain):
self._armed = False
self.__contract = None
self._blockchain = blockchain
def __eq__(self, other):
return self.__contract.address == other.address
@property
def address(self) -> str:
return self.__contract.address
@property
def is_deployed(self) -> bool:
return bool(self.__contract is not None)
@property
@classmethod
def contract_name(cls) -> str:
return cls.__contract_name
def _verify_contract_deployment(self) -> None:
"""Raises ContractDeploymentError if the contract has not been armed and deployed."""
if not self.__contract:
class_name = self.__class__.__name__
message = '{} contract is not deployed. Arm, then deploy.'.format(class_name)
raise self.ContractDeploymentError(message)
return None
def arm(self) -> None:
self._armed = True
return None
@abstractmethod
def deploy(self) -> str:
raise NotImplementedError
@abstractmethod
def make_agent(self) -> 'ContractAgent':
raise NotImplementedError
# @classmethod
# def from_blockchain(cls, blockchain: TheBlockchain) -> 'ContractDeployer':
# """
# Returns the NuCypherKMSToken object,
# or raises UnknownContract if the contract has not been deployed.
# """
# contract = blockchain._chain.provider.get_contract(cls.contract_name)
# instance = cls(blockchain=blockchain)
# instance._contract = contract
# return instance
class ContractAgent(ABC):
__deployer = None
_contract_name = None
class ContractNotDeployed(Exception):
pass
def __init__(self, agent, *args, **kwargs):
contract = agent._blockchain._chain.provider.get_contract(agent._contract_name)
self._contract = contract
self._blockchain = agent._blockchain
def __repr__(self):
class_name = self.__class__.__name__
r = "{}(blockchain={}, contract={})"
return r.format(class_name, self._blockchain, self._contract)
def call(self):
return self._contract.call()
def transact(self, *args, **kwargs):
return self._contract.transact(*args, **kwargs)

View File

@ -6,12 +6,15 @@ Deploy contracts in tester.
A simple Python script to deploy contracts and then estimate gas for different methods.
"""
from nkms_eth.blockchain import TesterBlockchain
from nkms_eth.escrow import Escrow
from nkms_eth.token import NuCypherKMSToken
import os
from nkms_eth.agents import NuCypherKMSTokenAgent
from nkms_eth.escrow import Escrow
from nkms_eth.agents import NuCypherKMSTokenAgent
from nkms_eth.blockchain import TesterBlockchain
def main():
testerchain = TesterBlockchain()
chain, web3 = testerchain._chain, testerchain._chain.web3
creator, ursula1, ursula2, ursula3, alice1, *everyone_else = web3.eth.accounts