Again, the important thing to remember here is that casting from a larger type to a smaller type means that you are left with the least significant part of the original value.
For example, given the 64-bit value:
x == b63, b62, b61, ..., b2, b1, b0
If we cast it to a 32-bit value:
y = uint32(x)
Then we get the 32-bit value:
y == b31, b30, b29, ..., b2, b1, b0
Now, in order to compare between them, we first need to expand y
to the size of x
.
Of course, we can't change the actual value of y
, so we only expand it with leading zeros:
y == 0, 0, 0, ..., b31, b30, b29, ..., b2, b1, b0
Then we finally compare between them:
x == b63, b62, b61, ..., b34, b33, b32, b31, b30, b29, ..., b2, b1, b0
y == 0 , 0 , 0 , ..., 0 , 0 , 0 , b31, b30, b29, ..., b2, b1, b0
As you can see, they are equal if and only if bits 63-32 are all zeros.
If you still find it hard to understand, let's simulate the whole thing with a pair of values in base 10:
- Let
x = Decimal8(ABCDEFGH)
- Let
y = Decimal4(x) = EFGH
- Compare:
x == ABCDEFGH
y == 0000EFGH
As you can see, x == y
if and only if ABCD == 0000
Now it should hopefully be easier for you to see why:
uint32(uint64(n)) == uint16(uint64(n))
requires that bits 16-31 are all set to zerouint32(uint64(n)) != uint64(n)
requires that bits 32-63 are not all set to zero
As for the construction of the value of _gateKey
as a hexadecimal string - note that such strings:
- Are used for representing numerical values in base 16 (aka "hexadecimal")
- Consist of characters from the set [0 thru 9] and from the set [A thru F]
- Are case-insensitive, hence the set [A thru F] is synonymous [a thru f]
- Typically start with the prefix "0x" (though it is application-dependent)
Each character represents a unique sequence of 4 bits, denoting a unique value in base 2:
+-----------+--------------+---------------+
| Character | Bit Sequence | Decimal Value |
+-----------+--------------+---------------+
| 0 | 0000 | 0 |
| 1 | 0001 | 1 |
| 2 | 0010 | 2 |
| 3 | 0011 | 3 |
| 4 | 0100 | 4 |
| 5 | 0101 | 5 |
| 6 | 0110 | 6 |
| 7 | 0111 | 7 |
| 8 | 1000 | 8 |
| 9 | 1001 | 9 |
| A | 1010 | 10 |
| B | 1011 | 11 |
| C | 1100 | 12 |
| D | 1101 | 13 |
| E | 1110 | 14 |
| F | 1111 | 15 |
+-----------+--------------+---------------+
For example, the string "0x14E5"
represents the bit-sequence 0001 | 0100 | 1110 | 0101
.
Let's assume that the last 4 characters (least 16 bits) in the wallet address are A57C
.
Hence the value of _gateKey
can be constructed as:
const _gateKey = "0x"
+ "00" // the bit-sequence 0000|0000 is placed between bit 63 and bit 56
+ "00" // the bit-sequence 0000|0000 is placed between bit 55 and bit 48
+ "00" // the bit-sequence 0000|0000 is placed between bit 47 and bit 40
+ "01" // the bit-sequence 0000|0001 is placed between bit 39 and bit 32
+ "00" // the bit-sequence 0000|0000 is placed between bit 31 and bit 24
+ "00" // the bit-sequence 0000|0000 is placed between bit 23 and bit 16
+ "A5" // the bit-sequence 1010|0101 is placed between bit 15 and bit 8
+ "7C" // the bit-sequence 0111|1100 is placed between bit 7 and bit 0