From c856aa4d8b9b9cc73824a166122b91384078fcb8 Mon Sep 17 00:00:00 2001 From: freedomhero Date: Tue, 23 Nov 2021 11:45:39 +0800 Subject: [PATCH 1/4] add doc for generic types & HashedSet --- docs/contracts.rst | 86 ++++++++++++++++++++++++++++++++++++++++++---- docs/syntax.rst | 28 +++++++++++++++ 2 files changed, 108 insertions(+), 6 deletions(-) diff --git a/docs/contracts.rst b/docs/contracts.rst index f1fd340..850d202 100644 --- a/docs/contracts.rst +++ b/docs/contracts.rst @@ -221,6 +221,71 @@ Most functions of `HashedMap` require not only a key, but also its index, ranked // this creates a deep copy of the map HashedMap mapCopy = new HashedMap(b); +Library ``HashedSet`` +----------------------- + +The `HashedSet` library provides a set-like data structure. +Unique values are hashed before being stored. +Most functions of `HashedSet` require an index, ranked by the value's sha256 hash in ascending order. + +**Constructor** + +* ``HashedSet(bytes data)`` + Create an instance of ``HashedSet`` with some initial data. + + .. code-block:: solidity + + HashedSet set = new HashedSet(b''); + // key and value types can be omitted + HashedSet set1 = new HashedSet(b''); + // key and value types cannot be omitted since they cannot be inferred + auto set2 = new HashedSet(b''); + +**Instance methods** + +* ``add(V val, int index) : bool`` + Add `val` to set with the key index given by `index`. Returns `true` if successful; otherwise returns `false`. + + .. code-block:: solidity + + require(set.add(b'1234', 0)); + +* ``has(V val, int index) : bool`` + Check whether `val` exists in the set and its index is `index`. Returns `true` if both conditions are met; otherwise returns `false`. + + .. code-block:: solidity + + require(set.has(b'1234', 0)); + +* ``delete(V val, int index) : bool`` + Delete the entry with given `val` and the index is `index`. Returns `true` if successful; otherwise returns `false`. + + .. code-block:: solidity + + require(set.delete(b'1234', 0)); + +* ``clear() : bool`` + Delete all entries of the set. + + .. code-block:: solidity + + set.clear(); + +* ``size() : int`` + Returns the size of set, i.e. the number of the entries it contains. + + .. code-block:: solidity + + int s = set.size(); + +* ``data() : bytes`` + Returns the internal data representation of the set. + + .. code-block:: solidity + + bytes b = set.data(); + // this creates a deep copy of the set + HashedSet setCopy = new HashedSet(b); Full List --------- @@ -251,12 +316,21 @@ Full List * - HashedMap - bytes data - - set(K key, V val, int keyIndex) - canGet(K key, V val, int keyIndex) - delete(K key, int keyIndex) - has(K key, int keyIndex) - size() - data() + - | set(K key, V val, int keyIndex) + | canGet(K key, V val, int keyIndex) + | delete(K key, int keyIndex) + | has(K key, int keyIndex) + | size() + | data() + + * - HashedSet + - bytes data + - | add(V val, int index) + | delete(V val, int index) + | has(V val, int index) + | clear() + | size() + | data() .. [#] ``X`` is hashing function and can be Ripemd160/Sha1/Sha256/Hash160 .. [#] ``Y`` is hashing function return type and can be Ripemd160/Sha1/Sha256/Ripemd160 diff --git a/docs/syntax.rst b/docs/syntax.rst index d7cc9cd..8095bdf 100644 --- a/docs/syntax.rst +++ b/docs/syntax.rst @@ -168,6 +168,34 @@ Type aliases create a new name for a type. It does not actually create a new typ type Age = int; type Coordinate = int[2]; +Generic Types +------------- +A generic type is a special type that is parameterized over types, it allows a library to work over a variety of types rather than a single one. Users can consume these libraries and use their own types. + +* **Declare Generic Types** + +Generic types can only be declared in a library, and used within the library's scope. + + .. code-block:: solidity + + // declare two generic types: K & V + library HashedMap { + + // use them as function parameters' type + function set(K k, V v, int idx) { + ... + } + + } + +* **Instantiate Generic Types** + + .. code-block:: solidity + + HashedMap map = new HashedMap(); + map.set(b'01', 1, 0); + map.set(2, 1, 1); // this will throw semantic error for the first argument's type `int`, which expects `bytes` + Domain Subtypes =============== There are several subtypes, specific to the Bitcoin context, used to further improve type safety. From c49315428a54ed263605a17b28d3afc17967d4bc Mon Sep 17 00:00:00 2001 From: Xiaohui Date: Tue, 23 Nov 2021 09:32:39 -0800 Subject: [PATCH 2/4] improve syntax --- docs/contracts.rst | 1 + docs/syntax.rst | 13 +++++++------ 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/docs/contracts.rst b/docs/contracts.rst index 850d202..dd62434 100644 --- a/docs/contracts.rst +++ b/docs/contracts.rst @@ -225,6 +225,7 @@ Library ``HashedSet`` ----------------------- The `HashedSet` library provides a set-like data structure. +It can be regarded as a special `HashedMap` where a value is the same with its key and is thus omitted. Unique values are hashed before being stored. Most functions of `HashedSet` require an index, ranked by the value's sha256 hash in ascending order. diff --git a/docs/syntax.rst b/docs/syntax.rst index 8095bdf..df9e9c5 100644 --- a/docs/syntax.rst +++ b/docs/syntax.rst @@ -168,18 +168,19 @@ Type aliases create a new name for a type. It does not actually create a new typ type Age = int; type Coordinate = int[2]; -Generic Types -------------- -A generic type is a special type that is parameterized over types, it allows a library to work over a variety of types rather than a single one. Users can consume these libraries and use their own types. +Generics/Generic Types +---------------------- +A generic type is a parameterized type. It allows a library to work over a variety of types rather than a single one. +Users can consume these libraries and use their own concrete types. * **Declare Generic Types** -Generic types can only be declared in a library, and used within the library's scope. +Generic types can only be declared at library level and used within the library's scope. .. code-block:: solidity - // declare two generic types: K & V - library HashedMap { + // declare two generic type variables: K & V + library HashedMap { // use them as function parameters' type function set(K k, V v, int idx) { From 1ec17b2ca61b5355d5bb002496f9eafb4bbf1bc0 Mon Sep 17 00:00:00 2001 From: freedomhero Date: Wed, 24 Nov 2021 20:54:51 +0800 Subject: [PATCH 3/4] add doc for `flattenSha256` & minor fix --- docs/contracts.rst | 24 ++++++++++++++---------- docs/functions.rst | 7 +++++++ 2 files changed, 21 insertions(+), 10 deletions(-) diff --git a/docs/contracts.rst b/docs/contracts.rst index dd62434..d15bc4a 100644 --- a/docs/contracts.rst +++ b/docs/contracts.rst @@ -235,31 +235,35 @@ Most functions of `HashedSet` require an index, ranked by the value's sha256 has Create an instance of ``HashedSet`` with some initial data. .. code-block:: solidity + struct ST { + int x; + bool y; + } - HashedSet set = new HashedSet(b''); + HashedSet set = new HashedSet(b''); // key and value types can be omitted - HashedSet set1 = new HashedSet(b''); + HashedSet set1 = new HashedSet(b''); // key and value types cannot be omitted since they cannot be inferred - auto set2 = new HashedSet(b''); + auto set2 = new HashedSet(b''); **Instance methods** -* ``add(V val, int index) : bool`` - Add `val` to set with the key index given by `index`. Returns `true` if successful; otherwise returns `false`. +* ``add(E entry, int index) : bool`` + Add `entry` to set with the key index given by `index`. Returns `true` if successful; otherwise returns `false`. .. code-block:: solidity require(set.add(b'1234', 0)); -* ``has(V val, int index) : bool`` - Check whether `val` exists in the set and its index is `index`. Returns `true` if both conditions are met; otherwise returns `false`. +* ``has(E entry, int index) : bool`` + Check whether `entry` exists in the set and its index is `index`. Returns `true` if both conditions are met; otherwise returns `false`. .. code-block:: solidity require(set.has(b'1234', 0)); -* ``delete(V val, int index) : bool`` - Delete the entry with given `val` and the index is `index`. Returns `true` if successful; otherwise returns `false`. +* ``delete(E entry, int index) : bool`` + Delete the entry with given `entry` and the index is `index`. Returns `true` if successful; otherwise returns `false`. .. code-block:: solidity @@ -286,7 +290,7 @@ Most functions of `HashedSet` require an index, ranked by the value's sha256 has bytes b = set.data(); // this creates a deep copy of the set - HashedSet setCopy = new HashedSet(b); + HashedSet setCopy = new HashedSet(b); Full List --------- diff --git a/docs/functions.rst b/docs/functions.rst index 6451186..27ae958 100644 --- a/docs/functions.rst +++ b/docs/functions.rst @@ -123,6 +123,13 @@ Hashing sha256(sha256(b)) +* ``Sha256 flattenSha256(T a)`` + + Returns a Sha256 bytes for the given argument ``a`` of any type. ``T`` here is a generic type which can be any basic type or user-defined struct type. + If `T` is a basic type, like ``bool`` / ``int`` / ``bytes``, the return is the same as ``sha256(a)``. + Otherwise connect all the sha256 values for each flattened fields of `a` to form a joint bytes, and then call `sha256` on it to get the final result. + + Signature Verification ---------------------- * ``bool checkSig(Sig sig, PubKey pk)`` From ecedc08b41bfffd55f478c4a72d9ca062b0eb4e9 Mon Sep 17 00:00:00 2001 From: freedomhero Date: Thu, 25 Nov 2021 13:34:01 +0800 Subject: [PATCH 4/4] minor fix --- docs/contracts.rst | 8 ++++++++ docs/functions.rst | 7 +++---- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/docs/contracts.rst b/docs/contracts.rst index d15bc4a..f984451 100644 --- a/docs/contracts.rst +++ b/docs/contracts.rst @@ -204,6 +204,13 @@ Most functions of `HashedMap` require not only a key, but also its index, ranked require(map.delete(b'1234', 0)); +* ``clear() : bool`` + Delete all entries of the map. + + .. code-block:: solidity + + map.clear(); + * ``size() : int`` Returns the size of map, i.e. the number of the keys it contains. @@ -325,6 +332,7 @@ Full List | canGet(K key, V val, int keyIndex) | delete(K key, int keyIndex) | has(K key, int keyIndex) + | clear() | size() | data() diff --git a/docs/functions.rst b/docs/functions.rst index 27ae958..abd2816 100644 --- a/docs/functions.rst +++ b/docs/functions.rst @@ -125,10 +125,9 @@ Hashing * ``Sha256 flattenSha256(T a)`` - Returns a Sha256 bytes for the given argument ``a`` of any type. ``T`` here is a generic type which can be any basic type or user-defined struct type. - If `T` is a basic type, like ``bool`` / ``int`` / ``bytes``, the return is the same as ``sha256(a)``. - Otherwise connect all the sha256 values for each flattened fields of `a` to form a joint bytes, and then call `sha256` on it to get the final result. - + Returns Sha256 for the given argument a of any type. + If ``T`` is a basic type, like ``bool / int / bytes``, the return is the same as ``sha256(a)``. + If ``T`` is a composite type (i.e., array and struct), it concatenates all the sha256 values for each flattened fields of a to form a joint bytes, and then call ``sha256`` on it to get the final result. Signature Verification ----------------------