Exemplo n.º 1
0
    def _structure_from_instance(self):
        """
        Override parent method.
        """

        struct = super()._structure_from_instance()

        struct.update({
            'type': self.TYPE,
            'data': {
                'address':
                MinterHelper.hex2bin(
                    MinterPrefix.remove_prefix(string=self.address,
                                               prefix=MinterPrefix.ADDRESS)),
                'pub_key':
                MinterHelper.hex2bin(
                    MinterPrefix.remove_prefix(
                        string=self.pub_key, prefix=MinterPrefix.PUBLIC_KEY)),
                'comission':
                '' if self.comission == 0 else self.comission,
                'coin':
                MinterConvertor.encode_coin_name(self.coin),
                'stake':
                MinterConvertor.convert_value(value=self.stake, to='pip')
            },
            'signature_type': self.SIGNATURE_SINGLE_TYPE
        })

        return struct
Exemplo n.º 2
0
    def _structure_from_instance(self):
        """
        Override parent method to add tx special data.
        """

        struct = super()._structure_from_instance()

        struct.update({
            'type': self.TYPE,
            'data': {
                'pub_key':
                MinterHelper.hex2bin(
                    MinterPrefix.remove_prefix(
                        string=self.pub_key, prefix=MinterPrefix.PUBLIC_KEY)),
                'reward_address':
                MinterHelper.hex2bin(
                    MinterPrefix.remove_prefix(string=self.reward_address,
                                               prefix=MinterPrefix.ADDRESS)),
                'owner_address':
                MinterHelper.hex2bin(
                    MinterPrefix.remove_prefix(string=self.owner_address,
                                               prefix=MinterPrefix.ADDRESS))
            },
            'signature_type': self.SIGNATURE_SINGLE_TYPE
        })

        return struct
Exemplo n.º 3
0
    def proof(cls, address, passphrase):
        """
        Create proof
        Args:
            address (str)
            passphrase (str)
        Returns:
            str
        """

        # Get address hash
        address = MinterPrefix.remove_prefix(
            string=address,
            prefix=MinterPrefix.ADDRESS
        )
        address = MinterHelper.hex2bin(address)
        address_hash = cls.__hash(data=[address])

        # Create SHA256 from passphrase
        sha = hashlib.sha256()
        sha.update(passphrase.encode())
        passphrase = sha.hexdigest()

        # Get signature
        signature = ECDSA.sign(message=address_hash, private_key=passphrase)

        return binascii.hexlify(cls.__lockfromsignature(signature)).decode()
Exemplo n.º 4
0
    def _structure_from_instance(self):
        """
        Override parent method to add tx special data.
        """

        struct = super()._structure_from_instance()

        struct.update({
            'type': self.TYPE,
            'data': {
                'txs': []
            },
            'signature_type': self.SIGNATURE_SINGLE_TYPE
        })

        # Populate multi data from each single tx.
        for item in self.txs:
            struct['data']['txs'].append([
                MinterConvertor.encode_coin_name(item['coin']),
                MinterHelper.hex2bin(
                    MinterPrefix.remove_prefix(string=item['to'],
                                               prefix=MinterPrefix.ADDRESS)),
                MinterConvertor.convert_value(value=item['value'], to='pip')
            ])

        return struct
Exemplo n.º 5
0
    def sign(self, private_key=None, signature=None, ms_address=None):
        """
        Sign transaction.
        This method can be called only from instances of inherited classes.
        Args:
            private_key (string|list[string]): private key to sign transaction with
            signature (string|list[string]): signature to sign transaction with
            ms_address (string): Multi signature address to sign tx by
        """
        # Check arguments validity
        if not private_key and not signature:
            raise Exception('Please, provide either `private_key(s)` or `signature(s)`')
        if not ms_address and private_key and type(private_key) is not str:
            raise Exception('Please, provide a single `private_key` or set `ms_address` argument for multisig tx')
        if not ms_address and signature and type(signature) is not str:
            raise Exception('Please, provide a single `signature` or set `ms_address` argument for multisig tx')

        # Set tx signature type
        self.signature_type = self.SIGNATURE_SINGLE_TYPE
        if ms_address:
            if type(private_key) is str:
                private_key = [private_key]
            if type(signature) is str:
                signature = [signature]
            self.signature_type = self.SIGNATURE_MULTI_TYPE

        # Get populated and rlp encoded tx structure
        tx_struct = self.generate_tx_rlp()

        # Signature data
        if self.signature_type == self.SIGNATURE_SINGLE_TYPE:
            # Only one of private_key or signature can be provided for single signature type tx
            if private_key and signature:
                raise Exception('Please, provide one of `private_key` or `signature` for single signature type tx')

            # Set signature_data
            signature_data = self.generate_signature(private_key) if private_key else signature
            signature_data = self.decode_signature(signature_data)
        else:
            # Add multisig address to signature
            signature_data = [
                MinterHelper.hex2bin(MinterPrefix.remove_prefix(string=ms_address, prefix=MinterPrefix.ADDRESS)),
                []
            ]

            # Sign by each private key and add to total signature data
            if private_key:
                for pk in private_key:
                    _signature = self.generate_signature(pk)
                    signature_data[1].append(self.decode_signature(_signature))

            # Sign by each signature and add to total signature data
            if signature:
                for _signature in signature:
                    signature_data[1].append(self.decode_signature(_signature))
        tx_struct['signature_data'] = rlp.encode(signature_data)

        self.signed_tx = self.generate_signed_tx(tx_struct)
Exemplo n.º 6
0
    def add_signature(cls, signed_tx, private_key):
        """
        Add signature to already signed tx. Method is available only for multisig txs
        Args:
            signed_tx (str): signed tx
            private_key (str): private key
        Returns:
            tx object
        """

        # Create tx instance from raw tx
        tx = cls.from_raw(signed_tx)

        # Check tx to be multi signature type
        if tx.signature_type != cls.SIGNATURE_MULTI_TYPE:
            raise Exception('Signature can be added only to tx with multi signature type')

        # Convert signature data from verbose dict to needed list of signatures
        signature_data = [
            MinterHelper.hex2bin(
                MinterPrefix.remove_prefix(string=tx.signature_data['from_mx'], prefix=MinterPrefix.ADDRESS)
            ),
            []
        ]
        for item in tx.signature_data['signatures']:
            # Create raw signature (values as integers)
            raw = [item['v']]
            raw.append(int(item['r'], 16))
            raw.append(int(item['s'], 16))
            # Append raw signature to total signature data
            signature_data[1].append(raw)

        # Get tx populated structure and keccak hash from this structure
        tx_struct = tx.generate_tx_rlp()

        # Create new signature and update signatures list and signatures attribute of tx
        signature = cls.decode_signature(signature=tx.generate_signature(private_key))
        signature_data[1].append(signature)
        tx.signature_data['signatures'].append({
            'v': signature[0],
            'r': format(signature[1], 'x'),
            's': format(signature[2], 'x')
        })

        # Update resulting struct signature data
        tx_struct['signature_data'] = rlp.encode(signature_data)

        # Generate new signed tx and update tx object attribute
        tx.signed_tx = cls.generate_signed_tx(tx_struct)

        return tx
Exemplo n.º 7
0
    def from_raw(cls, rawcheck):
        """
        Create check instance from raw check
        Args:
            rawcheck (str)
        Returns:
            MinterCheck
        """

        # Remove check prefix and RLP decode it
        rawcheck = MinterPrefix.remove_prefix(
            string=rawcheck,
            prefix=MinterPrefix.CHECK
        )
        rawcheck = binascii.unhexlify(rawcheck)
        decoded = rlp.decode(rawcheck)

        # Create MinterCheck instance
        kwargs = {
            'nonce': int(decoded[0].decode()),
            'chain_id': MinterHelper.bin2int(decoded[1]),
            'due_block': MinterHelper.bin2int(decoded[2]),
            'coin': MinterConvertor.decode_coin_name(decoded[3]),
            'value': MinterConvertor.convert_value(
                value=MinterHelper.bin2int(decoded[4]),
                to='bip'
            ),
            'lock': binascii.hexlify(decoded[5]).decode(),
            'signature': {
                'v': MinterHelper.bin2int(decoded[6]),
                'r': MinterHelper.bin2hex(decoded[7]),
                's': MinterHelper.bin2hex(decoded[8])
            }
        }
        check = MinterCheck(**kwargs)

        # Recover owner address
        msg_hash = cls.__hash(data=[
            int(binascii.hexlify(str(check.nonce).encode()), 16),
            check.chain_id,
            check.due_block,
            MinterConvertor.encode_coin_name(check.coin),
            MinterConvertor.convert_value(value=check.value, to='pip'),
            MinterHelper.hex2bin(check.lock)
        ])
        public_key = ECDSA.recover(msg_hash, list(check.signature.values()))
        public_key = MinterPrefix.PUBLIC_KEY + public_key

        check.owner = MinterWallet.get_address_from_public_key(public_key)

        return check
Exemplo n.º 8
0
    def _structure_from_instance(self):
        """ Override parent method to add tx special data. """

        struct = super()._structure_from_instance()

        struct.update({
            'type': self.TYPE,
            'data': {
                'check': MinterHelper.hex2bin(MinterPrefix.remove_prefix(self.check, MinterPrefix.CHECK)),
                'proof': MinterHelper.hex2bin(self.proof)
            }
        })

        return struct
Exemplo n.º 9
0
    def _structure_from_instance(self):
        """ Override parent method to add tx special data. """

        struct = super()._structure_from_instance()

        struct.update({
            'type': self.TYPE,
            'data': {
                'pub_key': MinterHelper.hex2bin(MinterPrefix.remove_prefix(self.pub_key, MinterPrefix.PUBLIC_KEY)),
                'coin': MinterConvertor.encode_coin_name(self.coin),
                'stake': MinterConvertor.convert_value(value=self.stake, to='pip')
            }
        })

        return struct
Exemplo n.º 10
0
    def _structure_from_instance(self):
        """ Override parent method to add tx special data. """

        struct = super()._structure_from_instance()

        struct.update({
            'type': self.TYPE,
            'data': {
                'pub_key': MinterHelper.hex2bin(
                    MinterPrefix.remove_prefix(string=self.pub_key, prefix=MinterPrefix.PUBLIC_KEY)
                )
            }
        })

        return struct
Exemplo n.º 11
0
    def _structure_from_instance(self):
        """ Override parent method to add tx special data. """

        struct = super()._structure_from_instance()

        struct.update({
            'type': self.TYPE,
            'data': {
                'coin': MinterConvertor.encode_coin_name(self.coin),
                'to': MinterHelper.hex2bin(MinterPrefix.remove_prefix(string=self.to, prefix=MinterPrefix.ADDRESS)),
                'value': MinterConvertor.convert_value(value=self.value, to='pip')
            }
        })

        return struct