holo_hash::HoloHash is a hashing framework for Holochain.
Note that not all HoloHashes are simple hashes of the full content as you might expect in a "content-addressable" application. The main exception is AgentPubKey
, which is simply the key itself to enable self-proving signatures. As an exception it is also named exceptionally, i.e. it doesn't end in "Hash".
Each HoloHash has a HashType. There are two flavors of HashType: primitive, and composite
Each primitive HashType has a unique 3-byte prefix associated with it, to easily distiguish between hashes in any environment. These prefixes are multihash compatible. The primitive types are:
| hash type | HoloHash alias | prefix | |-----------|----------------|--------| | Agent | AgentPubKey | uhCAk | | Entry | EntryHash | uhCEk | | DhtOp | DhtOpHash | uhCQk | | Dna | DnaHash | uhC0k | | NetId | NetIdHash | uhCIk | | Header | HeaderHash | uhCkk | | Wasm | DnaWasmHash | uhCok |
The "HoloHash alias" column lists the type aliases provided to refer to each type of HoloHash. For instance, HeaderHash
is the following type alias:
rust
pub type HeaderHash = HoloHash<hash_type::Header>;
(the prefixes listed are the base64 representations)
Composite hash types are used in contexts when one of several primitive hash types would be valid. They are implemented as Rust enums. The composite types are:
EntryHash
: used to hash Entries. An Entry can hash to either a ContentHash
or an AgentPubKey
.
AnyDhtHash
: used to hash arbitrary DHT data. DHT data is either a Header or an Entry, therefore AnyDhtHash can refer to either a HeaderHash
or an EntryHash
.
HoloHash implements Display
providing a to_string()
function accessing the hash as a user friendly string. It also provides TryFrom for string types allowing you to parse this string representation.
HoloHash includes a 4 byte (or u32) dht "location" that serves dual purposes. - It is used as a checksum when parsing string representations. - It is used as a u32 in our dht sharding algorithm.
HoloHash implements SerializedBytes to make it easy to cross ffi barriers such as WASM and the UI websocket.
```rust use holohash::*; use std::convert::TryInto; use holochainserialized_bytes::SerializedBytes;
let entry: EntryHash = "uhCEkWCsAgoKkkfwyJAglj30xXGLLV-3BXuFy436a2SqpcEwyBzm" .tryinto() .unwrap();
asserteq!(3860645936, entry.getloc());
let bytes: SerializedBytes = entry.try_into().unwrap();
assert_eq!( "{\"type\":\"EntryHash\",\"hash\":[88,43,0,130,130,164,145,252,50,36,8,37,143,125,49,95,241,139,45,95,183,5,123,133,203,141,250,107,100,170,165,193,48,200,28,230]}", &format!("{:?}", bytes), ); ```
Calculating hashes takes time - In a futures context we don't want to block. HoloHash provides sync (blocking) and async (non-blocking) apis for hashing.
```rust use holo_hash::*;
let entry_content = b"test entry content";
let contenthash = EntryHash::withdatasync(entrycontent.to_vec()).into();
asserteq!( "EntryHash(uhCEkhPbA5vaw3Fk-ZvPSKuyyjg8eoX98fve75qiUEFgAE3BO7D4d)", &format!("{:?}", contenthash), ); ```
```rust use holo_hash::*;
// pretend our pub key is all 0xdb bytes let agentpubkey = vec![0xdb; 32];
let agentid: HoloHash = AgentPubKey::fromraw32(agentpub_key).into();
asserteq!( "AgentPubKey(uhCAk29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uTp5Iv)", &format!("{:?}", agentid), ); ```
Holochain is an open source project. We welcome all sorts of participation and are actively working on increasing surface area to accept it. Please see our contributing guidelines for our general practices and protocols on participating in the community, as well as specific expectations around things like code formatting, testing practices, continuous integration, etc.
Copyright (C) 2019 - 2021, Holochain Foundation
This program is free software: you can redistribute it and/or modify it under the terms of the license provided in the LICENSE file (CAL-1.0). This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.