The validation functions are the heart of ensuring distributed data integrity. Please consider them thoroughly and carefully as your systems data integrity is built from them.
Validation functions are called under two distinct conditions.
-
When data is about to be added to the local chain (validateCommit).
-
Whenever any node of the DHT receives a request to store or change data in some way, the request and the changes are validated against the source chain of the person making the request (validatePut,validateLink.) These are the validation functions that check permissions and enforce any other kind of data integrity you intend to preserve. For example, in a distributed Twitter, only Bob should be able to attach (link) a "post" to Bob as if it is his, and only Bob should be able to link Bob as a "follower" of Alice. Please keep in mind that system variables like App.Agent.Hash that return your own address will not return YOUR address when being executed by a remote DHT node. Code your functions as if anyone will be running them, because they will be.
Common parameters:
header
the header for the entry, type Header-objectpackage
the data package created by validateXPkg, type Package-object-
sources
an array of strings (hash-string) of agents that were involved in taking the action. This parameter will be useful for validation when you want to check if the content created relates in the proper way to the actor.
A Header-object looks like this:
{ "EntryLink": "QmSGQSdWpgcAPUrSJsz9rvNu75qc1W6AMe8sBYNasK3sbE", "Time": "2018-03-21T11:37:15Z", "Type": "sampleEntry" }
A Package-object can be (and often is) simply null
, but it can look like this (click the arrow to expand it):
HC.PkgReq.ChainOpt.Full
option, this is what the corresponding Package-object looks like. { "Chain":{ "Emap":{ "QmNguhukN2MEELRK5mZw7TBefh9vX2yLbxw43QEV9t4XVw":0, "QmSDAaTvrfbcwyqLS1XKUTfTnThJFhbfknKatuMHTVuEyj":1, "QmSGQSdWpgcAPUrSJsz9rvNu75qc1W6AMe8sBYNasK3sbE":2 }, "Entries":[ { "C":"ewogICAgI...F0KfQo=" }, { "C":{ "Identity":"user@test.com", "PublicKey":"CAESIIcqftcYvOZEv68EqoK9qg2MHfG3mOit7XxSLEK9nyoD", "Revocation":null } }, { "C":"{\"content\":\"this is the entry body\",\"timestamp\":12345}" } ], "Hashes":[ { "H":"EiDFxJb8TaLCPlxMAnyRQgfy8VGUO8YtsruC8ReVItlbWw==" }, { "H":"EiD93rzLG+9mnZljmtv82jxfzZpaD6zG/lo/C9wB5fK8AQ==" }, { "H":"EiCoiVOt4C9FMHrgUVxoXRUhhZgktw++30rJ8/0Sb7IXyQ==" } ], "Headers":[ { "Change":{ "Action":"", "Hash":{ "H":"AA==" } }, "EntryLink":{ "H":"EiAFMJKqCpm7+cWS4EjW1/ZGbt4zATjP2G2LM9Wg0FG07g==" }, "HeaderLink":{ "H":"AA==" }, "Sig":{ "S":"Y5eim7v/04hBT27/p0/X+bDFlalR4T29oxCKycaSzCRmgmnbHQ2SEeXVE147xcWvzdCXm+MNpXv3vjdXOGoDDA==" }, "Time":"2018-03-21T08:39:48.979488-04:00", "Type":"%dna", "TypeLink":{ "H":"AA==" } }, { "Change":{ "Action":"", "Hash":{ "H":"AA==" } }, "EntryLink":{ "H":"EiA5g9+VLSyKXibwpLDMZ1phPnvZOOxrXScrEs5azEnDzg==" }, "HeaderLink":{ "H":"EiDFxJb8TaLCPlxMAnyRQgfy8VGUO8YtsruC8ReVItlbWw==" }, "Sig":{ "S":"kTG7OuEgLsv+zJwvOLMCkQkv/0R9I9cgyJ/Je49Rk0haUVZOPRrBZCNn4rm5RLixPN63c8MpfVsAPTxRuyy+DA==" }, "Time":"2018-03-21T08:39:48.979833-04:00", "Type":"%agent", "TypeLink":{ "H":"AA==" } }, { "Change":{ "Action":"", "Hash":{ "H":"AA==" } }, "EntryLink":{ "H":"EiA6WEr8LmyCA722R6fAx3bnthzNomGktZqmTwpoZNAPOQ==" }, "HeaderLink":{ "H":"EiD93rzLG+9mnZljmtv82jxfzZpaD6zG/lo/C9wB5fK8AQ==" }, "Sig":{ "S":"EGVMKvlDyOB8ZPkdiI6pQJKhKAvIiMMN/02XAGt9q9IiYt7OuVy0dJD1YdTcIQaDh0SRL2tLnNowdGsEQM87Bw==" }, "Time":"2018-03-21T08:39:48.991196-04:00", "Type":"sampleEntry", "TypeLink":{ "H":"AA==" } } ], "Hmap":{ "QmZgYexq1BVd2yPcWETtPHVBSdrTFjBEKy8nJxenYKqrcx":2, "QmbeetdahFrDJqpggXHj8q4jk3hNsZz3Cs8QWmZbUsuoFQ":0, "QmfRer6JyLsjGCSdQ9zhqzUG4y9xDCZbSdxHNofHHLK2px":1 }, "TypeTops":{ "%agent":1, "%dna":0, "sampleEntry":2 } } }
A sources object looks like this:
["12ixijdsi..."]
A Link-object looks like this:
{ "Base": "Qmb3XtdnuqCRWaWPfiMtAnGjhRDKLTrLgr2TJGFKqFoA3x", "Link": "QmSGQSdWpgcAPUrSJsz9rvNu75qc1W6AMe8sBYNasK3sbE", "Tag": "relation", "LinkAction": "" }
Go back to the API documentation.