Exemplo n.º 1
0
    def transfer_batch(self, batch: List[BatchTransfer],
                       gas_price: Optional[int]=None, gas_limit=1,
                       max_workers=200, timeout=None):
        """Batch Transfer zils to addresses."""
        if not self.zil_key or not self.zil_key.encoded_private_key:
            raise RuntimeError("can not create transaction without private key")

        # check address format
        for to_addr, zils in batch:
            to_addr = zilkey.normalise_address(to_addr)
            if not to_addr:
                raise ValueError("invalid to address")

        if gas_price is None:
            gas_price = self.get_min_gas_price(refresh=False)

        resp = self.get_balance_nonce()
        batch_nonce = resp["nonce"] + 1

        txn_params = []
        for to_addr, zils in batch:
            to_addr = zilkey.normalise_address(to_addr)
            if not to_addr:
                raise ValueError("invalid to address")

            if isinstance(zils, Qa):
                amount = zils
            else:
                if not isinstance(zils, Zil):
                    zils = Zil(zils)
                amount = zils.toQa()

            params = active_chain.build_transaction_params(
                self.zil_key, to_addr,
                amount, batch_nonce,
                gas_price, gas_limit
            )
            txn_params.append(params)
            batch_nonce += 1

        def create_txn(p):
            try:
                txn_info = active_chain.api.CreateTransaction(p)
            except Exception as e:
                print("Error in CreateTransaction: {}".format(e))
                txn_info = None
            return txn_info

        txn_results = []
        with ThreadPoolExecutor(max_workers=max_workers) as pool:
            all_tasks = [pool.submit(create_txn, p) for p in txn_params]

            for future in futures.as_completed(all_tasks, timeout=timeout):
                try:
                    txn_results.append(future.result())
                except Exception as e:
                    print("Error: {}".format(e))
                    txn_results.append(None)

        return txn_results
Exemplo n.º 2
0
def withdraw(config, gas_price, gas_limit, contract):
    '''
    This function will generate a transaction to transfer the token from TEE accoount to the worker's account.
    '''
    cfg = _parse_config(config)

    # set the active chain
    local_chain = BlockChain(cfg["baseChainServer"],
                             int(cfg["baseChainversion"]),
                             int(cfg["baseChainID"]))
    chain.set_active_chain(local_chain)
    KMSConnector.rpcserver = cfg["baseChainServer"]
    KMSConnector.version = cfg["baseChainversion"]
    KMSConnector.networkid = cfg["baseChainID"]
    KMSConnector.host = str(cfg["KMS_HOST"])
    KMSConnector.port = int(cfg["KMS_PORT"])

    contract_addr = cfg[contract]
    contract = Contract.load_from_address(contract_addr)

    account = Account(private_key=cfg["oracleSK"])
    contract.account = account
    resp = contract.call(method="get_reward_balance",
                         params=[
                             Contract.value_dict(
                                 'oracle_owner_address', 'ByStr20',
                                 zilkey.normalise_address(
                                     cfg['oracleAddress']).lower())
                         ],
                         gas_price=gas_price,
                         gas_limit=gas_limit)
    if (resp is not None) and (not resp['receipt']['success']):
        print("Network error")
    else:
        if (resp['receipt']['event_logs'][0]['params'][0]['value']['arguments']
                == []) or (resp['receipt']['event_logs'][0]['params'][0]
                           ['value']['arguments'] == ['0']):
            print("No money")
        else:
            money = int(resp['receipt']['event_logs'][0]['params'][0]['value']
                        ['arguments'][0]) / 1000000000000.0
            print("Have money: " + str(money))
            kms = KMSConnector()
            if kms.withdraw(
                    zilkey.normalise_address(cfg['oracleAddress'].lower()),
                    money, cfg[contract]) == "success":
                print("Withdraw submit success")
                time.sleep(300)
                print("Withdraw success")
            elif kms.withdraw(
                    zilkey.normalise_address(cfg['oracleAddress'].lower()),
                    money, cfg[contract]) is None:
                print("KMS server has no response")
            else:
                print("Withdraw submit fail")
Exemplo n.º 3
0
 def respond(self):
     if not self.res_q.empty():
         response = self.res_q.get()
         self.logger.info("zilliqa respond: " + response.result)
         request_id = response.request_id
         tora_contract_address = response.tora_addr
         zilkey.normalise_address(KMSConnector.oracle_owner_address)
         if response.response_method == 'responseString':
             data = self.__generate_send_data(method=response.response_method,
                                              params=[self.__value_dict('id', 'Uint32', str(request_id)),
                                                      self.__value_dict('result', 'String',
                                                                        response.result.replace('"', "'")),
                                                      self.__value_dict('oracle_owner_address', 'ByStr20',
                                                                        zilkey.normalise_address(KMSConnector.oracle_owner_address).lower()),
                                                      self.__value_dict('param', 'String', response.params)
                                                      ])
         else:
             data = self.__generate_send_data(method=response.response_method,
                                              params=[self.__value_dict('id', 'Uint32', str(request_id)),
                                                      self.__value_dict('result', 'String',
                                                                        response.result.replace('"', "'")),
                                                      self.__value_dict('oracle_owner_address', 'ByStr20',
                                                                        zilkey.normalise_address(
                                                                            KMSConnector.oracle_owner_address).lower())
                                                      ])
         try:
             resp = self.__send_data_to_address(tora_contract_address, 0, response.gas_price, response.gas_limit, data)
         except Exception as e:
             self.logger.info(e)
             resp = None
         if not resp:
             self.logger.info("Respond fail")
             return
         print(resp)
         if resp['receipt']['success']:
             self.logger.info("Respond success")
             remain_gas = response.gas_limit - int(resp['receipt']['cumulative_gas'])
             # 一部分是退款的手续费,一部分作为withdraw的手续费
             refund_gas = remain_gas * response.gas_price - TRANSFER_GAS * TRANSFER_GAS_PRICE - WITHDRAW_GAS * WITHDRAW_GAS_PRICE
             if refund_gas < 0:
                 self.logger.info("Refund_gas<0")
                 return
             if refund_gas == 0:
                 self.logger.info("Refund_gas=0")
                 return
             self.logger.info("Refund_gas:"+str(refund_gas))
             refund_resp = self.__send_data_to_address(zilkey.to_checksum_address(response.user_addr), refund_gas, TRANSFER_GAS_PRICE, TRANSFER_GAS)
             print(refund_resp)
         else:
             self.logger.info("Respond fail")
     else:
         time.sleep(1)
Exemplo n.º 4
0
def __get_swap_request_event(account_addr, api, block_num):
    txns = api.GetTransactionsForTxBlock(block_num)
    for txn in txns:
        if len(txn) != 0:
            receipt = api.GetTransaction(txn[0])["receipt"]
            if "event_logs" in receipt:
                event_logs = receipt["event_logs"]
                for event_log in event_logs:
                    if event_log["address"] == (
                            zilkey.normalise_address(contract_addr)).lower():
                        if event_log["_eventname"] == "swap":
                            params = event_log["params"]
                            for param in params:
                                if param["vname"] == "targetaddr" and param[
                                        "value"] == account_addr.lower():
                                    print("A new request arrives.")
                                    pprint(event_log)
                                    for temp_p in params:
                                        if temp_p["vname"] == "id":
                                            print(
                                                "The request id is " +
                                                temp_p["value"] +
                                                ", please put the hexadecimal format of it in the input field of your transfer transaction."
                                            )
                                            return True
    return False
Exemplo n.º 5
0
def __get_swap_request_event(account_addr, api, block_num):
    txns = api.GetTransactionsForTxBlock(block_num)
    for txn in txns:
        if len(txn) != 0:
            receipt = api.GetTransaction(txn[0])["receipt"]
            if "event_logs" in receipt:
                event_logs = receipt["event_logs"]
                for event_log in event_logs:
                    if event_log["address"] == (
                            zilkey.normalise_address(contract_addr)).lower():
                        if event_log["_eventname"] == "Swap success":
                            params = event_log["params"]
                            for param in params:
                                if param["vname"] == "targetaddr" and param[
                                        "value"] == account_addr.lower():
                                    print("Swap successfully...")
                                    print(event_log)
                                    return True
                        if event_log[
                                "_eventname"] == "Swap fail and return the lock money":
                            params = event_log["params"]
                            for param in params:
                                if param["vname"] == "targetaddr" and param[
                                        "value"] == account_addr.lower():
                                    print(
                                        "Swap fail and return the lock money..."
                                    )
                                    print(event_log)
                                    return True
    return False
Exemplo n.º 6
0
    def transfer(self, to_addr: str,
                 zils: Union[str, float, Zil, Qa],
                 nonce: Optional[int]=None,
                 gas_price: Optional[int]=None, gas_limit=1,
                 code="", data="", priority=False,
                 confirm=False, timeout=300, sleep=20, hit_chain=False):
        """Transfer zils to another address."""
        if not self.zil_key or not self.zil_key.encoded_private_key:
            raise RuntimeError("can not create transaction without private key")

        to_addr = zilkey.normalise_address(to_addr)
        if not to_addr:
            raise ValueError("invalid to address")

        if isinstance(zils, Qa):
            amount = zils
        else:
            if not isinstance(zils, Zil):
                zils = Zil(zils)
            amount = zils.toQa()

        if gas_price is None:
            if hit_chain:
                gas_price = self.get_min_gas_price(refresh=False)
            else:
                gas_price = 100

        if nonce is None:
            resp = self.get_balance_nonce()
            if amount > Qa(resp["balance"]):
                raise ValueError("insufficient balance to send")
            nonce = resp["nonce"] + 1

        params = active_chain.build_transaction_params(
            self.zil_key, to_addr,
            amount, nonce,
            gas_price, gas_limit,
            code, data, priority
        )
        self.last_params = params

        if not hit_chain:
            return None
        else:
            txn_info = active_chain.api.CreateTransaction(params)
            self.last_txn_info = txn_info
            if not confirm:
                return txn_info

            if not txn_info:
                return None

            txn_details = Account.wait_txn_confirm(
                txn_info["TranID"],
                timeout=timeout, sleep=sleep
            )
            self.last_txn_details = txn_details
            return txn_details
Exemplo n.º 7
0
    def __send_data_to_address(self,
                               to_addr: str,
                               amount=0,
                               gas_price: Optional[int] = None,
                               gas_limit=1,
                               data="",
                               priority=True,
                               timeout=300,
                               sleep=20):
        if not to_addr:
            raise ValueError("invalid to address")
        if not to_addr.startswith("0x"):
            # to_addr zli... to checksum address
            to_addr = zilkey.normalise_address(to_addr)
            print(to_addr)
        if not to_addr:
            raise ValueError("invalid to address")
        kms_conn = KMSConnector()
        if kms_conn.get_master_tee_nonce() is None:
            self.logger.info("KMS server has no response")
            return None
        master_tee_nonce = kms_conn.get_master_tee_nonce() + 1
        master_tee_pubkey_bytes = kms_conn.get_master_tee_pubkey()
        master_tee_pubkey = hex(
            int.from_bytes(master_tee_pubkey_bytes, byteorder="big"))

        data_to_sign = chain.active_chain.get_data_to_sign(
            master_tee_pubkey_bytes, to_addr, master_tee_nonce, amount,
            gas_price, gas_limit, '', data)
        signature = kms_conn.sign_message(data_to_sign)
        if signature == 'None':
            self.logger.info("The request has been responded")
            return None
        params = {
            "version": chain.active_chain.version,
            "nonce": master_tee_nonce,
            "toAddr": to_addr,
            "amount": str(amount),
            "pubKey": '0' + master_tee_pubkey[2:],
            "gasPrice": str(gas_price),
            "gasLimit": str(gas_limit),
            "code": None,
            "data": data or None,
            "signature": signature,
            "priority": priority,
        }
        print(params)
        txn_info = chain.active_chain.api.CreateTransaction(params)

        txn_details = chain.active_chain.wait_txn_confirm(txn_info["TranID"],
                                                          timeout=timeout,
                                                          sleep=sleep)
        return txn_details
Exemplo n.º 8
0
def __get_response_from_block(contract_addr, api, block_num):
    txns = api.GetTransactionsForTxBlock(block_num)
    for txn in txns:
        if len(txn) != 0:
            receipt = api.GetTransaction(txn[0])["receipt"]
            if "event_logs" in receipt:
                event_logs = receipt["event_logs"]
                for event_log in event_logs:
                    if event_log["address"] == (zilkey.normalise_address(contract_addr)).lower():
                        if event_log["_eventname"] == "callback":
                            print("Get a response...")
                            print(event_log)
                            return True
    return False
Exemplo n.º 9
0
 def __get_request_from_block(self, block_num):
     txns = self.api.GetTransactionsForTxBlock(block_num)
     for txn in txns:
         if len(txn) != 0:
             receipt = self.api.GetTransaction(txn[0])["receipt"]
             if "event_logs" in receipt:
                 event_logs = receipt["event_logs"]
                 for event_log in event_logs:
                     if event_log["address"] == (zilkey.normalise_address(
                             self.contract_addr)).lower():
                         if event_log[
                                 "_eventname"] == "request" or event_log[
                                     "_eventname"] == "verifyrequest":
                             self.req_q.put(
                                 self.__resolve_event_log(event_log))