def decode_ipfs_hash(hex_hash): """ Decode a Base58 IPFS hash from a 32 byte hex string """ if hex_hash.startswith('0x'): hex_hash = remove_0x_prefix(hex_hash) if not hex_hash.startswith('1220'): hex_hash = '1220' + hex_hash return multihash.to_b58_string(multihash.from_hex_string(hex_hash))
def _validate_asset_file_checksum(href, expected_multihash, asset_multihash): expected_multihash = multihash.decode(from_hex_string(expected_multihash)) logger.debug( 'Validate asset file checksum at %s with multihash %s/%s (from headers), expected %s/%s ' '(from checksum:multishash attribute)', href, to_hex_string(asset_multihash.digest), asset_multihash.name, to_hex_string(expected_multihash.digest), expected_multihash.name) if asset_multihash.name != expected_multihash.name: logger.error( 'Asset at href %s, with multihash name=%s digest=%s, doesn\'t match the expected ' 'multihash name=%s digest=%s defined in checksum:multihash attribute', href, asset_multihash.name, to_hex_string(asset_multihash.digest), expected_multihash.name, to_hex_string(expected_multihash.digest)) raise serializers.ValidationError({ 'href': _(f"Asset at href {href} has a {asset_multihash.name} multihash while a " f"{expected_multihash.name} multihash is defined in the checksum:multihash " "attribute") }) if asset_multihash != expected_multihash: logger.error( 'Asset at href %s, with multihash name=%s digest=%s, doesn\'t match the ' 'checksum:multihash value name=%s digest=%s', href, asset_multihash.name, to_hex_string(asset_multihash.digest), expected_multihash.name, to_hex_string(expected_multihash.digest)) raise serializers.ValidationError({ 'href': _(f"Asset at href {href} with {asset_multihash.name} hash " f"{to_hex_string(asset_multihash.digest)} doesn't match the " f"checksum:multihash {to_hex_string(expected_multihash.digest)}") })
def get_codec(chash): """ Extract the codec of a content hash :param str hash: a hex string containing a content hash :return: the extracted codec :rtype: str """ buffer = multihash.from_hex_string(chash.lstrip('0x')) return multicodec.get_codec(buffer)
def create_multihash(digest, hash_type): '''Returns a multihash from a digest Args: digest: string hash_type: string hash type sha2-256 Returns: multihash multihash ''' return multihash.decode(multihash.encode(multihash.from_hex_string(digest), hash_type))
def encode(value): """ Encode Swarm. :param bytes value: a decoded content :return: the encoded content :rtype: str """ mhash = multihash.encode(multihash.from_hex_string(value), 'keccak-256') return make_cid(1, 'swarm-manifest', mhash).buffer
def ipfs_get_json(ipfs_conn: ipfsapi.client.Client, file_hash: str, tmpdir: Optional[PS] = None) -> Dict[str, Any]: """ Perform an ipfs.get and return the json object as a Python dict """ if isinstance(file_hash, bytes): file_hash = to_b58_string( from_hex_string('1220' + remove_0x_prefix(file_hash.hex()))) elif is_0x_prefixed(file_hash): file_hash = to_b58_string( from_hex_string('1220' + remove_0x_prefix(file_hash))) elif is_hex(file_hash): file_hash = to_b58_string(from_hex_string('1220' + file_hash)) elif file_hash.startswith('Qm'): pass else: raise ValueError("Invalid file_hash") with tempfile.TemporaryDirectory(dir=tmpdir) as _workdir: workdir = Path(_workdir) orig_dir = Path.cwd() assert orig_dir is not None os.chdir(workdir) ipfs_conn.get(file_hash) downloaded: Path = workdir.joinpath(file_hash) if not downloaded.exists() or not downloaded.is_file(): raise ScatterError("Download filed. File not found.") contents = '' with downloaded.open() as _userfile: userfile_text = _userfile.read() print("Downloaded... {}".format(userfile_text)) contents = json.loads(userfile_text) os.chdir(orig_dir) downloaded.unlink() return contents
def parse_multihash(multihash_string): '''Parse a multihash string Args: multihash_string: string multihash string to parse Returns. Multihash object Raises: TypeError: if incoming data is not a string ValueError: if the incoming data is not a valid multihash ''' return multihash.decode(multihash.from_hex_string(multihash_string))
def decode(chash): """ Decode a content hash. :param str hash: a hex string containing a content hash :return: the decoded content :rtype: str """ buffer = multihash.from_hex_string(chash.lstrip('0x')) codec = multicodec.get_codec(buffer) value = multicodec.remove_prefix(buffer) profile = get_profile(codec) return profile.decode(value)
def validate_asset_multihash(value): '''Validate the Asset multihash field The field value must be a multihash string Args: value: string multihash value Raises: ValidationError in case of invalid multihash value ''' try: mhash = multihash.decode(multihash.from_hex_string(value)) except ValueError as error: logger.error("Invalid multihash %s; %s", value, error) raise ValidationError(code='checksum:multihash', message=_('Invalid multihash value; %(error)s'), params={'error': error})
def validate_checksum_multihash_sha256(value): '''Validate the checksum multihash field The field value must be a multihash sha256 string Args: value: string multihash value Raises: ValidationError in case of invalid multihash value ''' try: mhash = multihash.decode(multihash.from_hex_string(value)) except (ValueError, TypeError) as error: logger.error("Invalid multihash %s; %s", value, error) raise ValidationError(_('Invalid multihash value; %(error)s'), params={'error': error}, code='invalid') from None if mhash.code != HASH_CODES['sha2-256']: logger.error("Invalid multihash value: must be sha2-256 but is %s", CODE_HASHES[mhash.code]) raise ValidationError(_('Invalid multihash value: must be sha2-256 but is %(code)s'), params={'code': CODE_HASHES[mhash.code]}, code='invalid')
def test_check_sum_sha256(): """Test basic check_sum multihash generation.""" with TemporaryDirectory() as tmp: tmp_file = Path(tmp) / 'file.txt' message = 'Testing' with open(tmp_file, 'w') as f: f.write(message) _hash = multihash_checksum_sha256(tmp_file) expected_hash = '1220e806a291cfc3e61f83b98d344ee57e3e8933cccece4fb45e1481f1f560e70eb1' assert _hash == expected_hash # Try using stream instead file stream = BytesIO(message.encode()) stream_hash = multihash_checksum_sha256(stream) assert stream_hash == expected_hash digest = multihash.from_hex_string(_hash) # Ensure digest is a multihash assert multihash.is_valid(digest)
def test_from_hex_string_invalid_type(self, value): """ from_hex_string: raises TypeError for invalid types """ with pytest.raises(TypeError) as excinfo: from_hex_string(value) assert 'multihash should be str' in str(excinfo.value)
def test_from_digest_string_valid(self, value): """ from_hex_string: decodes the correct values """ code = value['encoding']['code'] buffer = encode(bytes.fromhex(value['hex']), code) assert from_hex_string(hexlify(buffer).decode()) == buffer
def test_valid_from_hex_string(self, valid): for case in valid: code = case['encoding']['code'] buf = multihash.encode(bytes.fromhex(case['hex']), code) assert multihash.from_hex_string(hexlify(buf).decode()) == buf