Chain-of-Custody Zome
Steps to create this zome:
- Define a
Transfer
entry and add it to theentry_defs
#[hdk_entry(id = "resource")]
struct Transfer {
transfer_from: AgentPubKey,
transfer_to: AgentPubKey,
resource_hash: EntryHash,
last_transfer_hash: Option<HeaderHash> // On the first transfer, this will be None
}
entry_defs![Transfer::entry_def()];
-
Add a
transfer_resource(resource_hash: EntryHash, transfer_to: AgentPubKey, last_transfer_hash: Option<HeaderHash>) -> ExternResult<()>
function that:- Gets the public key of the executing agent with agent_info.
- Defines a new
Transfer
struct. - If
last_transfer_hash
isNone
, creates a new transfer entry, and links the resource entry to the transfer hash. - If
last_transfer_hash
exists, updates thelast_transfer_hash
header with theTransfer
struct.
-
Add a
get_resource_trace(resource_hash: EntryHash) -> ExternResult<Vec<(Element, Transfer)>>
that:- Does a
get_links
with the resource hash as the base to get the firstTransfer
. - In a loop:
- Does a get_details with the transfer hash.
- Adds the element and entry to the result vector.
- If there is any update with the entry, continue the loop with the new transfer hash.
- Does a
-
Add the validation functions for the links and the transfer:
#[hdk_extern]
fn validate_create_entry_transfer(data: ValidationData) -> ExternResult<ValidationCallbackResult> {
// Validate that the author of the element matches the `transfer_from` field
// If `last_transfer_hash` doesn't exist:
// - Get the resource with the resource hash
// - Validate that the author of the element matches the owner field of the resource
}
#[hdk_extern]
fn validate_update_entry_transfer(data: ValidationData) -> ExternResult<ValidationCallbackResult> {
// `get_details` from the `last_transfer_hash`
// Validate that the header has not been updated already
// Note: this is what prevents a holder of the resource from transferring twice
}
#[hdk_extern]
fn validate_link(data: ValidationData) -> ExternResult<ValidationCallbackResult> {
// Validate that the author of the link matches the owner of the resource
// Validate that there is only one link attached to the base of the resource
// Note: this prevents the owner of the resource from transferring twice two start
}