solidity-scale-codec 2.1.1 → 2.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/guides/Definitions.md +186 -0
- package/package.json +2 -2
- package/src/Scale/Array/BoolArr.sol +3 -3
- package/src/Scale/Array/I128Arr.sol +3 -3
- package/src/Scale/Array/I16Arr.sol +3 -3
- package/src/Scale/Array/I256Arr.sol +3 -3
- package/src/Scale/Array/I32Arr.sol +3 -3
- package/src/Scale/Array/I64Arr.sol +3 -3
- package/src/Scale/Array/I8Arr.sol +3 -3
- package/src/Scale/Array/U128Arr.sol +3 -3
- package/src/Scale/Array/U16Arr.sol +3 -3
- package/src/Scale/Array/U256Arr.sol +3 -3
- package/src/Scale/Array/U32Arr.sol +3 -3
- package/src/Scale/Array/U64Arr.sol +3 -3
- package/src/Scale/Array/U8Arr.sol +3 -3
- package/src/Scale/Array.sol +14 -15
- package/src/Scale/Compact/Compact.sol +2 -4
- package/src/Scale/Signed/I128.sol +14 -9
- package/src/Scale/Signed/I16.sol +11 -8
- package/src/Scale/Signed/I256.sol +14 -9
- package/src/Scale/Signed/I32.sol +11 -8
- package/src/Scale/Signed/I64.sol +11 -8
- package/src/Scale/Signed/I8.sol +11 -8
- package/src/Scale/Signed.sol +7 -8
- package/src/Scale/Unsigned.sol +7 -8
- package/src/Xcm/v3/MaybeErrorCode/MaybeErrorCodeCodec.sol +6 -1
- package/src/Xcm/v5/AssetFilter/AssetFilterCodec.sol +6 -1
- package/src/Xcm/v5/AssetInstance/AssetInstanceCodec.sol +9 -1
- package/src/Xcm/v5/AssetTransferFilter/AssetTransferFilterCodec.sol +7 -1
- package/src/Xcm/v5/BodyPart/BodyPartCodec.sol +8 -1
- package/src/Xcm/v5/Fungibility/FungibilityCodec.sol +6 -1
- package/src/Xcm/v5/Instruction/InstructionCodec.sol +1295 -1246
- package/src/Xcm/v5/Junction/JunctionCodec.sol +13 -1
- package/src/Xcm/v5/NetworkId/NetworkIdCodec.sol +7 -1
- package/src/Xcm/v5/Response/ResponseCodec.sol +9 -1
- package/src/Xcm/v5/WeightLimit/WeightLimitCodec.sol +5 -1
- package/src/Xcm/v5/WildAsset/WildAssetCodec.sol +7 -1
- package/src/Xcm/v5/Xcm/XcmBuilder.sol +101 -1
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
> Note: These definitions were taken from https://github.com/w3f/polkadot-spec/blob/main/docs. They are provided here for reference. All credits to respective authors.
|
|
2
|
+
|
|
3
|
+
# SCALE
|
|
4
|
+
|
|
5
|
+
The Polkadot Host uses _Simple Concatenated Aggregate Little-Endian” (SCALE) codec_ to encode byte arrays as well as other data structures. SCALE provides a canonical encoding to produce consistent hash values across their implementation, including the Merkle hash proof for the State Storage.
|
|
6
|
+
|
|
7
|
+
## Decoding
|
|
8
|
+
|
|
9
|
+
$\text{Dec}_{{\text{SC}}}{\left({d}\right)}$ refers to the decoding of a blob of data. Since the SCALE codec is not self-describing, it’s up to the decoder to validate whether the blob of data can be deserialized into the given type or data structure.
|
|
10
|
+
|
|
11
|
+
It’s accepted behavior for the decoder to partially decode the blob of data. This means any additional data that does not fit into a data structure can be ignored.
|
|
12
|
+
|
|
13
|
+
> caution
|
|
14
|
+
> Considering that the decoded data is never larger than the encoded message, this information can serve as a way to validate values that can vary in size, such as [sequences](#sequence). The decoder should strictly use the size of the encoded data as an upper bound when decoding in order to prevent denial of service attacks.
|
|
15
|
+
|
|
16
|
+
# Notation
|
|
17
|
+
|
|
18
|
+
- Let $\mathbb{{B}}$ be the set of all byte sequences.
|
|
19
|
+
- Let $x \in \mathbb{{B}}$, $x_i$ denotes the $i$-th byte of $x$, and $x_i^j$ denotes the $j$-th bit of the $i$-th byte of $x$.
|
|
20
|
+
|
|
21
|
+
# Definitions
|
|
22
|
+
|
|
23
|
+
## Little Endian
|
|
24
|
+
|
|
25
|
+
By the **little-endian** representation of a non-negative integer, ${I}$, represented as
|
|
26
|
+
|
|
27
|
+
$$
|
|
28
|
+
{I}={\left({B}_{{n}}\ldots{B}_{{0}}\right)}_{{256}}
|
|
29
|
+
$$
|
|
30
|
+
|
|
31
|
+
in base 256, we refer to a byte array ${B}={\left({b}_{{0}},{b}_{{1}},\ldots,{b}_{{n}}\right)}$ such that
|
|
32
|
+
|
|
33
|
+
$$
|
|
34
|
+
{b}_{{i}}\:={B}_{{i}}
|
|
35
|
+
$$
|
|
36
|
+
|
|
37
|
+
Accordingly, we define the function ${\mathsf{\text{Enc}}}_{{{\mathsf{\text{LE}}}}}$:
|
|
38
|
+
|
|
39
|
+
$$
|
|
40
|
+
{\mathsf{\text{Enc}}}_{{{\mathsf{\text{LE}}}}}:{\mathbb{{Z}}}^{+}\rightarrow{\mathbb{{B}}};{\left({B}_{{n}}\ldots{B}_{{0}}\right)}_{{256}}{\mid}\rightarrow{\left({B}_{{{0},}}{B}_{{1}},\ldots,{B}_{{n}}\right)}
|
|
41
|
+
$$
|
|
42
|
+
|
|
43
|
+
## Scale Types
|
|
44
|
+
|
|
45
|
+
### Fixed Length Integers
|
|
46
|
+
|
|
47
|
+
The SCALE codec, $\text{Enc}_{{\text{SC}}}$, for fixed length integers not defined here otherwise, is equal to the little-endian encoding of those values.
|
|
48
|
+
|
|
49
|
+
### Tuple
|
|
50
|
+
|
|
51
|
+
The **SCALE codec** for **Tuple**, ${T}$, such that:
|
|
52
|
+
|
|
53
|
+
$$
|
|
54
|
+
{T}\:={\left({A}_{{1}},\ldots{A}_{{n}}\right)}
|
|
55
|
+
$$
|
|
56
|
+
|
|
57
|
+
Where ${A}_{{i}}$’s are values of **different types**, is defined as:
|
|
58
|
+
|
|
59
|
+
$$
|
|
60
|
+
\text{Enc}_{{\text{SC}}}{\left({T}\right)}\:=\text{Enc}_{{\text{SC}}}{\left({A}_{{1}}\right)}\text{||}\text{Enc}_{{\text{SC}}}{\left({A}_{{2}}\right)}\text{||}\ldots\text{||}\text{Enc}_{{\text{SC}}}{\left({A}_{{n}}\right)}
|
|
61
|
+
$$
|
|
62
|
+
|
|
63
|
+
In the case of a tuple (or a structure), the knowledge of the shape of data is not encoded even though it is necessary for decoding. The decoder needs to derive that information from the context where the encoding/decoding is happening.
|
|
64
|
+
|
|
65
|
+
### Varying Data Type
|
|
66
|
+
|
|
67
|
+
> This library does not provide means for encoding/decoding varying data types, but the definitions are provided here for completeness and reference. The implementation is left to the user of the library.
|
|
68
|
+
|
|
69
|
+
We define a **varying data** type to be an ordered set of data types.
|
|
70
|
+
|
|
71
|
+
$$
|
|
72
|
+
{\mathcal{{T}}}={\left\lbrace{T}_{{1}},\ldots,{T}_{{n}}\right\rbrace}
|
|
73
|
+
$$
|
|
74
|
+
|
|
75
|
+
A value ${A}$ of varying data type is a pair ${\left({A}_{{\text{Type}}},{A}_{{\text{Value}}}\right)}$ where ${A}_{{\text{Type}}}={T}_{{i}}$ for some ${T}_{{i}}\in{\mathcal{{T}}}$ and ${A}_{{\text{Value}}}$ is its value of type ${T}_{{i}}$, which can be empty. We define $\text{idx}{\left({T}_{{i}}\right)}={i}-{1}$, unless it is explicitly defined as another value in the definition of a particular varying data type.
|
|
76
|
+
|
|
77
|
+
The SCALE codec for value ${A}={\left({A}_{{\text{Type}}},{A}_{{\text{Value}}}\right)}$ of varying data type ${\mathcal{{T}}}={\left\lbrace{T}_{{i}},\ldots{T}_{{n}}\right\rbrace}$, formally referred to as $\text{Enc}_{{\text{SC}}}{\left({A}\right)}$ is defined as follows:
|
|
78
|
+
|
|
79
|
+
$$
|
|
80
|
+
\text{Enc}_{{\text{SC}}}{\left({A}\right)}\:=\text{Enc}_{{\text{SC}}}{\left(\text{idx}{\left({A}_{{\text{Type}}}\right)}\text{||}\text{Enc}_{{\text{SC}}}{\left({A}_{{\text{Value}}}\right)}\right)}
|
|
81
|
+
$$
|
|
82
|
+
|
|
83
|
+
The SCALE codec does not encode the correspondence between the value and the data type it represents; the decoder needs prior knowledge of such correspondence to decode the data.
|
|
84
|
+
|
|
85
|
+
### Boolean
|
|
86
|
+
|
|
87
|
+
The SCALE codec for a **boolean value** ${b}$ defined as a byte as follows:
|
|
88
|
+
|
|
89
|
+
$$
|
|
90
|
+
\text{Enc}_{{\text{SC}}}:{\left\lbrace\text{False},\text{True}\right\rbrace}\rightarrow{\mathbb{{B}}}_{{1}}
|
|
91
|
+
$$
|
|
92
|
+
|
|
93
|
+
$$
|
|
94
|
+
{b}\rightarrow{\left\lbrace\begin{matrix}{0}&{b}=\text{False}\\{1}&{b}=\text{True}\end{matrix}\right.}
|
|
95
|
+
$$
|
|
96
|
+
|
|
97
|
+
### Compact
|
|
98
|
+
|
|
99
|
+
**SCALE Length encoding** ${\text{Enc}_{{\text{SC}}}^{{\text{Len}}}}$, also known as a _compact encoding_, of a non-negative number ${n}$ is defined as follows:
|
|
100
|
+
|
|
101
|
+
$$
|
|
102
|
+
{\text{Enc}_{{\text{SC}}}^{{\text{Len}}}}:{\mathbb{{N}}}\rightarrow{\mathbb{{B}}}
|
|
103
|
+
$$
|
|
104
|
+
|
|
105
|
+
$$
|
|
106
|
+
{n}\rightarrow{b}\:={\left\lbrace\begin{matrix}{l}_{{1}}&{0}\le{n}<{2}^{{6}}\\{i}_{{1}}{i}_{{2}}&{2}^{{6}}\le{n}<{2}^{{14}}\\{j}_{{1}}{j}_{{2}}{j}_{{3}}{j}_{{4}}&{2}^{{14}}\le{n}<{2}^{{30}}\\{k}_{{1}}{k}_{{2}}\ldots{k}_{{m}+{1}}&{2}^{{30}}\le{n}\end{matrix}\right.}
|
|
107
|
+
$$
|
|
108
|
+
|
|
109
|
+
$$
|
|
110
|
+
{{l}_{{1}}^{{1}}}{{l}_{{1}}^{{0}}}={00}
|
|
111
|
+
$$
|
|
112
|
+
|
|
113
|
+
$$
|
|
114
|
+
{{i}_{{1}}^{{1}}}{{i}_{{1}}^{{0}}}={01}
|
|
115
|
+
$$
|
|
116
|
+
|
|
117
|
+
$$
|
|
118
|
+
{{j}_{{1}}^{{1}}}{{j}_{{1}}^{{0}}}={10}
|
|
119
|
+
$$
|
|
120
|
+
|
|
121
|
+
$$
|
|
122
|
+
{{k}_{{1}}^{{1}}}{{k}_{{1}}^{{0}}}={11}
|
|
123
|
+
$$
|
|
124
|
+
|
|
125
|
+
and the rest of the bits of ${b}$ store the value of ${n}$ in little-endian format in base-2 as follows:
|
|
126
|
+
|
|
127
|
+
$$
|
|
128
|
+
{n}\:={\left\lbrace\begin{matrix}{{l}_{{1}}^{{7}}}\ldots{{l}_{{1}}^{{3}}}{{l}_{{1}}^{{2}}}&{n}<{2}^{{6}}\\{{i}_{{2}}^{{7}}}\ldots{{i}_{{2}}^{{0}}}{{i}_{{1}}^{{7}}}..{{i}_{{1}}^{{2}}}&{2}^{{6}}\le{n}<{2}^{{14}}\\{{j}_{{4}}^{{7}}}\ldots{{j}_{{4}}^{{0}}}{{j}_{{3}}^{{7}}}\ldots{{j}_{{1}}^{{7}}}\ldots{{j}_{{1}}^{{2}}}&{2}^{{14}}\le{n}<{2}^{{30}}\\{k}_{{2}}+{k}_{{3}}{2}^{{8}}+{k}_{{4}}{2}^{{{2}\times{8}}}+\ldots+{k}_{{m}+{1}}{2}^{{{\left({m}-{1}\right)}{8}}}&{2}^{{30}}\le{n}\end{matrix}\right.}
|
|
129
|
+
$$
|
|
130
|
+
|
|
131
|
+
such that:
|
|
132
|
+
|
|
133
|
+
$$
|
|
134
|
+
{{k}_{{1}}^{{7}}}\ldots{{k}_{{1}}^{{3}}}{{k}_{{1}}^{{2}}}\:={m}-{4}
|
|
135
|
+
$$
|
|
136
|
+
|
|
137
|
+
Note that ${m}$ denotes the length of the original integer being encoded and does not include the extra byte describing the length. The encoding can be used for integers up to: $$2^{(63+4)8} -1 = 2^{536} -1$$
|
|
138
|
+
|
|
139
|
+
### Sequence
|
|
140
|
+
|
|
141
|
+
The **SCALE codec** for **sequence** ${S}$ such that:
|
|
142
|
+
|
|
143
|
+
$$
|
|
144
|
+
{S}\:={A}_{{1}},\ldots{A}_{{n}}
|
|
145
|
+
$$
|
|
146
|
+
|
|
147
|
+
where ${A}_{{i}}$’s are values of **the same type** (and the decoder is unable to infer value of ${n}$ from the context) is defined as:
|
|
148
|
+
|
|
149
|
+
$$
|
|
150
|
+
\text{Enc}_{{\text{SC}}}{\left({S}\right)}\:={\text{Enc}_{{\text{SC}}}^{{\text{Len}}}}{\left({\left|{{S}}\right|}\right)}\text{||}\text{Enc}_{{\text{SC}}}{\left({A}_{{2}}\right)}\text{||}\ldots\text{||}\text{Enc}_{{\text{SC}}}{\left({A}_{{n}}\right)}
|
|
151
|
+
$$
|
|
152
|
+
|
|
153
|
+
where ${\text{Enc}_{{\text{SC}}}^{{\text{Len}}}}$ is defined [here](#compact).
|
|
154
|
+
|
|
155
|
+
In some cases, the length indicator ${\text{Enc}_{{\text{SC}}}^{{\text{Len}}}}{\left({\left|{{S}}\right|}\right)}$ is omitted if the length of the sequence is fixed and known by the decoder upfront. Such cases are explicitly stated by the definition of the corresponding type.
|
|
156
|
+
|
|
157
|
+
### String
|
|
158
|
+
|
|
159
|
+
The SCALE codec for a **string value** is an [encoded sequence](#sequence) consisting of UTF-8 encoded bytes.
|
|
160
|
+
|
|
161
|
+
> This can be achieved via encoding the UTF-8 sequence as a `uint8[]` or `bytes`, which is supported by this library.
|
|
162
|
+
|
|
163
|
+
### Option Type
|
|
164
|
+
|
|
165
|
+
The **Option** type is a varying data type of ${\left\lbrace\text{None},{T}_{{2}}\right\rbrace}$ which indicates if data of ${T}_{{2}}$ type is available (referred to as _some_ state) or not (referred to as _empty_, _none_ or _null_ state). The presence of type _none_, indicated by $\text{idx}{\left({T}_{{\text{None}}}\right)}={0}$, implies that the data corresponding to ${T}_{{2}}$ type is not available and contains no additional data. Where as the presence of type ${T}_{{2}}$ indicated by $\text{idx}{\left({T}_{{2}}\right)}={1}$ implies that the data is available.
|
|
166
|
+
|
|
167
|
+
### Result Type
|
|
168
|
+
|
|
169
|
+
The **Result** type is a varying data type of ${\left\lbrace{T}_{{1}},{T}_{{2}}\right\rbrace}$ which is used to indicate if a certain operation or function was executed successfully (referred to as "ok" state) or not (referred to as "error" state). ${T}_{{1}}$ implies success, ${T}_{{2}}$ implies failure. Both types can either contain additional data or are defined as empty types otherwise.
|
|
170
|
+
|
|
171
|
+
### Dictionaries, Hashtables, Maps
|
|
172
|
+
|
|
173
|
+
SCALE codec for **dictionary** or **hashtable** D with key-value pairs
|
|
174
|
+
$({k}_{{i}},{v}_{{i}})$, such that:
|
|
175
|
+
|
|
176
|
+
$$
|
|
177
|
+
{D}\:={\left\lbrace{\left({k}_{{1}},{v}_{{1}}\right)},\ldots{\left({k}_{{n}},{v}_{{n}}\right)}\right\rbrace}
|
|
178
|
+
$$
|
|
179
|
+
|
|
180
|
+
is defined as the SCALE codec of ${D}$ as a sequence of key-value pairs (as tuples):
|
|
181
|
+
|
|
182
|
+
$$
|
|
183
|
+
\text{Enc}_{{\text{SC}}}{\left({D}\right)}\:={\text{Enc}_{{\text{SC}}}^{{\text{Size}}}}{\left({\left|{{D}}\right|}\right)}\text{||}\text{Enc}_{{\text{SC}}}{\left({k}_{{1}},{v}_{{1}}\right)}\text{||}\ldots\text{||}\text{Enc}_{{\text{SC}}}{\left({k}_{{n}},{v}_{{n}}\right)}
|
|
184
|
+
$$
|
|
185
|
+
|
|
186
|
+
where ${\text{Enc}_{{\text{SC}}}^{{\text{Size}}}}$ is encoded the same way as ${\text{Enc}_{{\text{SC}}}^{{\text{Len}}}}$ but argument $\text{Size}$ refers to the number of key-value pairs rather than the length.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "solidity-scale-codec",
|
|
3
|
-
"version": "2.1.
|
|
3
|
+
"version": "2.1.2",
|
|
4
4
|
"description": "Solidity implementation of scale-codec.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"solidity",
|
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
"README.md",
|
|
22
22
|
"LICENSE",
|
|
23
23
|
"CHANGELOG.md",
|
|
24
|
-
"
|
|
24
|
+
"guides/Definitions.md"
|
|
25
25
|
],
|
|
26
26
|
"license": "Apache-2.0",
|
|
27
27
|
"author": "LucasGrasso",
|
|
@@ -31,9 +31,9 @@ library BoolArr {
|
|
|
31
31
|
bytes memory data,
|
|
32
32
|
uint256 offset
|
|
33
33
|
) internal pure returns (uint256) {
|
|
34
|
-
(uint256 count, uint256 prefixSize) = Compact.decodeAt(data, offset);
|
|
35
|
-
uint256 totalSize = prefixSize + (count * 1);
|
|
36
|
-
if (offset + totalSize > data.length) revert InvalidBoolArrLength();
|
|
34
|
+
(uint256 count, uint256 prefixSize) = Compact.decodeAt(data, offset);
|
|
35
|
+
uint256 totalSize = prefixSize + (count * 1);
|
|
36
|
+
if (offset + totalSize > data.length) revert InvalidBoolArrLength();
|
|
37
37
|
return totalSize;
|
|
38
38
|
}
|
|
39
39
|
|
|
@@ -31,9 +31,9 @@ library I128Arr {
|
|
|
31
31
|
bytes memory data,
|
|
32
32
|
uint256 offset
|
|
33
33
|
) internal pure returns (uint256) {
|
|
34
|
-
(uint256 count, uint256 prefixSize) = Compact.decodeAt(data, offset);
|
|
35
|
-
uint256 totalSize = prefixSize + (count * 16);
|
|
36
|
-
if (offset + totalSize > data.length) revert InvalidI128ArrLength();
|
|
34
|
+
(uint256 count, uint256 prefixSize) = Compact.decodeAt(data, offset);
|
|
35
|
+
uint256 totalSize = prefixSize + (count * 16);
|
|
36
|
+
if (offset + totalSize > data.length) revert InvalidI128ArrLength();
|
|
37
37
|
return totalSize;
|
|
38
38
|
}
|
|
39
39
|
|
|
@@ -31,9 +31,9 @@ library I16Arr {
|
|
|
31
31
|
bytes memory data,
|
|
32
32
|
uint256 offset
|
|
33
33
|
) internal pure returns (uint256) {
|
|
34
|
-
(uint256 count, uint256 prefixSize) = Compact.decodeAt(data, offset);
|
|
35
|
-
uint256 totalSize = prefixSize + (count * 2);
|
|
36
|
-
if (offset + totalSize > data.length) revert InvalidI16ArrLength();
|
|
34
|
+
(uint256 count, uint256 prefixSize) = Compact.decodeAt(data, offset);
|
|
35
|
+
uint256 totalSize = prefixSize + (count * 2);
|
|
36
|
+
if (offset + totalSize > data.length) revert InvalidI16ArrLength();
|
|
37
37
|
return totalSize;
|
|
38
38
|
}
|
|
39
39
|
|
|
@@ -31,9 +31,9 @@ library I256Arr {
|
|
|
31
31
|
bytes memory data,
|
|
32
32
|
uint256 offset
|
|
33
33
|
) internal pure returns (uint256) {
|
|
34
|
-
(uint256 count, uint256 prefixSize) = Compact.decodeAt(data, offset);
|
|
35
|
-
uint256 totalSize = prefixSize + (count * 32);
|
|
36
|
-
if (offset + totalSize > data.length) revert InvalidI256ArrLength();
|
|
34
|
+
(uint256 count, uint256 prefixSize) = Compact.decodeAt(data, offset);
|
|
35
|
+
uint256 totalSize = prefixSize + (count * 32);
|
|
36
|
+
if (offset + totalSize > data.length) revert InvalidI256ArrLength();
|
|
37
37
|
return totalSize;
|
|
38
38
|
}
|
|
39
39
|
|
|
@@ -31,9 +31,9 @@ library I32Arr {
|
|
|
31
31
|
bytes memory data,
|
|
32
32
|
uint256 offset
|
|
33
33
|
) internal pure returns (uint256) {
|
|
34
|
-
(uint256 count, uint256 prefixSize) = Compact.decodeAt(data, offset);
|
|
35
|
-
uint256 totalSize = prefixSize + (count * 4);
|
|
36
|
-
if (offset + totalSize > data.length) revert InvalidI32ArrLength();
|
|
34
|
+
(uint256 count, uint256 prefixSize) = Compact.decodeAt(data, offset);
|
|
35
|
+
uint256 totalSize = prefixSize + (count * 4);
|
|
36
|
+
if (offset + totalSize > data.length) revert InvalidI32ArrLength();
|
|
37
37
|
return totalSize;
|
|
38
38
|
}
|
|
39
39
|
|
|
@@ -31,9 +31,9 @@ library I64Arr {
|
|
|
31
31
|
bytes memory data,
|
|
32
32
|
uint256 offset
|
|
33
33
|
) internal pure returns (uint256) {
|
|
34
|
-
(uint256 count, uint256 prefixSize) = Compact.decodeAt(data, offset);
|
|
35
|
-
uint256 totalSize = prefixSize + (count * 8);
|
|
36
|
-
if (offset + totalSize > data.length) revert InvalidI64ArrLength();
|
|
34
|
+
(uint256 count, uint256 prefixSize) = Compact.decodeAt(data, offset);
|
|
35
|
+
uint256 totalSize = prefixSize + (count * 8);
|
|
36
|
+
if (offset + totalSize > data.length) revert InvalidI64ArrLength();
|
|
37
37
|
return totalSize;
|
|
38
38
|
}
|
|
39
39
|
|
|
@@ -31,9 +31,9 @@ library I8Arr {
|
|
|
31
31
|
bytes memory data,
|
|
32
32
|
uint256 offset
|
|
33
33
|
) internal pure returns (uint256) {
|
|
34
|
-
(uint256 count, uint256 prefixSize) = Compact.decodeAt(data, offset);
|
|
35
|
-
uint256 totalSize = prefixSize + (count * 1);
|
|
36
|
-
if (offset + totalSize > data.length) revert InvalidI8ArrLength();
|
|
34
|
+
(uint256 count, uint256 prefixSize) = Compact.decodeAt(data, offset);
|
|
35
|
+
uint256 totalSize = prefixSize + (count * 1);
|
|
36
|
+
if (offset + totalSize > data.length) revert InvalidI8ArrLength();
|
|
37
37
|
return totalSize;
|
|
38
38
|
}
|
|
39
39
|
|
|
@@ -31,9 +31,9 @@ library U128Arr {
|
|
|
31
31
|
bytes memory data,
|
|
32
32
|
uint256 offset
|
|
33
33
|
) internal pure returns (uint256) {
|
|
34
|
-
(uint256 count, uint256 prefixSize) = Compact.decodeAt(data, offset);
|
|
35
|
-
uint256 totalSize = prefixSize + (count * 16);
|
|
36
|
-
if (offset + totalSize > data.length) revert InvalidU128ArrLength();
|
|
34
|
+
(uint256 count, uint256 prefixSize) = Compact.decodeAt(data, offset);
|
|
35
|
+
uint256 totalSize = prefixSize + (count * 16);
|
|
36
|
+
if (offset + totalSize > data.length) revert InvalidU128ArrLength();
|
|
37
37
|
return totalSize;
|
|
38
38
|
}
|
|
39
39
|
|
|
@@ -31,9 +31,9 @@ library U16Arr {
|
|
|
31
31
|
bytes memory data,
|
|
32
32
|
uint256 offset
|
|
33
33
|
) internal pure returns (uint256) {
|
|
34
|
-
(uint256 count, uint256 prefixSize) = Compact.decodeAt(data, offset);
|
|
35
|
-
uint256 totalSize = prefixSize + (count * 2);
|
|
36
|
-
if (offset + totalSize > data.length) revert InvalidU16ArrLength();
|
|
34
|
+
(uint256 count, uint256 prefixSize) = Compact.decodeAt(data, offset);
|
|
35
|
+
uint256 totalSize = prefixSize + (count * 2);
|
|
36
|
+
if (offset + totalSize > data.length) revert InvalidU16ArrLength();
|
|
37
37
|
return totalSize;
|
|
38
38
|
}
|
|
39
39
|
|
|
@@ -31,9 +31,9 @@ library U256Arr {
|
|
|
31
31
|
bytes memory data,
|
|
32
32
|
uint256 offset
|
|
33
33
|
) internal pure returns (uint256) {
|
|
34
|
-
(uint256 count, uint256 prefixSize) = Compact.decodeAt(data, offset);
|
|
35
|
-
uint256 totalSize = prefixSize + (count * 32);
|
|
36
|
-
if (offset + totalSize > data.length) revert InvalidU256ArrLength();
|
|
34
|
+
(uint256 count, uint256 prefixSize) = Compact.decodeAt(data, offset);
|
|
35
|
+
uint256 totalSize = prefixSize + (count * 32);
|
|
36
|
+
if (offset + totalSize > data.length) revert InvalidU256ArrLength();
|
|
37
37
|
return totalSize;
|
|
38
38
|
}
|
|
39
39
|
|
|
@@ -31,9 +31,9 @@ library U32Arr {
|
|
|
31
31
|
bytes memory data,
|
|
32
32
|
uint256 offset
|
|
33
33
|
) internal pure returns (uint256) {
|
|
34
|
-
(uint256 count, uint256 prefixSize) = Compact.decodeAt(data, offset);
|
|
35
|
-
uint256 totalSize = prefixSize + (count * 4);
|
|
36
|
-
if (offset + totalSize > data.length) revert InvalidU32ArrLength();
|
|
34
|
+
(uint256 count, uint256 prefixSize) = Compact.decodeAt(data, offset);
|
|
35
|
+
uint256 totalSize = prefixSize + (count * 4);
|
|
36
|
+
if (offset + totalSize > data.length) revert InvalidU32ArrLength();
|
|
37
37
|
return totalSize;
|
|
38
38
|
}
|
|
39
39
|
|
|
@@ -31,9 +31,9 @@ library U64Arr {
|
|
|
31
31
|
bytes memory data,
|
|
32
32
|
uint256 offset
|
|
33
33
|
) internal pure returns (uint256) {
|
|
34
|
-
(uint256 count, uint256 prefixSize) = Compact.decodeAt(data, offset);
|
|
35
|
-
uint256 totalSize = prefixSize + (count * 8);
|
|
36
|
-
if (offset + totalSize > data.length) revert InvalidU64ArrLength();
|
|
34
|
+
(uint256 count, uint256 prefixSize) = Compact.decodeAt(data, offset);
|
|
35
|
+
uint256 totalSize = prefixSize + (count * 8);
|
|
36
|
+
if (offset + totalSize > data.length) revert InvalidU64ArrLength();
|
|
37
37
|
return totalSize;
|
|
38
38
|
}
|
|
39
39
|
|
|
@@ -31,9 +31,9 @@ library U8Arr {
|
|
|
31
31
|
bytes memory data,
|
|
32
32
|
uint256 offset
|
|
33
33
|
) internal pure returns (uint256) {
|
|
34
|
-
(uint256 count, uint256 prefixSize) = Compact.decodeAt(data, offset);
|
|
35
|
-
uint256 totalSize = prefixSize + (count * 1);
|
|
36
|
-
if (offset + totalSize > data.length) revert InvalidU8ArrLength();
|
|
34
|
+
(uint256 count, uint256 prefixSize) = Compact.decodeAt(data, offset);
|
|
35
|
+
uint256 totalSize = prefixSize + (count * 1);
|
|
36
|
+
if (offset + totalSize > data.length) revert InvalidU8ArrLength();
|
|
37
37
|
return totalSize;
|
|
38
38
|
}
|
|
39
39
|
|
package/src/Scale/Array.sol
CHANGED
|
@@ -1,17 +1,16 @@
|
|
|
1
|
-
|
|
2
1
|
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
-
pragma solidity ^0.8.28;
|
|
2
|
+
pragma solidity ^0.8.28;
|
|
4
3
|
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
14
|
-
import {
|
|
15
|
-
import {
|
|
16
|
-
import {
|
|
17
|
-
import {
|
|
4
|
+
import {U8Arr} from "./Array/U8Arr.sol";
|
|
5
|
+
import {U16Arr} from "./Array/U16Arr.sol";
|
|
6
|
+
import {U32Arr} from "./Array/U32Arr.sol";
|
|
7
|
+
import {U64Arr} from "./Array/U64Arr.sol";
|
|
8
|
+
import {U128Arr} from "./Array/U128Arr.sol";
|
|
9
|
+
import {U256Arr} from "./Array/U256Arr.sol";
|
|
10
|
+
import {I8Arr} from "./Array/I8Arr.sol";
|
|
11
|
+
import {I16Arr} from "./Array/I16Arr.sol";
|
|
12
|
+
import {I32Arr} from "./Array/I32Arr.sol";
|
|
13
|
+
import {I64Arr} from "./Array/I64Arr.sol";
|
|
14
|
+
import {I128Arr} from "./Array/I128Arr.sol";
|
|
15
|
+
import {I256Arr} from "./Array/I256Arr.sol";
|
|
16
|
+
import {BoolArr} from "./Array/BoolArr.sol";
|
|
@@ -105,14 +105,12 @@ library Compact {
|
|
|
105
105
|
} else if (mode == MODE_TWO) {
|
|
106
106
|
if (data.length < offset + 2) revert OffsetOutOfBounds();
|
|
107
107
|
value =
|
|
108
|
-
uint256(LittleEndianU16.fromLittleEndian(data, offset)) >>
|
|
109
|
-
2;
|
|
108
|
+
uint256(LittleEndianU16.fromLittleEndian(data, offset)) >> 2;
|
|
110
109
|
bytesRead = 2;
|
|
111
110
|
} else if (mode == MODE_FOUR) {
|
|
112
111
|
if (data.length < offset + 4) revert OffsetOutOfBounds();
|
|
113
112
|
value =
|
|
114
|
-
uint256(LittleEndianU32.fromLittleEndian(data, offset)) >>
|
|
115
|
-
2;
|
|
113
|
+
uint256(LittleEndianU32.fromLittleEndian(data, offset)) >> 2;
|
|
116
114
|
bytesRead = 4;
|
|
117
115
|
} else {
|
|
118
116
|
uint8 m = (header >> 2) + 4;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// SPDX-License-Identifier: Apache-2.0
|
|
2
2
|
pragma solidity ^0.8.28;
|
|
3
3
|
|
|
4
|
-
import {
|
|
4
|
+
import {U128} from "../Unsigned/U128.sol";
|
|
5
5
|
|
|
6
6
|
/// @title Scale Codec for the `int128` type.
|
|
7
7
|
/// @notice SCALE-compliant encoder/decoder for the `int128` type.
|
|
@@ -9,7 +9,7 @@ import { U128 } from "../Unsigned/U128.sol";
|
|
|
9
9
|
library I128 {
|
|
10
10
|
error OffsetOutOfBounds();
|
|
11
11
|
|
|
12
|
-
|
|
12
|
+
/// @notice Encodes an `int128` into SCALE format (16-byte two's-complement little-endian).
|
|
13
13
|
/// @param value The signed 128-bit integer to encode.
|
|
14
14
|
/// @return SCALE-encoded byte sequence.
|
|
15
15
|
function encode(int128 value) internal pure returns (bytes memory) {
|
|
@@ -17,10 +17,13 @@ library I128 {
|
|
|
17
17
|
}
|
|
18
18
|
|
|
19
19
|
/// @notice Returns the number of bytes that a `int128` would occupy when SCALE-encoded.
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
function encodedSizeAt(
|
|
20
|
+
/// @param data The byte sequence containing the encoded `int128`.
|
|
21
|
+
/// @param offset The starting index in `data` from which to calculate the encoded size of the `int128`.
|
|
22
|
+
/// @return The number of bytes that the `int128` would occupy when SCALE-encoded.
|
|
23
|
+
function encodedSizeAt(
|
|
24
|
+
bytes memory data,
|
|
25
|
+
uint256 offset
|
|
26
|
+
) internal pure returns (uint256) {
|
|
24
27
|
return U128.encodedSizeAt(data, offset);
|
|
25
28
|
}
|
|
26
29
|
|
|
@@ -43,10 +46,12 @@ library I128 {
|
|
|
43
46
|
return int128(U128.decodeAt(data, offset));
|
|
44
47
|
}
|
|
45
48
|
|
|
46
|
-
|
|
49
|
+
/// @notice Converts an int128 to little-endian bytes16 (two's complement)
|
|
47
50
|
/// @param value The signed 128-bit integer to convert.
|
|
48
51
|
/// @return result Little-endian byte representation of the input value.
|
|
49
|
-
function toLittleEndian(
|
|
52
|
+
function toLittleEndian(
|
|
53
|
+
int128 value
|
|
54
|
+
) internal pure returns (bytes16 result) {
|
|
50
55
|
return U128.toLittleEndian(uint128(value));
|
|
51
56
|
}
|
|
52
|
-
}
|
|
57
|
+
}
|
package/src/Scale/Signed/I16.sol
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// SPDX-License-Identifier: Apache-2.0
|
|
2
2
|
pragma solidity ^0.8.28;
|
|
3
3
|
|
|
4
|
-
import {
|
|
4
|
+
import {U16} from "../Unsigned/U16.sol";
|
|
5
5
|
|
|
6
6
|
/// @title Scale Codec for the `int16` type.
|
|
7
7
|
/// @notice SCALE-compliant encoder/decoder for the `int16` type.
|
|
@@ -9,7 +9,7 @@ import { U16 } from "../Unsigned/U16.sol";
|
|
|
9
9
|
library I16 {
|
|
10
10
|
error OffsetOutOfBounds();
|
|
11
11
|
|
|
12
|
-
|
|
12
|
+
/// @notice Encodes an `int16` into SCALE format (2-byte two's-complement little-endian).
|
|
13
13
|
/// @param value The signed 16-bit integer to encode.
|
|
14
14
|
/// @return SCALE-encoded byte sequence.
|
|
15
15
|
function encode(int16 value) internal pure returns (bytes memory) {
|
|
@@ -17,10 +17,13 @@ library I16 {
|
|
|
17
17
|
}
|
|
18
18
|
|
|
19
19
|
/// @notice Returns the number of bytes that a `int16` would occupy when SCALE-encoded.
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
function encodedSizeAt(
|
|
20
|
+
/// @param data The byte sequence containing the encoded `int16`.
|
|
21
|
+
/// @param offset The starting index in `data` from which to calculate the encoded size of the `int16`.
|
|
22
|
+
/// @return The number of bytes that the `int16` would occupy when SCALE-encoded.
|
|
23
|
+
function encodedSizeAt(
|
|
24
|
+
bytes memory data,
|
|
25
|
+
uint256 offset
|
|
26
|
+
) internal pure returns (uint256) {
|
|
24
27
|
return U16.encodedSizeAt(data, offset);
|
|
25
28
|
}
|
|
26
29
|
|
|
@@ -43,10 +46,10 @@ library I16 {
|
|
|
43
46
|
return int16(U16.decodeAt(data, offset));
|
|
44
47
|
}
|
|
45
48
|
|
|
46
|
-
|
|
49
|
+
/// @notice Converts an int16 to little-endian bytes2 (two's complement)
|
|
47
50
|
/// @param value The signed 16-bit integer to convert.
|
|
48
51
|
/// @return result Little-endian byte representation of the input value.
|
|
49
52
|
function toLittleEndian(int16 value) internal pure returns (bytes2 result) {
|
|
50
53
|
return U16.toLittleEndian(uint16(value));
|
|
51
54
|
}
|
|
52
|
-
}
|
|
55
|
+
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// SPDX-License-Identifier: Apache-2.0
|
|
2
2
|
pragma solidity ^0.8.28;
|
|
3
3
|
|
|
4
|
-
import {
|
|
4
|
+
import {U256} from "../Unsigned/U256.sol";
|
|
5
5
|
|
|
6
6
|
/// @title Scale Codec for the `int256` type.
|
|
7
7
|
/// @notice SCALE-compliant encoder/decoder for the `int256` type.
|
|
@@ -9,7 +9,7 @@ import { U256 } from "../Unsigned/U256.sol";
|
|
|
9
9
|
library I256 {
|
|
10
10
|
error OffsetOutOfBounds();
|
|
11
11
|
|
|
12
|
-
|
|
12
|
+
/// @notice Encodes an `int256` into SCALE format (32-byte two's-complement little-endian).
|
|
13
13
|
/// @param value The signed 256-bit integer to encode.
|
|
14
14
|
/// @return SCALE-encoded byte sequence.
|
|
15
15
|
function encode(int256 value) internal pure returns (bytes memory) {
|
|
@@ -17,10 +17,13 @@ library I256 {
|
|
|
17
17
|
}
|
|
18
18
|
|
|
19
19
|
/// @notice Returns the number of bytes that a `int256` would occupy when SCALE-encoded.
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
function encodedSizeAt(
|
|
20
|
+
/// @param data The byte sequence containing the encoded `int256`.
|
|
21
|
+
/// @param offset The starting index in `data` from which to calculate the encoded size of the `int256`.
|
|
22
|
+
/// @return The number of bytes that the `int256` would occupy when SCALE-encoded.
|
|
23
|
+
function encodedSizeAt(
|
|
24
|
+
bytes memory data,
|
|
25
|
+
uint256 offset
|
|
26
|
+
) internal pure returns (uint256) {
|
|
24
27
|
return U256.encodedSizeAt(data, offset);
|
|
25
28
|
}
|
|
26
29
|
|
|
@@ -43,10 +46,12 @@ library I256 {
|
|
|
43
46
|
return int256(U256.decodeAt(data, offset));
|
|
44
47
|
}
|
|
45
48
|
|
|
46
|
-
|
|
49
|
+
/// @notice Converts an int256 to little-endian bytes32 (two's complement)
|
|
47
50
|
/// @param value The signed 256-bit integer to convert.
|
|
48
51
|
/// @return result Little-endian byte representation of the input value.
|
|
49
|
-
function toLittleEndian(
|
|
52
|
+
function toLittleEndian(
|
|
53
|
+
int256 value
|
|
54
|
+
) internal pure returns (bytes32 result) {
|
|
50
55
|
return U256.toLittleEndian(uint256(value));
|
|
51
56
|
}
|
|
52
|
-
}
|
|
57
|
+
}
|
package/src/Scale/Signed/I32.sol
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// SPDX-License-Identifier: Apache-2.0
|
|
2
2
|
pragma solidity ^0.8.28;
|
|
3
3
|
|
|
4
|
-
import {
|
|
4
|
+
import {U32} from "../Unsigned/U32.sol";
|
|
5
5
|
|
|
6
6
|
/// @title Scale Codec for the `int32` type.
|
|
7
7
|
/// @notice SCALE-compliant encoder/decoder for the `int32` type.
|
|
@@ -9,7 +9,7 @@ import { U32 } from "../Unsigned/U32.sol";
|
|
|
9
9
|
library I32 {
|
|
10
10
|
error OffsetOutOfBounds();
|
|
11
11
|
|
|
12
|
-
|
|
12
|
+
/// @notice Encodes an `int32` into SCALE format (4-byte two's-complement little-endian).
|
|
13
13
|
/// @param value The signed 32-bit integer to encode.
|
|
14
14
|
/// @return SCALE-encoded byte sequence.
|
|
15
15
|
function encode(int32 value) internal pure returns (bytes memory) {
|
|
@@ -17,10 +17,13 @@ library I32 {
|
|
|
17
17
|
}
|
|
18
18
|
|
|
19
19
|
/// @notice Returns the number of bytes that a `int32` would occupy when SCALE-encoded.
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
function encodedSizeAt(
|
|
20
|
+
/// @param data The byte sequence containing the encoded `int32`.
|
|
21
|
+
/// @param offset The starting index in `data` from which to calculate the encoded size of the `int32`.
|
|
22
|
+
/// @return The number of bytes that the `int32` would occupy when SCALE-encoded.
|
|
23
|
+
function encodedSizeAt(
|
|
24
|
+
bytes memory data,
|
|
25
|
+
uint256 offset
|
|
26
|
+
) internal pure returns (uint256) {
|
|
24
27
|
return U32.encodedSizeAt(data, offset);
|
|
25
28
|
}
|
|
26
29
|
|
|
@@ -43,10 +46,10 @@ library I32 {
|
|
|
43
46
|
return int32(U32.decodeAt(data, offset));
|
|
44
47
|
}
|
|
45
48
|
|
|
46
|
-
|
|
49
|
+
/// @notice Converts an int32 to little-endian bytes4 (two's complement)
|
|
47
50
|
/// @param value The signed 32-bit integer to convert.
|
|
48
51
|
/// @return result Little-endian byte representation of the input value.
|
|
49
52
|
function toLittleEndian(int32 value) internal pure returns (bytes4 result) {
|
|
50
53
|
return U32.toLittleEndian(uint32(value));
|
|
51
54
|
}
|
|
52
|
-
}
|
|
55
|
+
}
|