Support encoding of signed integers
This commit is contained in:
parent
56005d623d
commit
8131170475
|
@ -67,22 +67,30 @@ func encode(encoder: var AbiEncoder, tupl: Tuple) =
|
|||
func finishTuple(encoder: var AbiEncoder) =
|
||||
encoder.encode(encoder.stack.pop())
|
||||
|
||||
func pad(encoder: var AbiEncoder, len: int) =
|
||||
func pad(encoder: var AbiEncoder, len: int, padding=0'u8) =
|
||||
let padlen = (32 - len mod 32) mod 32
|
||||
for _ in 0..<padlen:
|
||||
encoder.append([0'u8])
|
||||
encoder.append([padding])
|
||||
|
||||
func padleft(encoder: var AbiEncoder, bytes: openArray[byte]) =
|
||||
encoder.pad(bytes.len)
|
||||
func padleft(encoder: var AbiEncoder, bytes: openArray[byte], padding=0'u8) =
|
||||
encoder.pad(bytes.len, padding)
|
||||
encoder.append(bytes)
|
||||
|
||||
func padright(encoder: var AbiEncoder, bytes: openArray[byte]) =
|
||||
func padright(encoder: var AbiEncoder, bytes: openArray[byte], padding=0'u8) =
|
||||
encoder.append(bytes)
|
||||
encoder.pad(bytes.len)
|
||||
encoder.pad(bytes.len, padding)
|
||||
|
||||
func encode(encoder: var AbiEncoder, value: SomeUnsignedInt | StUint) =
|
||||
encoder.padleft(value.toBytesBE)
|
||||
|
||||
func encode[bits](encoder: var AbiEncoder, value: StInt[bits]) =
|
||||
let bytes = value.stuint(bits).toBytesBE
|
||||
let padding = if value.isNegative: 0xFF'u8 else: 0x00'u8
|
||||
encoder.padleft(bytes, padding)
|
||||
|
||||
func encode(encoder: var AbiEncoder, value: SomeSignedInt) =
|
||||
encoder.write(value.i256)
|
||||
|
||||
func encode(encoder: var AbiEncoder, value: bool) =
|
||||
encoder.encode(if value: 1'u8 else: 0'u8)
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
|
||||
import std/unittest
|
||||
import std/sequtils
|
||||
import pkg/stint
|
||||
import pkg/stew/byteutils
|
||||
import contractabi
|
||||
|
@ -27,6 +28,16 @@ suite "ABI encoding":
|
|||
0x11'u8 & 0x22'u8 & 0x33'u8 & 0x44'u8 &
|
||||
0x55'u8 & 0x66'u8 & 0x77'u8 & 0x88'u8
|
||||
|
||||
test "encodes int8, 16, 32, 64":
|
||||
check AbiEncoder.encode(1'i8) == 31.zeroes & 0x01'u8
|
||||
check AbiEncoder.encode(-1'i8) == 0xFF'u8.repeat(32)
|
||||
check AbiEncoder.encode(1'i16) == 31.zeroes & 0x01'u8
|
||||
check AbiEncoder.encode(-1'i16) == 0xFF'u8.repeat(32)
|
||||
check AbiEncoder.encode(1'i32) == 31.zeroes & 0x01'u8
|
||||
check AbiEncoder.encode(-1'i32) == 0xFF'u8.repeat(32)
|
||||
check AbiEncoder.encode(1'i64) == 31.zeroes & 0x01'u8
|
||||
check AbiEncoder.encode(-1'i64) == 0xFF'u8.repeat(32)
|
||||
|
||||
test "encodes ranges":
|
||||
type SomeRange = range[0x0000'u16..0xAAAA'u16]
|
||||
check AbiEncoder.encode(SomeRange(0x1122)) == 30.zeroes & 0x11'u8 & 0x22'u8
|
||||
|
@ -40,9 +51,13 @@ suite "ABI encoding":
|
|||
|
||||
test "encodes stints":
|
||||
let uint256 = UInt256.example
|
||||
check AbiEncoder.encode(uint256) == @(uint256.toBytesBE)
|
||||
let uint128 = UInt128.example
|
||||
check AbiEncoder.encode(uint256) == @(uint256.toBytesBE)
|
||||
check AbiEncoder.encode(uint128) == 16.zeroes & @(uint128.toBytesBE)
|
||||
check AbiEncoder.encode(1.i256) == 31.zeroes & 0x01'u8
|
||||
check AbiEncoder.encode(1.i128) == 31.zeroes & 0x01'u8
|
||||
check AbiEncoder.encode(-1.i256) == 0xFF'u8.repeat(32)
|
||||
check AbiEncoder.encode(-1.i128) == 0xFF'u8.repeat(32)
|
||||
|
||||
test "encodes byte arrays":
|
||||
let bytes3 = [1'u8, 2'u8, 3'u8]
|
||||
|
|
Loading…
Reference in New Issue