-
Notifications
You must be signed in to change notification settings - Fork 33
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #128 from dfinity/icrc-3
- Loading branch information
Showing
3 changed files
with
560 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,102 @@ | ||
## Representation independent hashing | ||
|
||
The following pseudocode specifies how to calculate the (representation independent) hash of an element of the Value type. Some test vectors to check compliance of an implementation with this specification follow. | ||
|
||
``` | ||
type Value = variant { | ||
Blob : blob, | ||
Text : text, | ||
Nat : nat, | ||
Int : int, | ||
Array : vec Value, | ||
Map : vec (text, Value) | ||
}; | ||
Function hash_value(value) | ||
Initialize hasher as a new instance of SHA256 | ||
Match value with | ||
Nat: | ||
Return SHA256_hash(LEB128_encode(value)) | ||
Int: | ||
Return SHA256_hash(SLEB128_encode(value)) | ||
Text: | ||
Return SHA256_hash(UTF8_encode(value)) | ||
Blob: | ||
Return SHA256_hash(value) | ||
Array: | ||
For each element in value | ||
Update hasher with hash_value(element) | ||
Return hasher.finalize() | ||
Map: | ||
Initialize hashes as empty list | ||
For each (key, val) in value | ||
Add (SHA256_hash(UTF8_encode(key)), hash_value(val)) to hashes | ||
Sort hashes in lexicographical order | ||
For each (key_hash, val_hash) in hashes | ||
Update hasher with key_hash | ||
Update hasher with val_hash | ||
Return hasher.finalize() | ||
Else: | ||
Return error "unsupported value type" | ||
End Function | ||
Function LEB128_encode(nat_input) | ||
Convert nat_input to LEB128 byte encoding | ||
End Function | ||
Function SLEB128_encode(integer_input) | ||
Convert integer_input to SLEB128 byte encoding | ||
End Function | ||
Function UTF8_encode(text) | ||
Convert text to UTF-8 byte array and return it | ||
End Function | ||
Function SHA256_hash(data) | ||
Initialize a new SHA256 hasher | ||
Update hasher with data | ||
Return hasher.finalize() | ||
End Function | ||
``` | ||
|
||
## Test vectors | ||
|
||
|
||
```ignorelang | ||
input: Nat(42) | ||
expected output: 684888c0ebb17f374298b65ee2807526c066094c701bcc7ebbe1c1095f494fc1 | ||
``` | ||
|
||
```ignorelang | ||
input: Int(-42) | ||
expected output: de5a6f78116eca62d7fc5ce159d23ae6b889b365a1739ad2cf36f925a140d0cc | ||
``` | ||
|
||
|
||
```ignorelang | ||
input: Text("Hello, World!"), | ||
expected output: dffd6021bb2bd5b0af676290809ec3a53191dd81c7f70a4b28688a362182986f | ||
``` | ||
|
||
```ignorelang | ||
input: Blob(b'\x01\x02\x03\x04') | ||
expected output: 9f64a747e1b97f131fabb6b447296c9b6f0201e79fb3c5356e6c77e89b6a806a | ||
``` | ||
|
||
```ignorelang | ||
input: Array([Nat(3), Text("foo"), Blob(b'\x05\x06')]) | ||
expected output: 514a04011caa503990d446b7dec5d79e19c221ae607fb08b2848c67734d468d6 | ||
``` | ||
|
||
```ignorelang | ||
input: Map([("from", Blob(b'\x00\xab\xcd\xef\x00\x12\x34\x00\x56\x78\x9a\x00\xbc\xde\xf0\x00\x01\x23\x45\x67\x89\x00\xab\xcd\xef\x01')), | ||
("to", Blob(b'\x00\xab\x0d\xef\x00\x12\x34\x00\x56\x78\x9a\x00\xbc\xde\xf0\x00\x01\x23\x45\x67\x89\x00\xab\xcd\xef\x01')), | ||
("amount", Nat(42)), | ||
("created_at", Nat(1699218263)), | ||
("memo", Nat(0)) | ||
]) | ||
expected output: c56ece650e1de4269c5bdeff7875949e3e2033f85b2d193c2ff4f7f78bdcfc75 | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
type Value = variant { | ||
Blob : blob; | ||
Text : text; | ||
Nat : nat; | ||
Int : int; | ||
Array : vec Value; | ||
Map : vec record { text; Value }; | ||
}; | ||
|
||
type GetArchivesArgs = record { | ||
// The last archive seen by the client. | ||
// The Ledger will return archives coming | ||
// after this one if set, otherwise it | ||
// will return the first archives. | ||
from : opt principal; | ||
}; | ||
|
||
type GetArchivesResult = vec record { | ||
// The id of the archive | ||
canister_id : principal; | ||
|
||
// The first block in the archive | ||
start : nat; | ||
|
||
// The last block in the archive | ||
end : nat; | ||
}; | ||
|
||
type GetBlocksArgs = vec record { start : nat; length : nat }; | ||
|
||
type GetBlocksResult = record { | ||
// Total number of blocks in the | ||
// block log | ||
log_length : nat; | ||
|
||
blocks : vec record { id : nat; block: Value }; | ||
|
||
archived_blocks : vec record { | ||
args : GetBlocksArgs; | ||
callback : func (GetBlocksArgs) -> (GetBlocksResult) query; | ||
}; | ||
}; | ||
|
||
type DataCertificate = record { | ||
// See https://internetcomputer.org/docs/current/references/ic-interface-spec#certification | ||
certificate : blob; | ||
|
||
// CBOR encoded hash_tree | ||
hash_tree : blob; | ||
}; | ||
|
||
service : { | ||
icrc3_get_archives : (GetArchivesArgs) -> (GetArchivesResult) query; | ||
icrc3_get_tip_certificate : () -> (opt DataCertificate) query; | ||
icrc3_get_blocks : (GetBlocksArgs) -> (GetBlocksResult) query; | ||
icrc3_supported_block_types : () -> (vec record { block_type : text; url : text }) query; | ||
}; |
Oops, something went wrong.