mirror of
https://github.com/status-im/nim-contract-abi.git
synced 2025-02-27 09:50:29 +00:00
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) =
|
func finishTuple(encoder: var AbiEncoder) =
|
||||||
encoder.encode(encoder.stack.pop())
|
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
|
let padlen = (32 - len mod 32) mod 32
|
||||||
for _ in 0..<padlen:
|
for _ in 0..<padlen:
|
||||||
encoder.append([0'u8])
|
encoder.append([padding])
|
||||||
|
|
||||||
func padleft(encoder: var AbiEncoder, bytes: openArray[byte]) =
|
func padleft(encoder: var AbiEncoder, bytes: openArray[byte], padding=0'u8) =
|
||||||
encoder.pad(bytes.len)
|
encoder.pad(bytes.len, padding)
|
||||||
encoder.append(bytes)
|
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.append(bytes)
|
||||||
encoder.pad(bytes.len)
|
encoder.pad(bytes.len, padding)
|
||||||
|
|
||||||
func encode(encoder: var AbiEncoder, value: SomeUnsignedInt | StUint) =
|
func encode(encoder: var AbiEncoder, value: SomeUnsignedInt | StUint) =
|
||||||
encoder.padleft(value.toBytesBE)
|
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) =
|
func encode(encoder: var AbiEncoder, value: bool) =
|
||||||
encoder.encode(if value: 1'u8 else: 0'u8)
|
encoder.encode(if value: 1'u8 else: 0'u8)
|
||||||
|
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
|
|
||||||
import std/unittest
|
import std/unittest
|
||||||
|
import std/sequtils
|
||||||
import pkg/stint
|
import pkg/stint
|
||||||
import pkg/stew/byteutils
|
import pkg/stew/byteutils
|
||||||
import contractabi
|
import contractabi
|
||||||
@ -27,6 +28,16 @@ suite "ABI encoding":
|
|||||||
0x11'u8 & 0x22'u8 & 0x33'u8 & 0x44'u8 &
|
0x11'u8 & 0x22'u8 & 0x33'u8 & 0x44'u8 &
|
||||||
0x55'u8 & 0x66'u8 & 0x77'u8 & 0x88'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":
|
test "encodes ranges":
|
||||||
type SomeRange = range[0x0000'u16..0xAAAA'u16]
|
type SomeRange = range[0x0000'u16..0xAAAA'u16]
|
||||||
check AbiEncoder.encode(SomeRange(0x1122)) == 30.zeroes & 0x11'u8 & 0x22'u8
|
check AbiEncoder.encode(SomeRange(0x1122)) == 30.zeroes & 0x11'u8 & 0x22'u8
|
||||||
@ -40,9 +51,13 @@ suite "ABI encoding":
|
|||||||
|
|
||||||
test "encodes stints":
|
test "encodes stints":
|
||||||
let uint256 = UInt256.example
|
let uint256 = UInt256.example
|
||||||
check AbiEncoder.encode(uint256) == @(uint256.toBytesBE)
|
|
||||||
let uint128 = UInt128.example
|
let uint128 = UInt128.example
|
||||||
|
check AbiEncoder.encode(uint256) == @(uint256.toBytesBE)
|
||||||
check AbiEncoder.encode(uint128) == 16.zeroes & @(uint128.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":
|
test "encodes byte arrays":
|
||||||
let bytes3 = [1'u8, 2'u8, 3'u8]
|
let bytes3 = [1'u8, 2'u8, 3'u8]
|
||||||
|
Loading…
x
Reference in New Issue
Block a user