diff --git a/assets/img/4-Substrate/Big-Endian.svg b/assets/img/4-Substrate/Big-Endian.svg new file mode 100644 index 000000000..a2bb67579 --- /dev/null +++ b/assets/img/4-Substrate/Big-Endian.svg @@ -0,0 +1,549 @@ + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + ... + ... + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/styles/custom-classes.css b/assets/styles/custom-classes.css index c77bb1e77..7c7ac5c0f 100644 --- a/assets/styles/custom-classes.css +++ b/assets/styles/custom-classes.css @@ -145,6 +145,10 @@ th { font-size: 24px !important; } +.text-smaller * { + font-size: 18px !important; +} + .overlay-table { width: 800px; } diff --git a/syllabus/4-Substrate/4.x-SCALE_Slides.md b/syllabus/4-Substrate/4.x-SCALE_Slides.md index 1b3ea52ea..2e3ff5337 100644 --- a/syllabus/4-Substrate/4.x-SCALE_Slides.md +++ b/syllabus/4-Substrate/4.x-SCALE_Slides.md @@ -31,7 +31,7 @@ Wasm is a little endian system, which makes SCALE very performant. -TODO use img that does not break `yarn build` + @@ -44,7 +44,7 @@ TODO use img that does not break `yarn build` --- -### Why SCALE? +### Why SCALE? Why not X? - Simple to define. - Not Rust-specific (but happens to work great in Rust). @@ -67,8 +67,8 @@ The encoded data does not include this contextual information. ### Example: SCALE vs JSON - - +
+
```rust use parity_scale_codec::{ Encode }; @@ -96,8 +96,8 @@ fn main() { 7 ``` - -pba-col center style="margin-left: 10px;"> +
+
```rust use serde::{ Serialize }; @@ -125,8 +125,8 @@ fn main() { 42 ``` - - +
+
--- @@ -168,7 +168,7 @@ fn main() {
-pba-col center style="margin-left: 10px;"> + ```bash @@ -222,12 +222,20 @@ Though for single-byte values, the fixed-width integer is never worse. ### Compact Prefix -Compact/general integers are encoded with the two least significant **bits** denoting the mode: +
+ +| `0b00` | `0b01` | `0b10` | `0b11` | +| ------ | ------ | ------ | ------ | +| single-byte mode; upper six bits are the LE encoding of the value. Valid only for values of `0` through `63`. +| two-byte mode: upper six bits and the following byte is the LE encoding of the value. Valid only for values `64` through `(2^14 - 1)`. +| four-byte mode: upper six bits and the following three bytes are the LE encoding of the value. Valid only for values `(2^14)` through `(2^30 - 1)`. +| Big-integer mode: The upper six bits are the number of bytes following, plus four. The value is contained, LE encoded, in the bytes following. The final (most significant) byte must be non-zero. Valid only for values `(2^30)` through `(2^536 - 1)`. +| + +
+ +Compact/general integers are encoded with the two least significant **bits** denoting the mode. -- `0b00`: single-byte mode; upper six bits are the LE encoding of the value. Valid only for values of `0` through `63`. -- `0b01`: two-byte mode: upper six bits and the following byte is the LE encoding of the value. Valid only for values `64` through `(2^14 - 1)`. -- `0b10`: four-byte mode: upper six bits and the following three bytes are the LE encoding of the value. Valid only for values `(2^14)` through `(2^30 - 1)`. -- `0b11`: Big-integer mode: The upper six bits are the number of bytes following, plus four. The value is contained, LE encoded, in the bytes following. The final (most significant) byte must be non-zero. Valid only for values `(2^30)` through `(2^536 - 1)`. --- @@ -390,6 +398,7 @@ fn main() { println!("{:02x?}", [0u8, 1u8, 2u8, 3u8, 4u8].encode()); println!("{:02x?}", vec![0u8, 1u8, 2u8, 3u8, 4u8].encode()); println!("{:02x?}", "hello".encode()); + println!("{:02x?}", vec![0u8; 1024].encode()); } ``` @@ -397,8 +406,13 @@ fn main() { [00, 01, 02, 03, 04] [14, 00, 01, 02, 03, 04] [14, 68, 65, 6c, 6c, 6f] +[01, 10, 00, 00, ... snip ... , 00] ``` +Notes: + +Note that the length prefix can be multiple bytes, like the last example. + --- ### Tuple and Struct @@ -437,6 +451,38 @@ Note that tuple and struct encode the same, even though struct has named fields. --- +## Embedded Compact + +```rust +use parity_scale_codec::Encode; + +#[derive(Encode)] +struct Example { + number: u64, + #[codec(compact)] + compact_number: u64, +} + +#[derive(Encode)] +enum Choices { + One(u64, #[codec(compact)] u64), +} + +fn main() { + let my_struct = Example { number: 42, compact_number: 1337 }; + let my_choice = Choices::One(42, 1337); + println!("{:02x?}", my_struct.encode()); + println!("{:02x?}", my_choice.encode()); +} +``` + +```bash +[2a, 00, 00, 00, 00, 00, 00, 00, e5, 14] +[00, 2a, 00, 00, 00, 00, 00, 00, 00, e5, 14] +``` + +--- + ### Enum Prefix with index (`u8`), then the value, if any. @@ -603,4 +649,12 @@ SCALE Codec has been implemented in other languages, including: --- +## Missing Some Metadata? + +To make SCALE useful as an encoding format within the Substrate and Polkadot ecosystem, we need to figure out a way to provide **metadata** about all the types we will expect, and when we will expect them. + +HINT: We do. + +--- + ### Remember, in the end of the day, everything is just 0's and 1's.