Пример #1
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':
                bytes.fromhex(MinterHelper.prefix_remove(self.pub_key)),
                'reward_address':
                bytes.fromhex(MinterHelper.prefix_remove(self.reward_address)),
                'owner_address':
                bytes.fromhex(MinterHelper.prefix_remove(self.owner_address))
            }
        })

        return struct
Пример #2
0
    def _structure_from_instance(self):
        """ Override parent method. """

        struct = super()._structure_from_instance()

        struct.update({
            'type': self.TYPE,
            'data': {
                'address':
                bytes.fromhex(MinterHelper.prefix_remove(self.address)),
                'pub_key':
                bytes.fromhex(MinterHelper.prefix_remove(self.pub_key)),
                'commission': '' if self.commission == 0 else self.commission,
                'coin': int(self.coin),
                'stake': MinterHelper.to_pip(self.stake)
            }
        })

        return struct
Пример #3
0
    def get_address_from_public_key(cls, public_key):
        """
        Args:
            public_key (str)
        Returns:
            str
        """
        # Create keccak hash
        _keccak = MinterHelper.keccak_hash(
            bytes.fromhex(MinterHelper.prefix_remove(public_key)))

        return MinterHelper.prefix_add(_keccak[-40:], PREFIX_ADDR)
Пример #4
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 = [
            bytes.fromhex(
                MinterHelper.prefix_remove(tx.signature_data['from_mx'])), []
        ]
        for item in tx.signature_data['signatures']:
            # Create raw signature (values as integers)
            raw = [item['v'], int(item['r'], 16), 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
Пример #5
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': bytes.fromhex(MinterHelper.prefix_remove(self.check)),
                'proof': bytes.fromhex(self.proof)
            }
        })

        return struct
Пример #6
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': int(self.coin),
                'to': bytes.fromhex(MinterHelper.prefix_remove(self.to)),
                'value': MinterHelper.to_pip(self.value)
            }
        })

        return struct
Пример #7
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': []}})

        # Populate multi data from each single tx.
        for item in self.txs:
            struct['data']['txs'].append([
                int(item['coin']),
                bytes.fromhex(MinterHelper.prefix_remove(item['to'])),
                MinterHelper.to_pip(item['value'])
            ])

        return struct
Пример #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': {
                'pub_key':
                bytes.fromhex(MinterHelper.prefix_remove(self.pub_key)),
                'coin': MinterHelper.encode_coin_name(self.coin),
                'stake': MinterHelper.to_pip(self.stake)
            }
        })

        return struct
Пример #9
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 = MinterHelper.prefix_remove(rawcheck)
        rawcheck = bytes.fromhex(rawcheck)
        decoded = rlp.decode(rawcheck)

        # Create MinterCheck instance
        kwargs = {
            'nonce': int(decoded[0].decode()),
            'chain_id': int.from_bytes(decoded[1], 'big'),
            'due_block': int.from_bytes(decoded[2], 'big'),
            'coin': MinterHelper.decode_coin_name(decoded[3]),
            'value': MinterHelper.to_bip(int.from_bytes(decoded[4], 'big')),
            'gas_coin': MinterHelper.decode_coin_name(decoded[5]),
            'lock': decoded[6].hex(),
            'signature': {
                'v': int.from_bytes(decoded[7], 'big'),
                'r': decoded[8].hex(),
                's': decoded[9].hex()
            }
        }
        check = MinterCheck(**kwargs)

        # Recover owner address
        msg_hash = cls.__hash(data=[
            int(str(check.nonce).encode().hex(), 16), check.chain_id,
            check.due_block,
            MinterHelper.encode_coin_name(check.coin),
            MinterHelper.to_pip(check.value),
            MinterHelper.encode_coin_name(check.gas_coin),
            bytes.fromhex(check.lock)
        ])
        public_key = ECDSA.recover(msg_hash, tuple(check.signature.values()))
        public_key = MinterHelper.prefix_add(public_key, PREFIX_PUBKEY)

        check.owner = MinterWallet.get_address_from_public_key(public_key)

        return check
Пример #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': {
                'threshold':
                self.threshold if self.threshold else '',
                'weights': [w if w else '' for w in self.weights],
                'addresses': [
                    bytes.fromhex(MinterHelper.prefix_remove(address))
                    for address in self.addresses
                ]
            }
        })

        return struct
Пример #11
0
    def proof(cls, address, passphrase=''):
        """
        Create proof
        Args:
            address (str)
            passphrase (str)
        Returns:
            str
        """

        # Get address hash
        address = MinterHelper.prefix_remove(address)
        address = bytes.fromhex(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 cls.__lockfromsignature(signature).hex()
Пример #12
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 with
            signature (string|list[string]): signature to sign 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
            if private_key:
                signature_data = self.generate_signature(private_key)
            else:
                signature_data = signature
            signature_data = self.decode_signature(signature_data)
        else:
            # Add multisig address to signature
            signature_data = [
                bytes.fromhex(MinterHelper.prefix_remove(ms_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)