Exemplo n.º 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': {
                'coin': int(self.coin),
                'to': bytes.fromhex(MinterHelper.prefix_remove(self.to)),
                'value': MinterHelper.to_pip(self.value)
            }
        })

        return struct
Exemplo n.º 2
0
    def sign(self, private_key):
        """
        Sign transaction.
        This method can be called only from instances of inherited classes.
        Args:
            private_key (string): private key
        Return:
            string
        """

        # Get structure populated with instance data
        tx = self._structure_from_instance()
        # Remove sgnature data, it's not needed before getting Keccak
        tx.pop('signature_data')

        # Encode tx data to RLP
        tx['data'] = rlp.encode(list(tx['data'].values()))

        # Encode all tx to RLP and create Keccak hash
        tx_rlp = rlp.encode(list(tx.values()))
        _keccak = MinterHelper.keccak_hash(tx_rlp)

        # Signature data
        tx['signature_data'] = rlp.encode(ECDSA.sign(_keccak, private_key))

        tx_rlp = rlp.encode(list(tx.values()))
        self.signed_tx = binascii.hexlify(tx_rlp).decode()
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 estimate_coin_buy(self, coin_to_sell, value_to_buy, coin_to_buy,
                          height=None, pip2bip=False):
        """
        Return estimate of buy coin transaction
        Args:
            coin_to_sell (string): coin name to sell
            value_to_buy (string): Amount of coins to buy in PIP.
                    Provide `value_to_buy` in PIP, if `pip2bip` False.
                    Provide `value_to_buy` in BIP, if `pip2bip` True.
            coin_to_buy (string): coin name to buy
            height (int): block height
            pip2bip (bool): Convert coin amounts to BIP (default is in PIP)
        """
        # Convert `value_to_buy` to PIP, if needed
        if pip2bip:
            value_to_buy = MinterHelper.to_pip(value_to_buy)

        # Get default response
        response = self._request(
            command='estimate_coin_buy',
            params={
                'coin_to_sell': coin_to_sell,
                'value_to_buy': value_to_buy,
                'coin_to_buy': coin_to_buy,
                'height': height
            }
        )

        # Convert response values from PIP to BIP, if needed
        if pip2bip:
            return self.__response_processor(
                data=response, funcs=[self.__pip_to_bip]
            )

        return response
Exemplo n.º 5
0
    def _structure_to_kwargs(cls, structure):
        """ Prepare decoded structure data to instance kwargs. """

        kwargs = super()._structure_to_kwargs(structure)

        # Convert data values to verbose.
        # Data will be passed as additional kwarg
        kwargs['data'].update({
            'check': MinterPrefix.CHECK + MinterHelper.bin2hex(kwargs['data']['check']),
            'proof': MinterHelper.bin2hex(kwargs['data']['proof'])
        })

        # Populate data key values as kwargs
        kwargs.update(kwargs['data'])

        return kwargs
Exemplo n.º 6
0
    def _structure_to_kwargs(cls, structure):
        """ Prepare decoded structure data to instance kwargs. """
        kwargs = super()._structure_to_kwargs(structure)

        # Convert data values to verbose.
        # Data will be passed as additional kwarg
        kwargs['data'].update({
            'pub_key': MinterPrefix.PUBLIC_KEY + MinterHelper.bin2hex(kwargs['data']['pub_key']),
            'coin': MinterConvertor.decode_coin_name(kwargs['data']['coin']),
            'stake': MinterConvertor.convert_value(value=MinterHelper.bin2int(kwargs['data']['stake']), to='bip')
        })

        # Populate data key values as kwargs
        kwargs.update(kwargs['data'])

        return kwargs
Exemplo n.º 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
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': {
                '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.º 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': {
                'coin_to_sell': int(self.coin_to_sell),
                'value_to_sell': MinterHelper.to_pip(self.value_to_sell),
                'coin_to_buy': int(self.coin_to_buy),
                'min_value_to_buy': MinterHelper.to_pip(self.min_value_to_buy)
            }
        })

        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':
                bytes.fromhex(MinterHelper.prefix_remove(self.pub_key)),
                'coin': MinterHelper.encode_coin_name(self.coin),
                'stake': MinterHelper.to_pip(self.stake)
            }
        })

        return struct
Exemplo n.º 11
0
    def sign(self, private_key):
        """
        Sign check
        Args:
            private_key (str)
        """
        # Prepare structure
        # It contains nonce, chain_id, due_block, coin, value, gas_coin,
        # lock, v, r, s.
        # lock, v, r, s appended later in code
        structure = [
            int(str(self.nonce).encode().hex(), 16), self.chain_id,
            self.due_block,
            MinterHelper.encode_coin_name(self.coin),
            MinterHelper.to_pip(self.value),
            MinterHelper.encode_coin_name(self.gas_coin)
        ]

        # Create msg hash
        msg_hash = self.__hash(structure)

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

        # Create lock from signature
        self.lock = self.__lockfromsignature(
            signature=ECDSA.sign(message=msg_hash, private_key=passphrase))

        # Re-create msg hash with adding lock to structure
        structure.append(self.lock)
        msg_hash = self.__hash(structure)

        # Re-create signature, add it to check attrs and to structure
        signature = ECDSA.sign(message=msg_hash, private_key=private_key)
        self.signature = {
            'v': signature[0],
            'r': format(signature[1], 'x'),
            's': format(signature[2], 'x')
        }
        structure += signature

        # Get RLP, which will be the check
        check = rlp.encode(structure).hex()

        return MinterHelper.prefix_add(check, PREFIX_CHECK)
Exemplo n.º 12
0
    def get_fee(self):
        """
        Get fee of transaction in PIP.
        Returns:
            int
        """
        # Commission for payload and service_data bytes
        payload_gas = (MinterHelper.bytes_len(self.payload) *
                       self.PAYLOAD_COMMISSION)
        service_data_gas = (MinterHelper.bytes_len(self.service_data) *
                            self.PAYLOAD_COMMISSION)

        # Total commission
        commission = self.COMMISSION + payload_gas + service_data_gas
        commission *= self.FEE_DEFAULT_MULTIPLIER

        return commission
Exemplo n.º 13
0
    def _structure_to_kwargs(cls, structure):
        """ Prepare decoded structure data to instance kwargs. """

        kwargs = super()._structure_to_kwargs(structure)

        # Convert data values to verbose.
        # Data will be passed as additional kwarg
        kwargs['data'].update({
            'pub_key': MinterPrefix.PUBLIC_KEY + MinterHelper.bin2hex(kwargs['data']['pub_key']),
            'reward_address': MinterPrefix.ADDRESS + MinterHelper.bin2hex(kwargs['data']['reward_address']),
            'owner_address': MinterPrefix.ADDRESS + MinterHelper.bin2hex(kwargs['data']['owner_address'])
        })

        # Populate data key values as kwargs
        kwargs.update(kwargs['data'])

        return kwargs
Exemplo n.º 14
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.º 15
0
    def _structure_from_instance(self):
        """ Override parent method. """

        struct = super()._structure_from_instance()

        struct.update({
            'type': self.TYPE,
            'data': {
                'name': self.name,
                'symbol': MinterHelper.encode_coin_name(self.symbol),
                'initial_amount': MinterHelper.to_pip(self.initial_amount),
                'initial_reserve': MinterHelper.to_pip(self.initial_reserve),
                'crr': '' if self.crr == 0 else self.crr,
                'max_supply': MinterHelper.to_pip(self.max_supply)
            }
        })

        return struct
Exemplo n.º 16
0
    def _structure_to_kwargs(cls, structure):
        """ Prepare decoded structure data to instance kwargs. """

        kwargs = super()._structure_to_kwargs(structure)

        # Convert data values to verbose.
        # Data will be passed as additional kwarg
        for index, item in enumerate(kwargs['data']['txs']):
            kwargs['data']['txs'][index] = {
                'coin': item[0],
                'to': MinterHelper.prefix_add(item[1].hex(), PREFIX_ADDR),
                'value': MinterHelper.to_bip(int.from_bytes(item[2], 'big'))
            }

        # Populate data key values as kwargs
        kwargs.update(kwargs['data'])

        return kwargs
Exemplo n.º 17
0
    def _structure_from_instance(self):
        """ Override parent method. """

        struct = super()._structure_from_instance()

        struct.update({
            'type': self.TYPE,
            'data': {
                'coin_to_buy': MinterHelper.encode_coin_name(self.coin_to_buy),
                'value_to_buy': MinterHelper.to_pip(self.value_to_buy),
                'coin_to_sell':
                MinterHelper.encode_coin_name(self.coin_to_sell),
                'max_value_to_sell':
                MinterHelper.to_pip(self.max_value_to_sell)
            }
        })

        return struct
Exemplo n.º 18
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
Exemplo n.º 19
0
    def _structure_to_kwargs(cls, structure):
        """ Prepare decoded structure data to instance kwargs. """

        kwargs = super()._structure_to_kwargs(structure)

        # Convert data values to verbose.
        # Data will be passed as additional kwarg
        for index, item in enumerate(kwargs['data']['txs']):
            kwargs['data']['txs'][index] = {
                'coin': MinterConvertor.decode_coin_name(item[0]),
                'to': MinterPrefix.ADDRESS + MinterHelper.bin2hex(item[1]),
                'value': MinterConvertor.convert_value(value=MinterHelper.bin2int(item[2]), to='bip')
            }

        # Populate data key values as kwargs
        kwargs.update(kwargs['data'])

        return kwargs
Exemplo n.º 20
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': int.from_bytes(decoded[3], 'big'),
            'value': MinterHelper.to_bip(int.from_bytes(decoded[4], 'big')),
            'gas_coin': int.from_bytes(decoded[5], 'big'),
            '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, check.coin,
            MinterHelper.to_pip(check.value), 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
Exemplo n.º 21
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
Exemplo n.º 22
0
    def get_fee(self):
        """
        Get fee of transaction in PIP.
        Returns:
            int
        """

        # Multiplied gas comission in PIP
        gas_price = MinterHelper.pybcmul(self.COMMISSION,
                                         self.FEE_DEFAULT_MULTIPLIER)

        # Comission for payload and service_data bytes
        comission = MinterHelper.pybcadd(
            MinterHelper.pybcmul(len(self.payload),
                                 self.FEE_DEFAULT_MULTIPLIER),
            MinterHelper.pybcmul(len(self.service_data),
                                 self.FEE_DEFAULT_MULTIPLIER))

        return int(MinterHelper.pybcadd(gas_price, comission))
Exemplo n.º 23
0
 def __hash(data):
     """
     Create service hash by RLP encoding and getting keccak hash from
     rlp result
     Args:
         data (list)
     Returns:
         hash (str)
     """
     return MinterHelper.keccak_hash(rlp.encode(data))
Exemplo n.º 24
0
    def _structure_to_kwargs(cls, structure):
        """
        Works with already populated structure and prepare **kwargs for
        creating new instance of tx.
        """

        structure.update(
            {'gas_coin': MinterHelper.decode_coin_name(structure['gas_coin'])})

        return structure
Exemplo n.º 25
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)
            },
            'signature_type': self.SIGNATURE_SINGLE_TYPE
        })

        return struct
Exemplo n.º 26
0
    def _structure_to_kwargs(cls, structure):
        """ Prepare decoded structure data to instance kwargs. """
        kwargs = super()._structure_to_kwargs(structure)

        # Convert data values to verbose.
        # Data will be passed as additional kwarg
        kwargs['data'].update({
            'pub_key':
            MinterHelper.prefix_add(kwargs['data']['pub_key'].hex(),
                                    PREFIX_PUBKEY),
            'coin':
            kwargs['data']['coin'],
            'stake':
            MinterHelper.to_bip(int.from_bytes(kwargs['data']['stake'], 'big'))
        })

        # Populate data key values as kwargs
        kwargs.update(kwargs['data'])

        return kwargs
Exemplo n.º 27
0
    def get_address_from_public_key(cls, public_key):
        """
        @param public_key|string
        @return: string - Wallet address with prefix
        """

        # Create keccak hash
        _keccak = MinterHelper.keccak_hash(
            binascii.unhexlify(public_key.replace(MinterPrefix.PUBLIC_KEY,
                                                  '')))

        return MinterPrefix.ADDRESS + _keccak[-40:]
Exemplo n.º 28
0
    def _structure_to_kwargs(cls, structure):
        """ Prepare decoded structure data to instance kwargs. """

        kwargs = super()._structure_to_kwargs(structure)

        # Convert data values to verbose.
        # Data will be passed as additional kwarg
        kwargs['data'].update({
            'coin_to_sell':
            MinterHelper.decode_coin_name(kwargs['data']['coin_to_sell']),
            'coin_to_buy':
            MinterHelper.decode_coin_name(kwargs['data']['coin_to_buy']),
            'min_value_to_buy':
            MinterHelper.to_bip(
                int.from_bytes(kwargs['data']['min_value_to_buy'], 'big'))
        })

        # Populate data key values as kwargs
        kwargs.update(kwargs['data'])

        return kwargs
Exemplo n.º 29
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)
                )
            }
        })

        return struct
Exemplo n.º 30
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)
                ),
                'commission': '' if self.commission == 0 else self.commission,
                'coin': MinterConvertor.encode_coin_name(self.coin),
                'stake': MinterConvertor.convert_value(value=self.stake, to='pip')
            }
        })

        return struct