def get_balance_body(cls, address, contract):
     return {
         "from": cls.get_address(cls.ZERO_ADDRESS),
         "to": cls.get_address(contract),
         "value": digit.int_to_hex(0),
         "gas": digit.int_to_hex(cls.DEFAULT_GAS),
         # K M G  -> 10G
         "gasPrice": digit.int_to_hex(cls.DEFAULT_GAS_PRICE),
         "data": cls.GET_BALANCE_ABI + cls.get_address(address, contract)
     }
 def get_value(cls, value, contract=None) -> str:
     """
     获取合适的金额, 若是合约类型, 则补全至合适的位数, 并且没有0x开头
     :param value: 金额
     :param contract:
     :return: hex or hex not have ox
     """
     if contract is None:
         return digit.int_to_hex(value)
     real_value = digit.int_to_hex(value, has_0x=False)
     return real_value.zfill(cls.TRANSFER_VALUE_LENGTH)
 def get_transfer_template(cls,
                           sender=None,
                           receiver=None,
                           value=0,
                           gas=0,
                           gas_price=0,
                           data="",
                           contract=None):
     return {
         "from": cls.get_address(sender),
         "to": cls.get_address(contract or receiver),
         "value": digit.int_to_hex(value),
         "gas": digit.int_to_hex(gas or cls.DEFAULT_GAS),
         # K M G  -> 10G
         "gasPrice": digit.int_to_hex(gas_price or cls.DEFAULT_GAS_PRICE),
         "data": digit.add_0x(data)
     }
 def get_transfer_body(cls,
                       sender=None,
                       receiver=None,
                       gas: int = None,
                       gas_price: int = None,
                       value: int = 0,
                       contract=None) -> dict:
     if gas is None:
         gas = cls.DEFAULT_GAS
     if gas_price is None:
         gas_price = cls.DEFAULT_GAS_PRICE
     body = {
         "from": cls.get_address(sender),
         "to": cls.get_address(receiver),
         "value": cls.get_value(value) if contract is None else '0x0',
         "gas": digit.int_to_hex(gas),
         # K M G  -> 10G
         "gasPrice": digit.int_to_hex(gas_price),
     }
     if contract is not None:
         body['to'] = digit.add_0x(contract)
         body['data'] = cls.TRANSFER_ABI + cls.get_address(
             receiver, contract) + cls.get_value(value, contract)
     return body
Exemple #5
0
    def scan(self):
        self.block_info = self.rpc.get_block_height()
        self.newest_height = self.block_info.current_height
        self.highest_height = self.block_info.highest_height
        # 延迟扫 SCAN_DELAY_NUMBER 个块
        need_to_height = self.newest_height - self.SCAN_DELAY_NUMBER
        self.logger.info('起始扫块高度:{} 最新高度:{} 需要同步:{}'.format(
            self.current_scan_height, self.newest_height,
            need_to_height - self.current_scan_height))
        while self.current_scan_height < need_to_height:
            self.logger.info('当前已扫块高度:{} 最新高度:{} 需要同步:{}  节点最高高度:{}'.format(
                self.current_scan_height, self.newest_height,
                need_to_height - self.current_scan_height,
                self.highest_height))

            for height in range(self.current_scan_height, need_to_height,
                                self.SCAN_HEIGHT_NUMBER):
                # 分批处理, 一次处理 SCAN_HEIGHT_NUMBER 或 剩余要处理的块
                block_batch = min(self.SCAN_HEIGHT_NUMBER,
                                  need_to_height - self.current_scan_height)

                blocks = self.rpc.get_block_by_number([
                    digit.int_to_hex(height)
                    for height in range(height, height + block_batch)
                ])
                save_tx_count = 0
                with runtime.app.app_context():
                    # 一次处理一批
                    session = db.session()
                    try:
                        for block in blocks:
                            if block is None:
                                return
                            block_height = digit.hex_to_int(block['number'])
                            block_hash = block['hash']
                            block_timestamp = digit.hex_to_int(
                                block['timestamp'])
                            block_time = datetime.fromtimestamp(
                                block_timestamp)

                            session.begin(subtransactions=True)
                            db_block = Block(height=block_height,
                                             block_hash=block_hash,
                                             block_time=block_time)
                            session.add(db_block)
                            session.commit()

                            for transaction in block.get('transactions', []):
                                tx = EthereumResolver.resolver_transaction(
                                    transaction)
                                if tx.sender in runtime.project_address:
                                    # 提现的暂时不要
                                    continue
                                if tx.receiver in runtime.project_address:
                                    receipt_raw_tx = self.rpc.get_transaction_receipt(
                                        tx.tx_hash)
                                    if tx.contract:
                                        coin = runtime.coins.get(tx.contract)
                                    else:
                                        coin = runtime.coins.get(
                                            self.COIN_NAME)
                                    if coin is None:
                                        continue

                                    if receipt_raw_tx:
                                        receipt_tx = EthereumResolver.resolver_receipt(
                                            receipt_raw_tx)
                                    else:
                                        self.logger.error(
                                            '请求 {} receipt 错误, 重新处理')
                                        raise
                                    tx.status = receipt_tx.status
                                    # session.begin(subtransactions=True)
                                    # db_tx = Transaction(block_id=db_block.id, coin_id=coin['coin_id'],
                                    #                     tx_hash=tx.tx_hash, height=db_block.height,
                                    #                     block_time=block_timestamp,
                                    #                     amount=tx.value, sender=tx.sender, receiver=tx.receiver,
                                    #                     gas=tx.gas, gas_price=tx.gas_price,
                                    #                     is_send=SendEnum.NOT_PUSH.value,
                                    #                     fee=receipt_tx.gas_used * tx.gas_price,
                                    #                     contract=tx.contract, status=receipt_tx.status,
                                    #                     type=TxTypeEnum.DEPOSIT.value)
                                    Transaction.add_transaction_or_update(
                                        block_id=db_block.id,
                                        coin_id=coin['coin_id'],
                                        tx_hash=tx.tx_hash,
                                        height=db_block.height,
                                        block_time=block_timestamp,
                                        amount=tx.value,
                                        sender=tx.sender,
                                        receiver=tx.receiver,
                                        gas=tx.gas,
                                        gas_price=tx.gas_price,
                                        is_send=SendEnum.NOT_PUSH.value,
                                        fee=receipt_tx.gas_used * tx.gas_price,
                                        contract=tx.contract,
                                        status=receipt_tx.status,
                                        type=TxTypeEnum.DEPOSIT.value,
                                        session=session,
                                        commit=False)
                                    save_tx_count += 1
                                    # session.add(db_tx)
                                    # session.commit()
                                    # 添加推送信息

                        session.query(SyncConfig).filter(
                            SyncConfig.id == self.config_id).update({
                                'synced_height':
                                height + block_batch,
                                'highest_height':
                                self.highest_height
                            })
                        self.current_scan_height = height + block_batch
                        session.commit()
                        self.logger.info("本次同步高度为:{} -- {}, 保存交易: {} 笔".format(
                            height, height + block_batch, save_tx_count))

                    except Exception as e:
                        self.logger.error('同步块出现异常, 事务回滚. {}'.format(e))
                        session.rollback()
                        return
        self.logger.info("扫链结束, 本次同步")
Exemple #6
0
 def get_smart_fee(self, confirm_height="latest", contract=None):
     method = 'eth_estimateGas'
     if contract is None:
         return digit.int_to_hex(21000)
     payload = EthereumResolver.get_transfer_body(contract=contract)
     return self._single_post(method, payload)
Exemple #7
0
        # name, symbol, decimal, total
        return (EthereumResolver.parse_abi_name(rsp[0]),
                EthereumResolver.parse_abi_name(rsp[1]),
                EthereumResolver.parse_abi_name(rsp[2]),
                EthereumResolver.parse_abi_name(rsp[3]))


if __name__ == '__main__':
    import json

    rpc = EthereumRpcBase('http://192.168.10.201:37001')
    rpc.get_contract_info('0xdac17f958d2ee523a2206206994597c13d831ec7')
    # print(rpc.get_block_height())
    # print(rpc.get_block_by_hash('0x1a2f'))
    # print(rpc.get_block_by_hash(['0x1a2f', '0x9878']))
    # print(rpc.get_transaction_by_hash(['0x529bad6226fa1c843ea2b8cf70a2e4eaf95098783a3ee575994c87a6b726cb37',
    #                                    "0xcf13c31e274f7494d90ca996b26a64ce9e41b06c6a4cad6e37e2ddf04b81e47f"]))
    #
    # print(rpc.get_transaction_by_hash('0x529bad6226fa1c843ea2b8cf70a2e4eaf95098783a3ee575994c87a6b726cb37'))
    # print(rpc.get_transaction_by_hash('0x529bad6226fa1c843ea2b8cf70a2e4eaf95098783a3ee575994c87a6b726cb37',
    #                                   details=False))
    # print(rpc.get_transaction_receipt('0x529bad6226fa1c843ea2b8cf70a2e4eaf95098783a3ee575994c87a6b726cb37'))
    # print(rpc.get_transaction_receipt(['0x529bad6226fa1c843ea2b8cf70a2e4eaf95098783a3ee575994c87a6b726cb37',
    #                                    "0xcf13c31e274f7494d90ca996b26a64ce9e41b06c6a4cad6e37e2ddf04b81e47f"]))

    # print(rpc.get_wallet_balance())

    blocks = rpc.get_block_by_number(
        [digit.int_to_hex(height) for height in range(5000000, 5000010)])
    print(json.dumps(blocks))
def get_tx_by_tx_hash(tx_hash: str):
    rpc = RpcConfig.get_rpc()
    if rpc is None:
        return ResponseObject.error(**out_data_missing)
    chain_info = rpc.get_block_height()

    tx = Transaction.get_tx_coin_by_tx_hash(tx_hash=tx_hash)
    if tx:
        return ResponseObject.success(
            data={
                "sender":
                tx.Transaction.sender,
                "receiver":
                tx.Transaction.receiver,
                "txHash":
                tx.Transaction.tx_hash,
                "value":
                safe_math.divided(tx.Transaction.amount,
                                  safe_math.e_calc(
                                      tx.Coin.decimal)).to_eng_string(),
                "blockHeight":
                tx.Transaction.height,
                "blockTime":
                tx.Transaction.block_time,
                "contract":
                tx.Transaction.contract,
                "isValid":
                True if tx.Transaction.status == 1 else False,
                "confirmNumber":
                chain_info.highest_height -
                tx.Transaction.height if tx.Transaction.height > 0 else 0
            })
    else:
        tx_origin, receipt_origin = rpc.get_transaction_by_hash(tx_hash)
        if tx_origin and receipt_origin:
            tx, receipt = EthereumResolver.resolver_transaction(
                tx_origin), EthereumResolver.resolver_receipt(receipt_origin)
            block_info = rpc.get_block_by_number(int_to_hex(tx.block_height),
                                                 False)
            if not block_info:
                return ResponseObject.error(**rpc_block_not_found)
            block = EthereumResolver.resolver_block(block_info, False)
            if tx.contract is not None:
                coin = Coin.get_erc20_usdt_coin()
            else:
                coin = Coin.get_coin(name='Ethereum')
            if coin is None:
                return ResponseObject.error(**coin_missing)
            return ResponseObject.success(
                data={
                    "sender":
                    tx.sender,
                    "receiver":
                    tx.receiver,
                    "txHash":
                    tx.tx_hash,
                    "value":
                    safe_math.divided(tx.value, safe_math.e_calc(
                        coin.decimal)).to_eng_string(),
                    "blockHeight":
                    tx.block_height,
                    "blockTime":
                    block.timestamp,
                    "contract":
                    tx.contract,
                    "isValid":
                    True if receipt.status == 1 else False,
                    "confirmNumber":
                    chain_info.highest_height - tx.block_height
                })
    return ResponseObject.error(**tx_miss)
 def get_hex_highest_height(self):
     return digit.int_to_hex(self._highest_height)
 def get_hex_current_height(self):
     return digit.int_to_hex(self._current_height)