mirror of
https://github.com/status-im/nim-contract-abi.git
synced 2025-02-19 14:14:18 +00:00
Add support for Ethereum addresses
This commit is contained in:
parent
9aaafdb5b5
commit
e3c9aa4368
26
contractabi/address.nim
Normal file
26
contractabi/address.nim
Normal file
@ -0,0 +1,26 @@
|
||||
import pkg/stew/byteutils
|
||||
import pkg/questionable
|
||||
import pkg/upraises
|
||||
|
||||
push: {.upraises: [].}
|
||||
|
||||
type
|
||||
Address* = distinct array[20, byte]
|
||||
|
||||
func init*(_: type Address, bytes: array[20, byte]): Address =
|
||||
Address(bytes)
|
||||
|
||||
func init*(_: type Address, hex: string): ?Address =
|
||||
try:
|
||||
let bytes = array[20, byte].fromHex(hex)
|
||||
some Address.init(bytes)
|
||||
except ValueError:
|
||||
none Address
|
||||
|
||||
func toArray*(address: Address): array[20, byte] =
|
||||
array[20, byte](address)
|
||||
|
||||
func `$`*(address: Address): string =
|
||||
"0x" & toHex(address.toArray)
|
||||
|
||||
func `==`*(a, b: Address): bool {.borrow.}
|
@ -5,6 +5,10 @@ import pkg/questionable/results
|
||||
import pkg/upraises
|
||||
import ./encoding
|
||||
import ./integers
|
||||
import ./address
|
||||
|
||||
export stint
|
||||
export address
|
||||
|
||||
push: {.upraises:[].}
|
||||
|
||||
@ -114,6 +118,11 @@ func decode(decoder: var AbiDecoder, T: type enum): ?!T =
|
||||
else:
|
||||
failure "invalid enum value"
|
||||
|
||||
func decode(decoder: var AbiDecoder, T: type Address): ?!T =
|
||||
var bytes: array[20, byte]
|
||||
bytes[0..<20] =(?decoder.read(20))[0..<20]
|
||||
success T.init(bytes)
|
||||
|
||||
func decode[I](decoder: var AbiDecoder, T: type array[I, byte]): ?!T =
|
||||
var arr: T
|
||||
arr[0..<arr.len] = ?decoder.read(arr.len, padRight)
|
||||
|
@ -2,8 +2,10 @@ import pkg/stint
|
||||
import pkg/upraises
|
||||
import pkg/stew/byteutils
|
||||
import ./integers
|
||||
import ./address
|
||||
|
||||
export stint
|
||||
export address
|
||||
|
||||
push: {.upraises:[].}
|
||||
|
||||
@ -95,6 +97,9 @@ func encode(encoder: var AbiEncoder, value: bool) =
|
||||
func encode(encoder: var AbiEncoder, value: enum) =
|
||||
encoder.encode(uint64(ord(value)))
|
||||
|
||||
func encode(encoder: var AbiEncoder, value: Address) =
|
||||
encoder.padleft(value.toArray)
|
||||
|
||||
func encode[I](encoder: var AbiEncoder, bytes: array[I, byte]) =
|
||||
encoder.padright(bytes)
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
import std/random
|
||||
import std/sequtils
|
||||
import pkg/stint
|
||||
import pkg/contractabi/address
|
||||
|
||||
randomize()
|
||||
|
||||
@ -23,3 +24,6 @@ proc example*(T: type StUint): T =
|
||||
|
||||
proc example*(T: type StInt): T =
|
||||
cast[T](StUint[T.bits].example)
|
||||
|
||||
proc example*(T: type Address): T =
|
||||
Address.init(array[20, byte].example)
|
||||
|
25
tests/contractabi/testAddress.nim
Normal file
25
tests/contractabi/testAddress.nim
Normal file
@ -0,0 +1,25 @@
|
||||
import std/unittest
|
||||
import pkg/contractabi/address
|
||||
import pkg/questionable
|
||||
|
||||
suite "Address":
|
||||
|
||||
let address = Address.init [
|
||||
0x1'u8, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa,
|
||||
0x1 , 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa
|
||||
]
|
||||
|
||||
test "can be converted to string":
|
||||
check $address == "0x0102030405060708090a0102030405060708090a"
|
||||
|
||||
test "can be parsed from string":
|
||||
check:
|
||||
Address.init("0x0102030405060708090a0102030405060708090a") == some address
|
||||
|
||||
test "parsing fails when string does not contain proper hex":
|
||||
check:
|
||||
Address.init("0xfoo2030405060708090a0102030405060708090a") == none Address
|
||||
|
||||
test "parsing fails when string does not contain 20 bytes":
|
||||
check:
|
||||
Address.init("0x0102030405060708090a010203040506070809") == none Address
|
@ -84,6 +84,9 @@ suite "ABI decoding":
|
||||
checkDecode(Int128)
|
||||
checkDecode(Int256)
|
||||
|
||||
test "decodes addresses":
|
||||
checkDecode(Address.example)
|
||||
|
||||
test "decodes byte arrays":
|
||||
checkDecode([1'u8, 2'u8, 3'u8])
|
||||
checkDecode(array[32, byte].example)
|
||||
|
@ -59,6 +59,10 @@ suite "ABI encoding":
|
||||
check AbiEncoder.encode(-1.i256) == 0xFF'u8.repeat(32)
|
||||
check AbiEncoder.encode(-1.i128) == 0xFF'u8.repeat(32)
|
||||
|
||||
test "encodes addresses":
|
||||
let address = Address.example
|
||||
check AbiEncoder.encode(address) == 12.zeroes & @(address.toArray)
|
||||
|
||||
test "encodes byte arrays":
|
||||
let bytes3 = [1'u8, 2'u8, 3'u8]
|
||||
check AbiEncoder.encode(bytes3) == @bytes3 & 29.zeroes
|
||||
|
@ -1,3 +1,4 @@
|
||||
import ./contractabi/testAddress
|
||||
import ./contractabi/testEncoding
|
||||
import ./contractabi/testDecoding
|
||||
import ./contractabi/testCustomTypes
|
||||
|
Loading…
x
Reference in New Issue
Block a user