Skip to content

Commit

Permalink
Merge pull request #128 from dfinity/icrc-3
Browse files Browse the repository at this point in the history
  • Loading branch information
MarioDfinity authored Apr 2, 2024
2 parents ad8358a + 65ed86d commit 7bef69a
Show file tree
Hide file tree
Showing 3 changed files with 560 additions and 0 deletions.
102 changes: 102 additions & 0 deletions standards/ICRC-3/HASHINGVALUES.md
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
```
57 changes: 57 additions & 0 deletions standards/ICRC-3/ICRC-3.did
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;
};
Loading

0 comments on commit 7bef69a

Please sign in to comment.