Skip to content
Snippets Groups Projects
account.py 8.27 KiB
Newer Older
inso's avatar
inso committed
'''
Created on 1 févr. 2014

@author: inso
'''

from ucoinpy import PROTOCOL_VERSION
from ucoinpy.api import bma
from ucoinpy.api.bma import ConnectionHandler
from ucoinpy.documents.peer import Peer
inso's avatar
inso committed
from ucoinpy.documents.certification import SelfCertification, Certification
inso's avatar
inso committed
from ucoinpy.documents.membership import Membership
from ucoinpy.key import SigningKey
inso's avatar
inso committed
from ..tools.exceptions import PersonNotFoundError
import logging
inso's avatar
inso committed
import time
from .wallet import Wallet
from .community import Community
from .person import Person
inso's avatar
inso committed

class Account(object):
inso's avatar
inso committed
    '''
inso's avatar
inso committed
    An account is specific to a key.
    Each account has only one key, and a key can
    be locally referenced by only one account.
inso's avatar
inso committed
    '''
    def __init__(self, salt, pubkey, name, communities, wallets, contacts):
inso's avatar
inso committed
        '''
        Constructor
        '''
        self.salt = salt
        self.pubkey = pubkey
        self.name = name
        self.communities = communities
        self.wallets = wallets
inso's avatar
inso committed
        self.contacts = contacts
inso's avatar
inso committed
    def create(cls, name, communities, wallets, confpath):
        '''
        Constructor
        '''
inso's avatar
inso committed
        account = cls(None, None, name, communities, wallets, [])
        return account

    @classmethod
        salt = json_data['salt']
        name = json_data['name']
inso's avatar
inso committed
        contacts = []

        for contact_data in json_data['contacts']:
            contacts.append(Person.from_json(contact_data))
        wallets = []
        for data in json_data['wallets']:
            wallets.append(Wallet.load(data))

        communities = []
        for data in json_data['communities']:
            communities.append(Community.load(data))
        account = cls(salt, pubkey, name, communities, wallets, contacts)
        return account
inso's avatar
inso committed

inso's avatar
inso committed
    def __eq__(self, other):
        if other is not None:
            return other.pubkey == self.pubkey
inso's avatar
inso committed
        else:
            return False

    def check_password(self, password):
        key = SigningKey(self.salt, password)
        return (key.pubkey == self.pubkey)

    def add_contact(self, person):
        same_contact = [contact for contact in self.contacts if person.pubkey == contact.pubkey]
        if len(same_contact) == 0:
            print("add contact")
            self.contacts.append(person)
            return True
        return False
    def add_community(self, server, port):
inso's avatar
inso committed
        logging.debug("Adding a community")
        current = bma.blockchain.Current(ConnectionHandler(server, port))
inso's avatar
inso committed
        block_data = current.get()
        currency = block_data['currency']
        logging.debug("Currency : {0}".format(currency))

        peering = bma.network.Peering(ConnectionHandler(server, port))
        peer_data = peering.get()
        peer = Peer.from_signed_raw("{0}{1}\n".format(peer_data['raw'],
                                                      peer_data['signature']))

        community = Community.create(currency, peer)
        self.communities.append(community)
inso's avatar
inso committed
        return community

inso's avatar
inso committed
    def set_walletpool_size(self, size, password):
        logging.debug("Defining wallet pool size")
        if len(self.wallets) < size:
            for i in range(len(self.wallets), size):
                wallet = Wallet.create(i, self.salt, password, "Wallet {0}".format(i))
                self.wallets.append(wallet)
        else:
            self.wallets = self.wallets[:size]
    def certify(self, password, community, pubkey):
        certified = Person.lookup(pubkey, community)
        block = community.get_block()
        block_hash = hashlib.sha1(block.signed_raw().encode("ascii")).hexdigest().upper()

        certification = Certification(PROTOCOL_VERSION, community.currency,
                                      self.pubkey, certified.pubkey,
                                      block_hash, block.number, None)

        selfcert = certified.selfcert(community)
        logging.debug("SelfCertification : {0}".format(selfcert.raw()))

        key = SigningKey(self.salt, password)
inso's avatar
inso committed
        certification.sign(selfcert, [key])
        signed_cert = certification.signed_raw(selfcert)
        logging.debug("Certification : {0}".format(signed_cert))

        data = {'pubkey': certified.pubkey,
                        'self_': selfcert.signed_raw(),
                        'other': "{0}\n".format(certification.inline())}
        logging.debug("Posted data : {0}".format(data))
inso's avatar
inso committed
        community.broadcast(bma.wot.Add, {}, data)
    def sources(self, community):
        sources = []
        for w in self.wallets:
            for s in w.sources(community):
                sources.append(s)
        return sources

    def transactions_received(self, community):
inso's avatar
inso committed
        received = []
        for w in self.wallets:
            for t in w.transactions_received(community):
inso's avatar
inso committed
                # Lets remove transactions from our own wallets
                pubkeys = [wallet.pubkey for wallet in self.wallets]
                if t.issuers[0] not in pubkeys:
                    received.append(t)
inso's avatar
inso committed
        return received

    def transactions_sent(self, community):
inso's avatar
inso committed
        sent = []
        for w in self.wallets:
            for t in w.transactions_sent(community):
inso's avatar
inso committed
                # Lets remove transactions to our own wallets
                pubkeys = [wallet.pubkey for wallet in self.wallets]
                outputs = [o for o in t.outputs if o.pubkey not in pubkeys]
                if len(outputs) > 0:
                    sent.append(t)
inso's avatar
inso committed
        return sent

    def transactions_awaiting(self, community):
        awaiting = []
        for w in self.wallets:
            for t in w.transactions_awaiting(community):
                # Lets remove transactions to our own wallets
                pubkeys = [wallet.pubkey for wallet in self.wallets]
                outputs = [o for o in t.outputs if o.pubkey not in pubkeys]
                if len(outputs) > 0:
                    awaiting.append(t)
        return awaiting

    def member_of(self, community):
        pubkeys = community.members_pubkeys()
        if self.pubkey not in pubkeys:
            logging.debug("{0} not found in members : {1}".format(self.pubkey,
                                                                  pubkeys))
            return False
        return True

inso's avatar
inso committed
    def send_pubkey(self, password, community):
        selfcert = SelfCertification(PROTOCOL_VERSION,
                                     community.currency,
                                     self.pubkey,
                                     int(time.time()),
                                     self.name,
                                     None)
        key = SigningKey(self.salt, password)
        selfcert.sign([key])
        logging.debug("Key publish : {0}".format(selfcert.signed_raw()))
inso's avatar
inso committed
        community.broadcast(bma.wot.Add, {}, {'pubkey': self.pubkey,
inso's avatar
inso committed
                                    'self_': selfcert.signed_raw(),
                                    'other': []})
inso's avatar
inso committed
    def send_membership(self, password, community, type):
        self_ = Person.lookup(self.pubkey, community)
        selfcert = self_.selfcert(community)
inso's avatar
inso committed
        block = community.get_block()
        block_hash = hashlib.sha1(block.signed_raw().encode("ascii")).hexdigest().upper()
        membership = Membership(PROTOCOL_VERSION, community.currency,
                          selfcert.pubkey, block.number,
                          block_hash, type, selfcert.uid,
                          selfcert.timestamp, None)
        key = SigningKey(self.salt, password)
inso's avatar
inso committed
        membership.sign([key])
inso's avatar
inso committed
        logging.debug("Membership : {0}".format(membership.signed_raw()))
inso's avatar
inso committed
        community.broadcast(bma.blockchain.Membership, {},
inso's avatar
inso committed
                       {'membership': membership.signed_raw()})
inso's avatar
inso committed
    def jsonify(self):
        data_communities = []
        for c in self.communities:
            data_communities.append(c.jsonify())
inso's avatar
inso committed

inso's avatar
inso committed
        data_wallets = []
        for w in self.wallets:
inso's avatar
inso committed
            data_wallets.append(w.jsonify())
inso's avatar
inso committed
        data_contacts = []
        for p in self.contacts:
            data_contacts.append(p.jsonify())
        data = {'name': self.name,
inso's avatar
inso committed
                'communities': data_communities,
                'wallets': data_wallets,
                'contacts': data_contacts}