コード例 #1
0
    def test_wireup(self):
        """
        Verify that the command is wired up correctly.

        The API method indeed calls the appropiate command.
        """
        with patch(
                'iota.commands.extended.get_transaction_objects.GetTransactionObjectsCommand.__call__',
                MagicMock(return_value='You found me!')) as mocked_command:

            api = Iota(self.adapter)

            # Don't need to call with proper args here.
            response = api.get_transaction_objects('hashes')

            self.assertTrue(mocked_command.called)

            self.assertEqual(response, 'You found me!')
コード例 #2
0
class Collector(Crypt):
    def __init__(self, secret, node='https://nodes.thetangle.org:443'):
        super(Collector, self).__init__(secret)
        self.api = Iota(adapter=node)

    def getData(self, txHash):
        hashes = api.find_transactions(addresses=[
            address,
        ])['hashes']

    def decode(self, frag):
        hiddenMessage = frag.signature_message_fragment.decode()
        decrypted = self.decrypt(bytes(hiddenMessage, 'utf=8'))
        return json.loads(decrypted)

    def read(self, silent=False):
        address = Address(self.address)
        txHashes = self.api.find_transactions(addresses=[
            address,
        ])['hashes']
        batchSize = 80
        sets = math.ceil(len(txHashes) / batchSize)
        txs = []
        for i in range(sets):
            start = time.time()
            resp = self.api.get_transaction_objects(
                txHashes[i * batchSize:(i + 1) * batchSize])['transactions']
            txs += resp
            duration = time.time() - start
            if not silent:
                print(f'Fetched {len(resp)} events in {duration:.1f} sec.')
        return sorted([self.decode(t) for t in txs],
                      key=lambda a: a[0],
                      reverse=True)

    def readLatest(self, silent=False):
        messages = self.read()
        secconds, msg = messages[0]
        timestamp = datetime.datetime.fromtimestamp(secconds)
        return f'{timestamp}: {msg}'
コード例 #3
0
ファイル: collect.py プロジェクト: MViscardi-UCSC/temperature
class Collector:
    def __init__(self, endpoint=None):
        self.api = Iota(adapter='https://nodes.thetangle.org:443')
        if endpoint is None:
            self.endpoint = Controller.endpoint
        else:
            self.endpoint = endpoint

    def getData(self, txHash):
        hashes = api.find_transactions(addresses=[
            address,
        ])['hashes']

    def read(self):
        address = Address(self.endpoint)
        txHashes = self.api.find_transactions(addresses=[
            address,
        ])['hashes']
        txs = self.api.get_transaction_objects(txHashes)['transactions']
        decode = lambda a: json.loads(a.signature_message_fragment.decode())
        return sorted([decode(t) for t in txs],
                      key=lambda a: a[0],
                      reverse=True)
コード例 #4
0
class Escrow:
    def __init__(self, node='https://nodes.thetangle.org:443', seed=None):
        #Get Seed
        if seed is None:
            self.seed = self.getSeed()
        else:
            self.seed = seed

        #Setup API
        self.api = Iota(node, self.seed)

    #Generates a seed for escrow account
    def getSeed(self):
        #If no seed, create one
        if not os.path.isfile('seed.txt'):
            path = pathlib.Path(__file__).parent.absolute()
            seed = ''.join([random.choice(LETTERS) for i in range(81)])
            open('seed.txt', 'w+').write(seed)
            logging.info("Placed new seed in seed.txt")
        return open('seed.txt').read().strip().encode('utf-8')

    #Creates an escrow holding address
    def createEscrow(self):
        try:
            self.holdingAddress = self.api.get_new_addresses(
                count=None, checksum=True)['addresses'][0]
        except iota.adapter.BadApiResponse as e:
            logging.warning("Bad response from server retrying.")
            return self.createEscrow()
        return self.holdingAddress

    #Waits for a transactions with a refund address
    def getRefundAddress(self):
        #This is the escrow address
        address = self.holdingAddress
        try:
            #Get Hashes from ledger
            txHashes = self.api.find_transactions(addresses=[
                address,
            ])['hashes']
            #If no hashes, user has not submitted an address yet.
            if len(txHashes) == 0:
                return None
            else:
                #Check messages for a valid address
                txs = self.api.get_transaction_objects(
                    txHashes)['transactions']
                for tx in txs:
                    msg = tx.signature_message_fragment.decode()
                    try:
                        self.deposit = Address(msg.strip())
                        return self.deposit
                    except:
                        pass
                logging.warning("Invalid address recieved")
        except requests.exceptions.ConnectionError as e:
            #Sometimes the public nodes will reject a request
            print("Error contacting server; retrying")
            return self.getRefundAddress()

    #Cli version of escrow
    def startCli(self, collateral, fee=0, delay=120, deposit=None):
        #Create holding address
        self.createEscrow()
        self.fee = fee
        self.collateral = collateral
        #Wait for a deposit address to be entered
        if self.requestDeposit(collateral, deposit, delay):
            while not self.checkCondition():
                sleep(3)
        self.finalizeEscrow()

    #Wait for escrow address to recieve collateral
    def requestDeposit(self, collateral, deposit=None, duration=120):
        #For CLI prompt a deposit address
        if deposit is None:
            self.deposit = input("What is the deposit address: ")
        print(
            f"You have {duration/60:.1f} min to deposit {collateral} IOTA to {self.holdingAddress}"
        )

        #Wait for escrow to recive collateral funds.
        count = 0
        while count < duration:
            time.sleep(1)
            balance = self.getBalance(self.holdingAddress)
            if balance >= collateral:
                print("Successfully deposited into escrow", balance)
                return True
        return False

    #Condition to release escrow
    def checkCondition(self):
        #Setup a check condition
        #For example RFID or some ledger condition
        return True

    #Refund user their collateral, remoing the fee
    def finalizeEscrow(self, fee=None, deposit=None):
        if fee is None: fee = self.fee
        if deposit is None: deposit = self.deposit
        #Return money to deposit address
        returnAmount = self.getBalance(self.holdingAddress)

        #Calcualte return amount
        if returnAmount > 0:
            returnAmount -= fee

        #Setup transaction
        message = "Repayment of collateral"
        feeLocation = self.api.get_new_addresses(count=1,
                                                 checksum=True)['addresses'][0]
        txs = [
            ProposedTransaction(address=Address(deposit),
                                value=returnAmount,
                                message=TryteString.from_unicode(message)),
        ]

        #Send transaction
        try:
            bundle = self.api.send_transfer(transfers=txs)['bundle']
        except iota.adapter.BadApiResponse as e:
            print("Node did not respond. Retrying.")
            return self.finalizeEscrow(fee, deposit)
        logging.info(bundle.transactions[0].hash)
        logging.info("Sent money back to recipient")
        self.addRevenue(fee)

    def getBalance(self, address):
        try:
            response = self.api.get_balances(addresses=[address])['balances']
            return response[0]
        except requests.exceptions.ConnectionError as e:
            logging.info("Error contacting server; retrying")
            return self.getBalance(self, address)

    #Record the amount of revenue recieved
    def addRevenue(self, money, filename='revenue.txt'):
        if not os.path.isfile(filename):
            open(filename, 'w+').write('0')
        current = int(open(filename).read().strip())
        current += money
        open(filename, 'w+').write(str(current))

    #Get the current amount of revenue
    def getRevenue(self, filename="revenue.txt"):
        if not os.path.isfile(filename): return 0
        return int(open(filename).read().strip())

    #Send revenue to an address
    def sendRevenue(self, outputAddress):
        revenue = self.getRevenue()
        logger.info(f"Currently have {revenue} revenue.")
        message = "Output fees from escrow."
        txs = [
            ProposedTransaction(address=Address(outputAddress),
                                value=revenue,
                                message=TryteString.from_unicode(message)),
        ]
        try:
            logger.info("Sending transfer to node.")
            bundle = self.api.send_transfer(transfers=txs)['bundle']
        except iota.adapter.BadApiResponse as e:
            print("Bad api resonse retrying")
            return self.sendRevenue(outputAddress)
        print(bundle.transactions[0].hash)