# Path: pyledger/server/contract.py
# class SimpleContract(BaseContract):
#     """
#     Contract that uses SimpleStatus for serialization.
# 
#     The goal of this class is to make a contact feel just like a Python class.
#     """
#     _status_class = SimpleStatus
# 
# def register_contract(contract, description=''):
#     """
#     Register a contract and make it
#     :param contract:
#     :param description:
#     :return:
#     """
#     global contract_registry
# 
#     if contract.__class__.__name__ in contract_registry:
#         raise ValueError('A contract with the same name already registered')
#     else:
#         contract_registry[contract.__class__.__name__] = contract
# 
#     db_contract = Contract()
#     db_contract.name = contract.__class__.__name__
#     db_contract.created = datetime.datetime.now()
#     db_contract.description = description
# 
#     first_status = Status()
#     first_status.contract = db_contract
#     first_status.when = datetime.datetime.now()
#     first_status.attributes = status(contract).dump()
#     # Genesis key is the name of the contract
#     first_status.key = contract.__class__.__name__.encode('utf-8')
# 
#     DB.session.add(db_contract)
#     DB.session.add(first_status)
#     DB.session.commit()
# 
# def methods(contract):
#     """
#     Obtain methods from the contract
# 
#     :param contract:
#     :return:
#     """
#     methods = {}
# 
#     for name, function in inspect.getmembers(contract,
#                                              predicate=inspect.ismethod):
#         if not name == '__init__':
#             methods[name] = function
# 
#     return methods
# 
# def api(contract):
#     api_spec = {}
#     contract_methods = methods(contract)
#     for method in contract_methods:
#         function_spec = {}
#         sig = inspect.signature(contract_methods[method])
#         for param in sig.parameters:
#             function_spec[param] = sig.parameters[param].annotation
# 
#         api_spec[method] = function_spec
# 
#     return api_spec
# 
# def signatures(contract):
#     contract_signatures = {}
#     contract_methods = methods(contract)
#     for k, method in contract_methods.items():
#         contract_signatures[k] = inspect.signature(method)
# 
#     return contract_signatures
# 
# def status(contract):
#     all_attributes = inspect.getmembers(
#         contract,
#         predicate=lambda a: not(inspect.isroutine(a)))
# 
#     attributes = {}
# 
#     for attribute in all_attributes:
#         if not attribute[0].startswith('_'):
#             attributes[attribute[0]] = attribute[1]
# 
#     return contract._status_class(**attributes)
# 
# Path: pyledger/server/status.py
# class BaseStatus(abc.ABC):
#     """
#     Status abstract class
#     """
#     @abc.abstractmethod
#     def dump(self):
#         pass
# 
#     @abc.abstractmethod
#     def load(self, dump: bytes):
#         pass
# 
#     @abc.abstractmethod
#     def to_dict(self):
#         pass


from inspect import Signature, Parameter
from pyledger.server.contract import SimpleContract, register_contract, \
    methods, api, signatures, status
from pyledger.server.status import BaseStatus
            if key in self.accounts:
                raise Exception('Account already exists')

            self.accounts[key] = 0.0
            return key

        def increment(self, key: str, quantity: float):
            if key not in self.accounts:
                raise Exception('Account not found')

            self.accounts[key] += quantity

        def transfer(self, source: str, dest: str, quantity: float):
            if source not in self.accounts:
                raise Exception('Source account not found')
            if dest not in self.accounts:
                raise Exception('Destination account not found')
            if self.accounts[source] < quantity:
                raise Exception('Not enough funds in source account')

            self.accounts[source] -= quantity
            self.accounts[dest] += quantity

        def balance(self, key: str):
            if key not in self.accounts:
                print(self.accounts)
                raise Exception('Account not found')

            return str(self.accounts[key])


# Path: pyledger/server/contract.py
# class SimpleContract(BaseContract):
#     """
#     Contract that uses SimpleStatus for serialization.
# 
#     The goal of this class is to make a contact feel just like a Python class.
#     """
#     _status_class = SimpleStatus
# 
# def register_contract(contract, description=''):
#     """
#     Register a contract and make it
#     :param contract:
#     :param description:
#     :return:
#     """
#     global contract_registry
# 
#     if contract.__class__.__name__ in contract_registry:
#         raise ValueError('A contract with the same name already registered')
#     else:
#         contract_registry[contract.__class__.__name__] = contract
# 
#     db_contract = Contract()
#     db_contract.name = contract.__class__.__name__
#     db_contract.created = datetime.datetime.now()
#     db_contract.description = description
# 
#     first_status = Status()
#     first_status.contract = db_contract
#     first_status.when = datetime.datetime.now()
#     first_status.attributes = status(contract).dump()
#     # Genesis key is the name of the contract
#     first_status.key = contract.__class__.__name__.encode('utf-8')
# 
#     DB.session.add(db_contract)
#     DB.session.add(first_status)
#     DB.session.commit()
# 
# def methods(contract):
#     """
#     Obtain methods from the contract
# 
#     :param contract:
#     :return:
#     """
#     methods = {}
# 
#     for name, function in inspect.getmembers(contract,
#                                              predicate=inspect.ismethod):
#         if not name == '__init__':
#             methods[name] = function
# 
#     return methods
# 
# def api(contract):
#     api_spec = {}
#     contract_methods = methods(contract)
#     for method in contract_methods:
#         function_spec = {}
#         sig = inspect.signature(contract_methods[method])
#         for param in sig.parameters:
#             function_spec[param] = sig.parameters[param].annotation
# 
#         api_spec[method] = function_spec
# 
#     return api_spec
# 
# def signatures(contract):
#     contract_signatures = {}
#     contract_methods = methods(contract)
#     for k, method in contract_methods.items():
#         contract_signatures[k] = inspect.signature(method)
# 
#     return contract_signatures
# 
# def status(contract):
#     all_attributes = inspect.getmembers(
#         contract,
#         predicate=lambda a: not(inspect.isroutine(a)))
# 
#     attributes = {}
# 
#     for attribute in all_attributes:
#         if not attribute[0].startswith('_'):
#             attributes[attribute[0]] = attribute[1]
# 
#     return contract._status_class(**attributes)
# 
# Path: pyledger/server/status.py
# class BaseStatus(abc.ABC):
#     """
#     Status abstract class
#     """
#     @abc.abstractmethod
#     def dump(self):
#         pass
# 
#     @abc.abstractmethod
#     def load(self, dump: bytes):
#         pass
# 
#     @abc.abstractmethod
#     def to_dict(self):
#         pass


# Path: tests/test_3_simple_contract.py
from inspect import Signature, Parameter
from pyledger.server.contract import SimpleContract, register_contract, \
    methods, api, signatures, status
from pyledger.server.status import BaseStatus

            if key in self.accounts:
                raise Exception('Account already exists')

            self.accounts[key] = 0.0
            return key

        def increment(self, key: str, quantity: float):
            if key not in self.accounts:
                raise Exception('Account not found')

            self.accounts[key] += quantity

        def transfer(self, source: str, dest: str, quantity: float):
            if source not in self.accounts:
                raise Exception('Source account not found')
            if dest not in self.accounts:
                raise Exception('Destination account not found')
            if self.accounts[source] < quantity:
                raise Exception('Not enough funds in source account')

            self.accounts[source] -= quantity
            self.accounts[dest] += quantity

        def balance(self, key: str):
            if key not in self.accounts:
                print(self.accounts)
                raise Exception('Account not found')

            return str(self.accounts[key])


    register_contract(DigitalCurrency())