Пример #1
0
def multisend(wallet_from, w_dict, gas_coin='BIP', payload=''):
    nonce = API.get_nonce(wallet_from['address'])
    tx = MinterMultiSendCoinTx(w_dict, nonce=nonce, gas_coin=gas_coin, payload=payload)
    tx.sign(wallet_from['private_key'])
    r = API.send_transaction(tx.signed_tx)
    print(f'Send TX response:\n{r}')
    return tx
Пример #2
0
def multisend(api, private_key, wallet, txs, gas_coin='BIP', payload=''):
    nonce = api.get_nonce(wallet)
    tx = MinterMultiSendCoinTx(txs,
                               nonce=nonce,
                               gas_coin=gas_coin,
                               payload=payload)
    tx.sign(private_key=private_key)
    r = api.send_transaction(tx.signed_tx)

    print(f'Multisend успешно отправлен.\n\nSend TX response:\n{r}')
    return tx
Пример #3
0
 def test_multisend_fee(self):
     tx = MinterMultiSendCoinTx(
         **{
             'nonce': 1,
             'chain_id': MinterTx.TESTNET_CHAIN_ID,
             'gas_coin': 'MNT',
             'txs': self.MULTISEND_RECIPIENTS
         })
     tx.sign(self.PRIVATE_KEY)
     actual_fee = tx.get_fee()
     self.assertEqual(self.EXPECTED_MULTISEND_FEE, actual_fee)
Пример #4
0
class TestMinterMultiSendCoinTx(unittest.TestCase):
    def setUp(self):
        self.FROM = 'Mx31e61a05adbd13c6b625262704bc305bf7725026'
        self.PRIVATE_KEY = '07bc17abdcee8b971bb8723e36fe9d2523306d5ab2d683631693238e0f9df142'
        self.SIGNED_TX = 'f8b30102018a4d4e54000000000000000db858f856f854e98a4d4e540000000000000094fe60014a6e9ac91618f5d1cab3fd58cded61ee9988016345785d8a0000e98a4d4e540000000000000094ddab6281766ad86497741ff91b6b48fe85012e3c8802c68af0bb140000808001b845f8431ca0b15dcf2e013df1a2aea02e36a17af266d8ee129cdcb3e881d15b70c9457e7571a0226af7bdaca9d42d6774c100b22e0c7ba4ec8dd664d17986318e905613013283'
        self.TX = MinterMultiSendCoinTx(
            **{
                'nonce':
                1,
                'chain_id':
                MinterTx.TESTNET_CHAIN_ID,
                'gas_coin':
                'MNT',
                'txs': [{
                    'coin': 'MNT',
                    'to': 'Mxfe60014a6e9ac91618f5d1cab3fd58cded61ee99',
                    'value': decimal.Decimal('0.1')
                }, {
                    'coin': 'MNT',
                    'to': 'Mxddab6281766ad86497741ff91b6b48fe85012e3c',
                    'value': decimal.Decimal('0.2')
                }]
            })

    def test_valid_tx(self):
        """
        Is tx instance of needed TX class.
        """

        self.assertIsInstance(self.TX, MinterMultiSendCoinTx)

    def test_sign_tx(self):
        """
        Sign transaction and check signed transaction
        """
        self.TX.sign(self.PRIVATE_KEY)

        self.assertEqual(self.TX.signed_tx, self.SIGNED_TX)

    def test_from_raw(self):
        tx = MinterTx.from_raw(raw_tx=self.SIGNED_TX)

        self.assertEqual(tx.from_mx, self.FROM)
        self.assertEqual(tx.txs, self.TX.txs)

    def test_sign_with_signature(self):
        self.TX.signature_type = MinterTx.SIGNATURE_SINGLE_TYPE
        signature = self.TX.generate_signature(self.PRIVATE_KEY)
        self.TX.sign(signature=signature)

        self.assertEqual(self.TX.signed_tx, self.SIGNED_TX)
Пример #5
0
def coin_multisend(private_key,
                   address_from,
                   multisend_list,
                   gas_coin='BIP',
                   payload=''):
    for send_rec in multisend_list:
        logger.info(
            f"Sending: {send_rec['value']} {send_rec['coin']} -> {send_rec['to']}"
        )
    if LOCAL and not LOCAL_REAL_TXS:
        return {}
    nonce = API.get_nonce(address_from)
    tx = MinterMultiSendCoinTx(multisend_list,
                               nonce=nonce,
                               gas_coin=gas_coin,
                               payload=payload)
    tx.sign(private_key)
    r = API.send_transaction(tx.signed_tx)
    logger.info(f'Send TX response:\n{r}')
    return r
Пример #6
0
 def setUp(self):
     self.FROM = 'Mx31e61a05adbd13c6b625262704bc305bf7725026'
     self.PRIVATE_KEY = '07bc17abdcee8b971bb8723e36fe9d2523306d5ab2d683631693238e0f9df142'
     self.SIGNED_TX = 'f8b30102018a4d4e54000000000000000db858f856f854e98a4d4e540000000000000094fe60014a6e9ac91618f5d1cab3fd58cded61ee9988016345785d8a0000e98a4d4e540000000000000094ddab6281766ad86497741ff91b6b48fe85012e3c8802c68af0bb140000808001b845f8431ca0b15dcf2e013df1a2aea02e36a17af266d8ee129cdcb3e881d15b70c9457e7571a0226af7bdaca9d42d6774c100b22e0c7ba4ec8dd664d17986318e905613013283'
     self.TX = MinterMultiSendCoinTx(
         **{
             'nonce':
             1,
             'chain_id':
             MinterTx.TESTNET_CHAIN_ID,
             'gas_coin':
             'MNT',
             'txs': [{
                 'coin': 'MNT',
                 'to': 'Mxfe60014a6e9ac91618f5d1cab3fd58cded61ee99',
                 'value': 0.1
             }, {
                 'coin': 'MNT',
                 'to': 'Mxddab6281766ad86497741ff91b6b48fe85012e3c',
                 'value': 0.2
             }]
         })
Пример #7
0
    def multisend(self,
                  to_dict,
                  coin="BIP",
                  payload='',
                  include_commission=True):
        """
        Multisend на любое количество адресов

        :param to_dict: dict {address: value, ...}
        :param coin: str 'SYMBOL'
        :param payload: str 'Комментарий к транзакции'
        :param include_commission: bool Платит с учетом комиссии
        :return:
        """

        # Генерация общего списка транзакций и расчет общей суммы выплаты
        all_txs = []
        total_value = 0
        for d_address, d_value in to_dict.items():
            d_value = Decimal(str(d_value))
            all_txs.append({'coin': coin, 'to': d_address, 'value': d_value})
            total_value += d_value

        # Проверяем хватит ли баланса для совершения транзакции
        balance = self.get_balance(in_bip=True)[coin]
        if total_value > balance:
            print(
                f'Ошибка: На кошельке недостаточно {coin}. Нужно {total_value}, а у нас {balance}'
            )
            return

        # Разбивка на списки по 100 транзакций
        all_txs = self._split_txs(all_txs)

        # Генерируем шаблоны транзакций
        tx_templates = [
            MinterMultiSendCoinTx(txs, nonce=1, gas_coin=coin, payload=payload)
            for txs in all_txs
        ]

        # Считаем общую комиссию за все транзакции
        if coin == 'BIP':
            total_commission = to_bip(sum(tx.get_fee() for tx in tx_templates))
        else:
            [tx.sign(self.private_key) for tx in tx_templates]
            total_commission = sum(
                self.API.estimate_tx_commission(tx.signed_tx, pip2bip=True)
                ['result']['commission'] for tx in tx_templates)

        # Если перевод с учетом комиссии, то пересчитываем выплаты
        if include_commission:
            new_total_value = total_value - total_commission
            if new_total_value <= 0:
                print(
                    f'Ошибка: Комиссия ({total_commission}) превышает сумму выплаты ({total_value})'
                )
                return

            for tx in tx_templates:
                for tx_dict in tx.txs:
                    tx_dict['value'] = new_total_value * Decimal(
                        str(tx_dict['value'])) / Decimal(str(total_value))
        else:
            total_value -= total_commission
            if total_value <= 0:
                print(
                    f'Ошибка: Комиссия ({total_commission}) превышает сумму выплаты ({total_value})'
                )
                return

        r_out = []
        # Делаем multisend
        for tx in tx_templates:
            tx.nonce = self.API.get_nonce(self.address)
            tx.sign(self.private_key)
            r = self.API.send_transaction(tx.signed_tx)

            try:
                if r['result']['code'] == 0:
                    print(
                        f'Multisend для {len(tx.txs)} получателей успешно отправлен'
                    )
                    self._wait_for_nonce(
                        tx.nonce
                    )  # Ждем nonce, чтобы предотвратить отправку нескольких транзакций в блоке

            except Exception:
                print(f'Не удалось отправить multisend\nServer response: {r}')

            r_out.append(r)

        return r_out