Esempio n. 1
0
    def can_register(self):
        # 1. The master piece needs to be registered
        # 2. The number of editions needs to be registered
        # 3. The edition_number should not have been registered yet
        # 4. TODO The root address owns the piece
        #    right now we cannot do this because we only receive the leaf address
        #    when registering an edition
        chain = BlockchainSpider.chain(self._tree, 0)

        # edition 0 should only have two transactions: REGISTER and EDITIONS
        if len(chain) == 0:
            self.reason = 'Master edition not yet registered'
            return False

        chain = BlockchainSpider.strip_loan(chain)
        number_editions = chain[0]['number_editions']
        if number_editions == 0:
            self.reason = 'Number of editions not yet registered'
            return False

        if self.edition_number > number_editions:
            self.reason = 'You can only register {} editions. You are trying to register edition {}'.format(number_editions, self.edition_number)
            return False

        if self.edition_number in self._tree:
            self.reason = 'Edition number {} is already registerd in the blockchain'. format(self.edition_number)
            return False

        return True
Esempio n. 2
0
    def can_register(self):
        # 1. The master piece needs to be registered
        # 2. The number of editions needs to be registered
        # 3. The edition_number should not have been registered yet
        # 4. TODO The root address owns the piece
        #    right now we cannot do this because we only receive the leaf address
        #    when registering an edition
        chain = BlockchainSpider.chain(self._tree, 0)

        # edition 0 should only have two transactions: REGISTER and EDITIONS
        if len(chain) == 0:
            self.reason = 'Master edition not yet registered'
            return False

        chain = BlockchainSpider.strip_loan(chain)
        number_editions = chain[0]['number_editions']
        if number_editions == 0:
            self.reason = 'Number of editions not yet registered'
            return False

        if self.edition_number > number_editions:
            self.reason = 'You can only register {} editions. You are trying to register edition {}'.format(
                number_editions, self.edition_number)
            return False

        if self.edition_number in self._tree:
            self.reason = 'Edition number {} is already registerd in the blockchain'.format(
                self.edition_number)
            return False

        return True
Esempio n. 3
0
    def can_transfer(self):
        # 1. The address needs to own the edition
        chain = BlockchainSpider.chain(self._tree, self.edition_number)

        if len(chain) == 0:
            self.reason = 'The edition number {} does not exist in the blockchain'.format(self.edition_number)
            return False

        chain = BlockchainSpider.strip_loan(chain)
        to_address = chain[-1]['to_address']
        if to_address != self.address:
            self.reason = 'Address {} does not own the edition number {}'.format(self.address, self.edition_number)
            return False

        return True
Esempio n. 4
0
    def can_editions(self):
        # in order to register the number of editions:
        # 1. There needs to a least one transaction for the piece_address (the registration of the master edition)
        # 2. a piece with address piece_address needs to be registered with ASCRIBESPOOL01REGISTER0 (master edition)
        # 3. the number of editions should have not been set yet (no tx with verb ASCRIBESPOOLEDITIONS)
        chain = BlockchainSpider.chain(self._tree, 0)

        if len(chain) == 0:
            self.reason = 'Master edition not yet registered'
            return False

        number_editions = chain[0]['number_editions']
        if number_editions != 0:
            self.reason = 'Number of editions was already registered for this piece'
            return False

        return True
Esempio n. 5
0
    def can_transfer(self):
        # 1. The address needs to own the edition
        chain = BlockchainSpider.chain(self._tree, self.edition_number)

        if len(chain) == 0:
            self.reason = 'The edition number {} does not exist in the blockchain'.format(
                self.edition_number)
            return False

        chain = BlockchainSpider.strip_loan(chain)
        to_address = chain[-1]['to_address']
        if to_address != self.address:
            self.reason = 'Address {} does not own the edition number {}'.format(
                self.address, self.edition_number)
            return False

        return True
Esempio n. 6
0
    def can_editions(self):
        # in order to register the number of editions:
        # 1. There needs to a least one transaction for the piece_address (the registration of the master edition)
        # 2. a piece with address piece_address needs to be registered with ASCRIBESPOOL01REGISTER0 (master edition)
        # 3. the number of editions should have not been set yet (no tx with verb ASCRIBESPOOLEDITIONS)
        chain = BlockchainSpider.chain(self._tree, 0)

        if len(chain) == 0:
            self.reason = 'Master edition not yet registered'
            return False

        number_editions = chain[0]['number_editions']
        if number_editions != 0:
            self.reason = 'Number of editions was already registered for this piece'
            return False

        return True
Esempio n. 7
0
    def can_unconsign(self):
        # 1. If the last transaction is a consign of the edition to the user
        chain = BlockchainSpider.chain(self._tree, self.edition_number)
        if len(chain) == 0:
            self.reason = 'Master edition not yet registered'
            return False

        chain = BlockchainSpider.strip_loan(chain)
        action = chain[-1]['action']
        piece_address = chain[-1]['piece_address']
        edition_number = chain[-1]['edition_number']
        to_address = chain[-1]['to_address']

        if action != 'CONSIGN' or piece_address != self.piece_address or edition_number != self.edition_number or to_address != self.address:
            self.reason = 'Edition number {} is not consigned to {}'.format(self.edition_number, self.address)
            return False

        return True
Esempio n. 8
0
    def can_unconsign(self):
        # 1. If the last transaction is a consign of the edition to the user
        chain = BlockchainSpider.chain(self._tree, self.edition_number)
        if len(chain) == 0:
            self.reason = 'Master edition not yet registered'
            return False

        chain = BlockchainSpider.strip_loan(chain)
        action = chain[-1]['action']
        piece_address = chain[-1]['piece_address']
        edition_number = chain[-1]['edition_number']
        to_address = chain[-1]['to_address']

        if action != 'CONSIGN' or piece_address != self.piece_address or edition_number != self.edition_number or to_address != self.address:
            self.reason = 'Edition number {} is not consigned to {}'.format(
                self.edition_number, self.address)
            return False

        return True
Esempio n. 9
0
    def wrapper(*args, **kwargs):
        sync = kwargs.get('sync', False)
        ownsership = kwargs.get('ownership', False)
        name = f.__name__
        testnet = args[0].testnet
        t = args[0]._t
        from_address = args[1][1]
        to_address = args[2]
        password = args[4]      # TODO remove, as it is not used
        # a piece has no edition number
        if name not in ['register_piece', 'consigned_registration']:
            edition_number = args[5]
        hash = ''
        if name not in ['refill', 'refill_main_wallet']:
            hash = args[3][0]

        # check ownership
        if ownsership:
            if name == 'register' and edition_number == 0:
                ow = Ownership(to_address, hash, edition_number, testnet=testnet)
                if not ow.can_register_master:
                    raise OwnershipError(ow.reason)
            elif name == 'register' and edition_number != 0:
                ow = Ownership(to_address, hash, edition_number, testnet=testnet)
                if not ow.can_register:
                    raise OwnershipError(ow.reason)
            elif name == 'editions':
                ow = Ownership(to_address, hash, edition_number, testnet=testnet)
                if not ow.can_editions:
                    raise OwnershipError(ow.reason)
            elif name == 'transfer' or name == 'consign' or name == 'loan':
                ow = Ownership(from_address, hash, edition_number, testnet=testnet)
                if not ow.can_transfer:
                    raise OwnershipError(ow.reason)
            elif name == 'unconsign':
                ow = Ownership(from_address, hash, edition_number, testnet=testnet)
                if not ow.can_unconsign:
                    raise OwnershipError(ow.reason)

                # check the to address
                chain = BlockchainSpider.chain(ow._tree, edition_number)
                chain_from_address = chain[-1]['from_address']
                if chain_from_address != to_address:
                    raise OwnershipError('You can only unconsign to {}'.format(chain_from_address))

        # do a synchronous transaction
        if sync:
            txid = f(*args, **kwargs)
            # lets give it some time for the transaction to reach the network
            confirmations = 0
            timeout = TIMEOUT
            while not confirmations:
                # lets do a simple exponential backoff. Transactions may take some time to be picked up by some
                # services
                try:
                    confirmations = t.get(txid).get('confirmations', 0)
                    timeout = TIMEOUT
                except Exception as e:
                    if e.message.find('code: 404') != -1:
                        timeout *= 2
                        if timeout > MAX_TIMEOUT:
                            raise
                    else:
                        raise
                time.sleep(timeout)
            return txid
        else:
            return f(*args, **kwargs)
Esempio n. 10
0
    def wrapper(*args, **kwargs):
        sync = kwargs.get('sync', False)
        ownsership = kwargs.get('ownership', False)
        name = f.__name__
        testnet = args[0].testnet
        t = args[0]._t
        from_address = args[1][1]
        to_address = args[2]
        password = args[4]
        # a piece has no edition number
        if name not in ['register_piece', 'consigned_registration']:
            edition_number = args[5]
        hash = ''
        if name not in ['refill', 'refill_main_wallet']:
            hash = args[3][0]

        # check ownership
        if ownsership:
            if name == 'register' and edition_number == 0:
                ow = Ownership(to_address, hash, edition_number, testnet=testnet)
                if not ow.can_register_master:
                    raise OwnershipError(ow.reason)
            elif name == 'register' and edition_number != 0:
                ow = Ownership(to_address, hash, edition_number, testnet=testnet)
                if not ow.can_register:
                    raise OwnershipError(ow.reason)
            elif name == 'editions':
                ow = Ownership(to_address, hash, edition_number, testnet=testnet)
                if not ow.can_editions:
                    raise OwnershipError(ow.reason)
            elif name == 'transfer' or name == 'consign' or name == 'loan':
                ow = Ownership(from_address, hash, edition_number, testnet=testnet)
                if not ow.can_transfer:
                    raise OwnershipError(ow.reason)
            elif name == 'unconsign':
                ow = Ownership(from_address, hash, edition_number, testnet=testnet)
                if not ow.can_unconsign:
                    raise OwnershipError(ow.reason)

                # check the to address
                chain = BlockchainSpider.chain(ow._tree, edition_number)
                chain_from_address = chain[-1]['from_address']
                if chain_from_address != to_address:
                    raise OwnershipError('You can only unconsign to {}'.format(chain_from_address))

        # do a synchronous transaction
        if sync:
            txid = f(*args, **kwargs)
            # lets give it some time for the transaction to reach the network
            confirmations = 0
            timeout = TIMEOUT
            while not confirmations:
                # lets do a simple exponential backoff. Transactions may take some time to be picked up by some
                # services
                try:
                    confirmations = t.get(txid).get('confirmations', 0)
                    timeout = TIMEOUT
                except Exception as e:
                    if e.message.find('code: 404') != -1:
                        timeout *= 2
                        if timeout > MAX_TIMEOUT:
                            raise
                    else:
                        raise
                time.sleep(timeout)
            return txid
        else:
            return f(*args, **kwargs)