def __init__(self, address, value, tag=None, message=None, timestamp=None): # type: (Address, int, Optional[Tag], Optional[TryteString], Optional[int]) -> None if not timestamp: timestamp = get_current_timestamp() super(ProposedTransaction, self).__init__( address=address, tag=Tag(b'') if tag is None else tag, timestamp=timestamp, value=value, # These values will be populated when the bundle is finalized. bundle_hash=None, current_index=None, hash_=None, last_index=None, signature_message_fragment=None, # These values start out empty; they will be populated when the # node does PoW. branch_transaction_hash=TransactionHash(b''), nonce=Hash(b''), trunk_transaction_hash=TransactionHash(b''), ) self.message = TryteString(b'') if message is None else message
def from_tryte_string(cls, trytes, hash_=None): # type: (TrytesCompatible, Optional[TransactionHash]) -> Transaction """ Creates a Transaction object from a sequence of trytes. :param trytes: Raw trytes. Should be exactly 2673 trytes long. :param hash_: The transaction hash, if available. If not provided, it will be computed from the transaction trytes. """ tryte_string = TransactionTrytes(trytes) if not hash_: hash_trits = [0] * HASH_LENGTH # type: MutableSequence[int] sponge = Curl() sponge.absorb(tryte_string.as_trits()) sponge.squeeze(hash_trits) hash_ = TransactionHash.from_trits(hash_trits) return cls( hash_=hash_, signature_message_fragment=Fragment(tryte_string[0:2187]), address=Address(tryte_string[2187:2268]), value=int_from_trits(tryte_string[2268:2295].as_trits()), legacy_tag=Tag(tryte_string[2295:2322]), timestamp=int_from_trits(tryte_string[2322:2331].as_trits()), current_index=int_from_trits(tryte_string[2331:2340].as_trits()), last_index=int_from_trits(tryte_string[2340:2349].as_trits()), bundle_hash=BundleHash(tryte_string[2349:2430]), trunk_transaction_hash=TransactionHash(tryte_string[2430:2511]), branch_transaction_hash=TransactionHash(tryte_string[2511:2592]), tag=Tag(tryte_string[2592:2619]), attachment_timestamp=int_from_trits( tryte_string[2619:2628].as_trits()), attachment_timestamp_lower_bound=int_from_trits( tryte_string[2628:2637].as_trits()), attachment_timestamp_upper_bound=int_from_trits( tryte_string[2637:2646].as_trits()), nonce=Nonce(tryte_string[2646:2673]), )
def __init__( self, address, # type: Address value, # type: int tag=None, # type: Optional[Tag] message=None, # type: Optional[TryteString] timestamp=None, # type: Optional[int] ): if not timestamp: timestamp = get_current_timestamp() super(ProposedTransaction, self).__init__( address=address, tag=Tag(b'') if tag is None else Tag(tag), timestamp=timestamp, value=value, # These values will be populated when the bundle is # finalized. bundle_hash=None, current_index=None, hash_=None, last_index=None, signature_message_fragment=None, attachment_timestamp=0, attachment_timestamp_lower_bound=0, attachment_timestamp_upper_bound=0, # These values start out empty; they will be populated when # the node does PoW. branch_transaction_hash=TransactionHash(b''), nonce=Nonce(b''), trunk_transaction_hash=TransactionHash(b''), ) self.message = TryteString(b'') if message is None else message
def from_tryte_string(cls, trytes, hash_=None): # type: (TrytesCompatible, Optional[TransactionHash]) -> Transaction """ Creates a Transaction object from a sequence of trytes. :param trytes: Raw trytes. Should be exactly 2673 trytes long. :param hash_: The transaction hash, if available. If not provided, it will be computed from the transaction trytes. """ tryte_string = TransactionTrytes(trytes) if not hash_: hash_trits = [0] * HASH_LENGTH # type: MutableSequence[int] sponge = Curl() sponge.absorb(tryte_string.as_trits()) sponge.squeeze(hash_trits) hash_ = TransactionHash.from_trits(hash_trits) return cls( hash_ = hash_, signature_message_fragment = Fragment(tryte_string[0:2187]), address = Address(tryte_string[2187:2268]), value = int_from_trits(tryte_string[2268:2295].as_trits()), legacy_tag = Tag(tryte_string[2295:2322]), timestamp = int_from_trits(tryte_string[2322:2331].as_trits()), current_index = int_from_trits(tryte_string[2331:2340].as_trits()), last_index = int_from_trits(tryte_string[2340:2349].as_trits()), bundle_hash = BundleHash(tryte_string[2349:2430]), trunk_transaction_hash = TransactionHash(tryte_string[2430:2511]), branch_transaction_hash = TransactionHash(tryte_string[2511:2592]), tag = Tag(tryte_string[2592:2619]), attachment_timestamp = int_from_trits(tryte_string[2619:2628].as_trits()), attachment_timestamp_lower_bound = int_from_trits(tryte_string[2628:2637].as_trits()), attachment_timestamp_upper_bound = int_from_trits(tryte_string[2637:2646].as_trits()), nonce = Nonce(tryte_string[2646:2673]), )
def conductPOW(self, bundle): HASH_LENGTH = 243 mwm = 14 # minimum weight on mainnet tangle (expected 1 minute for iot device at this level) trailing_zeros = [0] * mwm # For checking transaction hash previoustx = None max_iter = 5 i = 0 branch_transaction_hash = bundle.branchObj.bundle_hash trunk_transaction_hash = bundle.trunkObj.bundle_hash for trxn in reversed(bundle.trxns): startTime = time.time() trxn.attachment_timestamp = int(round(time.time() * 1000)) while i != max_iter: if (not previoustx): if trxn.current_index == trxn.last_index: trxn.branch_transaction_hash = branch_transaction_hash trxn.trunk_transaction_hash = trunk_transaction_hash else: raise ValueError( 'Head transaction is inconsistent in bundle') else: # It is not the head transaction (For clarity, see bundle figure in report) trxn.branch_transaction_hash = trunk_transaction_hash trxn.trunk_transaction_hash = previoustx # Let's do the pow locally trxn_string = trxn.as_tryte_string().__str__() # returns a python unicode string powed_trytes = _libccurl.ccurl_pow(trxn_string.encode('utf-8'), mwm) # construct trytestring from python string powed_trytes_bytes = powed_trytes[:2673] # Let's decode into unicode powed_txn_trytes = powed_trytes_bytes.decode('utf-8') powed_txn_trytes = TryteString(powed_txn_trytes) # Create powed txn hash hash_trits: MutableSequence[int] = [0] * HASH_LENGTH sponge = Curl() sponge.absorb(powed_txn_trytes.as_trits()) sponge.squeeze(hash_trits) hash = TransactionHash.from_trits(hash_trits) trxn.hash = hash previoustx = hash if hash_trits[-mwm:] == trailing_zeros: # We are good to go, exit from while loop totalTime = time.time() - startTime logger.info("Successfully conducted PoW for trxn " + str(trxn.current_index) + "! Time: {:.4g}".format(totalTime) + " sec") break else: i = i + 1 logger.info( 'Oops, wrong hash detected in try' ' #{rounds}. Recalculating PoW... '.format(rounds=i)) # Tail transactions represent bundles in the tangle return bundle.tail_transaction.hash
def from_tryte_string(cls: Type[T], trytes: TrytesCompatible, hash_: Optional[TransactionHash] = None) -> T: """ Creates a Transaction object from a sequence of trytes. :param TrytesCompatible trytes: Raw trytes. Should be exactly 2673 trytes long. :param Optional[TransactionHash] hash_: The transaction hash, if available. If not provided, it will be computed from the transaction trytes. :return: :py:class:`Transaction` object. Example usage:: from iota import Transaction txn =\\ Transaction.from_tryte_string( b'GYPRVHBEZOOFXSHQBLCYW9ICTCISLHDBNMMVYD9JJHQMPQCTIQAQTJNNNJ9IDXLRCC' b'OYOXYPCLR9PBEY9ORZIEPPDNTI9CQWYZUOTAVBXPSBOFEQAPFLWXSWUIUSJMSJIIIZ' b'WIKIRH9GCOEVZFKNXEVCUCIIWZQCQEUVRZOCMEL9AMGXJNMLJCIA9UWGRPPHCEOPTS' b'VPKPPPCMQXYBHMSODTWUOABPKWFFFQJHCBVYXLHEWPD9YUDFTGNCYAKQKVEZYRBQRB' b'XIAUX9SVEDUKGMTWQIYXRGSWYRK9SRONVGTW9YGHSZRIXWGPCCUCDRMAXBPDFVHSRY' b'WHGB9DQSQFQKSNICGPIPTRZINYRXQAFSWSEWIFRMSBMGTNYPRWFSOIIWWT9IDSELM9' b'JUOOWFNCCSHUSMGNROBFJX9JQ9XT9PKEGQYQAWAFPRVRRVQPUQBHLSNTEFCDKBWRCD' b'X9EYOBB9KPMTLNNQLADBDLZPRVBCKVCYQEOLARJYAGTBFR9QLPKZBOYWZQOVKCVYRG' b'YI9ZEFIQRKYXLJBZJDBJDJVQZCGYQMROVHNDBLGNLQODPUXFNTADDVYNZJUVPGB9LV' b'PJIYLAPBOEHPMRWUIAJXVQOEM9ROEYUOTNLXVVQEYRQWDTQGDLEYFIYNDPRAIXOZEB' b'CS9P99AZTQQLKEILEVXMSHBIDHLXKUOMMNFKPYHONKEYDCHMUNTTNRYVMMEYHPGASP' b'ZXASKRUPWQSHDMU9VPS99ZZ9SJJYFUJFFMFORBYDILBXCAVJDPDFHTTTIYOVGLRDYR' b'TKHXJORJVYRPTDH9ZCPZ9ZADXZFRSFPIQKWLBRNTWJHXTOAUOL9FVGTUMMPYGYICJD' b'XMOESEVDJWLMCVTJLPIEKBE9JTHDQWV9MRMEWFLPWGJFLUXI9BXPSVWCMUWLZSEWHB' b'DZKXOLYNOZAPOYLQVZAQMOHGTTQEUAOVKVRRGAHNGPUEKHFVPVCOYSJAWHZU9DRROH' b'BETBAFTATVAUGOEGCAYUXACLSSHHVYDHMDGJP9AUCLWLNTFEVGQGHQXSKEMVOVSKQE' b'EWHWZUDTYOBGCURRZSJZLFVQQAAYQO9TRLFFN9HTDQXBSPPJYXMNGLLBHOMNVXNOWE' b'IDMJVCLLDFHBDONQJCJVLBLCSMDOUQCKKCQJMGTSTHBXPXAMLMSXRIPUBMBAWBFNLH' b'LUJTRJLDERLZFUBUSMF999XNHLEEXEENQJNOFFPNPQ9PQICHSATPLZVMVIWLRTKYPI' b'XNFGYWOJSQDAXGFHKZPFLPXQEHCYEAGTIWIJEZTAVLNUMAFWGGLXMBNUQTOFCNLJTC' b'DMWVVZGVBSEBCPFSM99FLOIDTCLUGPSEDLOKZUAEVBLWNMODGZBWOVQT9DPFOTSKRA' b'BQAVOQ9RXWBMAKFYNDCZOJGTCIDMQSQQSODKDXTPFLNOKSIZEOY9HFUTLQRXQMEPGO' b'XQGLLPNSXAUCYPGZMNWMQWSWCKAQYKXJTWINSGPPZG9HLDLEAWUWEVCTVRCBDFOXKU' b'ROXH9HXXAXVPEJFRSLOGRVGYZASTEBAQNXJJROCYRTDPYFUIQJVDHAKEG9YACV9HCP' b'JUEUKOYFNWDXCCJBIFQKYOXGRDHVTHEQUMHO999999999999999999999999999999' b'999999999999999999999999999999999999999999999999999999999999999999' b'999999999999999999999999999999999999999999999999999999999999999999' b'999999999999999999999999999999999999999999999999999999999999999999' b'999999999999999999999999999999999999999999999999999999999999999999' b'999999999999999999999999999999999999999999999999999999999999999999' b'999999999999999999999999999999999999999999999999999999999999999999' b'999999999999999999999999999999999999999999999999999999999999999999' b'999999999999999999999999999999999999999999999999999999999999999999' b'999999999999999999999999999999999999999999999999999999999999999999' b'999999999999999999999999999999999999999999999999999999999999999999' b'999999999999RKWEEVD99A99999999A99999999NFDPEEZCWVYLKZGSLCQNOFUSENI' b'XRHWWTZFBXMPSQHEDFWZULBZFEOMNLRNIDQKDNNIELAOXOVMYEI9PGTKORV9IKTJZQ' b'UBQAWTKBKZ9NEZHBFIMCLV9TTNJNQZUIJDFPTTCTKBJRHAITVSKUCUEMD9M9SQJ999' b'999TKORV9IKTJZQUBQAWTKBKZ9NEZHBFIMCLV9TTNJNQZUIJDFPTTCTKBJRHAITVSK' b'UCUEMD9M9SQJ999999999999999999999999999999999999999999999999999999' b'999999999999999999999999999999999' ) """ tryte_string = TransactionTrytes(trytes) if not hash_: hash_trits: MutableSequence[int] = [0] * HASH_LENGTH sponge = Curl() sponge.absorb(tryte_string.as_trits()) sponge.squeeze(hash_trits) hash_ = TransactionHash.from_trits(hash_trits) return cls( hash_=hash_, signature_message_fragment=Fragment(tryte_string[0:2187]), address=Address(tryte_string[2187:2268]), value=int_from_trits(tryte_string[2268:2295].as_trits()), legacy_tag=Tag(tryte_string[2295:2322]), timestamp=int_from_trits(tryte_string[2322:2331].as_trits()), current_index=int_from_trits(tryte_string[2331:2340].as_trits()), last_index=int_from_trits(tryte_string[2340:2349].as_trits()), bundle_hash=BundleHash(tryte_string[2349:2430]), trunk_transaction_hash=TransactionHash(tryte_string[2430:2511]), branch_transaction_hash=TransactionHash(tryte_string[2511:2592]), tag=Tag(tryte_string[2592:2619]), attachment_timestamp=int_from_trits( tryte_string[2619:2628].as_trits()), attachment_timestamp_lower_bound=int_from_trits( tryte_string[2628:2637].as_trits()), attachment_timestamp_upper_bound=int_from_trits( tryte_string[2637:2646].as_trits()), nonce=Nonce(tryte_string[2646:2673]), )