def explorer_post(self, endpoint, data): """ Put explorer data onto the stub client for the specified endpoint. """ hash_template = re.compile(r'^.*/transactionpool/transactions$') match = hash_template.match(endpoint) if match: transactionid = Hash(value=jscrypto.random(Hash.SIZE)).__str__() transaction = tftransactions.from_json(data) # ensure all coin outputs and block stake outputs have identifiers set for idx, co in enumerate(transaction.coin_outputs): co.id = transaction.coin_outputid_new(idx) for idx, bso in enumerate(transaction.blockstake_outputs): bso.id = transaction.blockstake_outputid_new(idx) self._posted_transactions[transactionid] = transaction return jsstr.sprintf('{"transactionid":"%s"}', transactionid.__str__()) raise Exception("invalid endpoint {}".format(endpoint))
class UnlockHash(BaseDataTypeClass): """ An UnlockHash is a specially constructed hash of the UnlockConditions type, with a fixed binary length of 33 and a fixed string length of 78 (string version includes a checksum). """ def __init__(self, uhtype=None, uhhash=None): self._type = UnlockHashType.NIL self.uhtype = uhtype self._hash = Hash() self.hash = uhhash @classmethod def from_str(cls, obj): if not isinstance(obj, str): raise TypeError( "UnlockHash is expected to be a str, not {}".format(type(obj))) obj = jsstr.strip(obj) if len(obj) != UnlockHash._TOTAL_SIZE_HEX: raise ValueError( "UnlockHash is expexcted to be of length {} when stringified, not of length {}, invalid: {} ({})" .format(UnlockHash._TOTAL_SIZE_HEX, len(obj), obj, type(obj))) t = UnlockHashType( int(jsarr.slice_array(obj, 0, UnlockHash._TYPE_SIZE_HEX))) h = Hash( value=obj[UnlockHash._TYPE_SIZE_HEX:UnlockHash._TYPE_SIZE_HEX + UnlockHash._HASH_SIZE_HEX]) uh = cls(uhtype=t, uhhash=h) if t.__eq__(UnlockHashType.NIL): expectedNH = jshex.bytes_to_hex( bytes(jsarr.new_array(UnlockHash._HASH_SIZE))) nh = jshex.bytes_to_hex(h.value) if nh != expectedNH: raise ValueError("unexpected nil hash {}".format(nh)) else: expected_checksum = jshex.bytes_to_hex( jsarr.slice_array(uh._checksum(), 0, UnlockHash._CHECKSUM_SIZE)) checksum = jsarr.slice_array( obj, UnlockHash._TOTAL_SIZE_HEX - UnlockHash._CHECKSUM_SIZE_HEX) if expected_checksum != checksum: raise ValueError("unexpected checksum {}, expected {}".format( checksum, expected_checksum)) return uh @classmethod def from_json(cls, obj): return UnlockHash.from_str(obj) @property def uhtype(self): return self._type @uhtype.setter def uhtype(self, value): if value == None: value = UnlockHashType.NIL elif not isinstance(value, UnlockHashType): raise TypeError( "UnlockHash's type has to be of type UnlockHashType, not {}". format(type(value))) self._type = value @property def hash(self): return self._hash @hash.setter def hash(self, value): self._hash.value = value def __str__(self): checksum = jshex.bytes_to_hex( jsarr.slice_array(self._checksum(), 0, UnlockHash._CHECKSUM_SIZE)) return "{}{}{}".format( jshex.bytes_to_hex(bytes([self._type.__int__()])), self._hash.__str__(), checksum) def _checksum(self): if self._type.__eq__(UnlockHashType.NIL): return bytes(jsarr.new_array(UnlockHash._CHECKSUM_SIZE)) e = RivineBinaryEncoder() e.add_int8(self._type.value) e.add(self._hash) return jscrypto.blake2b(e.data) def __repr__(self): return self.__str__() def json(self): return self.__str__() def __eq__(self, other): other = UnlockHash._op_other_as_unlockhash(other) return self.uhtype.__eq__(other.uhtype) and self.hash.__eq__( other.hash) def __ne__(self, other): other = UnlockHash._op_other_as_unlockhash(other) return self.uhtype.__ne__(other.uhtype) or self.hash.__ne__(other.hash) def __hash__(self): return hash(self.__str__()) @staticmethod def _op_other_as_unlockhash(other): if isinstance(other, str): other = UnlockHash.from_json(other) elif not isinstance(other, UnlockHash): raise TypeError("UnlockHash of type {} is not supported".format( type(other))) return other def sia_binary_encode(self, encoder): """ Encode this unlock hash according to the Sia Binary Encoding format. """ encoder.add_byte(self._type.__int__()) encoder.add(self._hash) def rivine_binary_encode(self, encoder): """ Encode this unlock hash according to the Rivine Binary Encoding format. """ encoder.add_int8(self._type.__int__()) encoder.add(self._hash)