More complete DynamicBytes implementation
This commit is contained in:
parent
9a0f1425c1
commit
74ae794993
|
@ -37,7 +37,7 @@ proc fromJson*[N](n: JsonNode, argName: string, result: var FixedBytes[N]) {.inl
|
|||
# expects base 16 string, starting with "0x"
|
||||
bytesFromJson(n, argName, array[N, byte](result))
|
||||
|
||||
proc fromJson*[N](n: JsonNode, argName: string, result: var DynamicBytes[N]) {.inline.} =
|
||||
proc fromJson*(n: JsonNode, argName: string, result: var DynamicBytes) {.inline.} =
|
||||
n.kind.expect(JString, argName)
|
||||
result = fromHex(type result, n.getStr())
|
||||
|
||||
|
@ -61,7 +61,7 @@ proc `%`*(v: Quantity): JsonNode =
|
|||
proc `%`*[N](v: FixedBytes[N]): JsonNode =
|
||||
result = %("0x" & array[N, byte](v).toHex)
|
||||
|
||||
proc `%`*[N](v: DynamicBytes[N]): JsonNode =
|
||||
proc `%`*(v: DynamicBytes): JsonNode =
|
||||
result = %("0x" & toHex(v))
|
||||
|
||||
proc `%`*(v: Address): JsonNode =
|
||||
|
@ -75,7 +75,7 @@ proc writeHexValue(w: JsonWriter, v: openarray[byte]) =
|
|||
w.stream.writeHex v
|
||||
w.stream.write "\""
|
||||
|
||||
proc writeValue*[N](w: var JsonWriter, v: DynamicBytes[N]) =
|
||||
proc writeValue*(w: var JsonWriter, v: DynamicBytes) =
|
||||
writeHexValue w, distinctBase(v)
|
||||
|
||||
proc writeValue*[N](w: var JsonWriter, v: FixedBytes[N]) =
|
||||
|
@ -87,7 +87,7 @@ proc writeValue*(w: var JsonWriter, v: Address) =
|
|||
proc writeValue*(w: var JsonWriter, v: TypedTransaction) =
|
||||
writeHexValue w, distinctBase(v)
|
||||
|
||||
proc readValue*[N](r: var JsonReader, T: type DynamicBytes[N]): T =
|
||||
proc readValue*(r: var JsonReader, T: type DynamicBytes): T =
|
||||
fromHex(T, r.readValue(string))
|
||||
|
||||
proc readValue*[N](r: var JsonReader, T: type FixedBytes[N]): T =
|
||||
|
@ -108,7 +108,7 @@ proc `$`*(v: Address): string {.inline.} =
|
|||
proc `$`*(v: TypedTransaction): string {.inline.} =
|
||||
"0x" & distinctBase(v).toHex
|
||||
|
||||
proc `$`*[N](v: DynamicBytes[N]): string {.inline.} =
|
||||
proc `$`*(v: DynamicBytes): string {.inline.} =
|
||||
"0x" & toHex(v)
|
||||
|
||||
proc `%`*(x: EthSend): JsonNode =
|
||||
|
|
|
@ -62,10 +62,13 @@ func encodeDynamic(v: openarray[byte]): EncodeResult =
|
|||
result.data &= y.toHex.toLower
|
||||
result.data &= "00".repeat(v.len mod 32)
|
||||
|
||||
func encode*[N](x: DynamicBytes[N]): EncodeResult {.inline.} =
|
||||
encodeDynamic(distinctBase(x))
|
||||
func encode*(x: DynamicBytes): EncodeResult {.inline.} =
|
||||
encodeDynamic(distinctBase x)
|
||||
|
||||
func decodeDynamic(input: string, offset: int, to: var openarray[byte]): int =
|
||||
func decodeDynamic(input: string,
|
||||
offset: int,
|
||||
minLen, maxLen: int,
|
||||
to: var openarray[byte]): int =
|
||||
var dataOffset, dataLen: UInt256
|
||||
result = decode(input, offset, dataOffset)
|
||||
discard decode(input, dataOffset.truncate(int) * 2, dataLen)
|
||||
|
@ -74,9 +77,8 @@ func decodeDynamic(input: string, offset: int, to: var openarray[byte]): int =
|
|||
let actualDataOffset = (dataOffset.truncate(int) + 32) * 2
|
||||
hexToByteArray(input[actualDataOffset .. actualDataOffset + meaningfulLen - 1], to)
|
||||
|
||||
func decode*[N](input: string, offset: int, to: var DynamicBytes[N]): int {.inline.} =
|
||||
{.fatal: "decodeDynamic is not implemented properly".}
|
||||
decodeDynamic(input, offset, distinctBase(to))
|
||||
func decode*(input: string, offset: int, to: var DynamicBytes): int {.inline.} =
|
||||
decodeDynamic(input, offset, to.minLen, to.maxLen, distinctBase(to))
|
||||
|
||||
macro makeTypeEnum(): untyped =
|
||||
## This macro creates all the various types of Solidity contracts and maps
|
||||
|
|
|
@ -9,7 +9,9 @@ type
|
|||
highestBlock*: int
|
||||
|
||||
FixedBytes*[N: static[int]] = distinct array[N, byte]
|
||||
DynamicBytes*[MaxLen: static[int]] = distinct seq[byte]
|
||||
DynamicBytes*[
|
||||
minLen: static[int] = 0,
|
||||
maxLen: static[int] = high(int)] = distinct seq[byte]
|
||||
|
||||
Address* = distinct array[20, byte]
|
||||
TxHash* = FixedBytes[32]
|
||||
|
@ -210,7 +212,7 @@ type
|
|||
gasLimit*: Quantity
|
||||
gasUsed*: Quantity
|
||||
timestamp*: Quantity
|
||||
extraData*: DynamicBytes[32]
|
||||
extraData*: DynamicBytes[32, 32]
|
||||
baseFeePerGas*: UInt256
|
||||
blockHash*: BlockHash
|
||||
transactions*: seq[TypedTransaction]
|
||||
|
@ -218,7 +220,7 @@ type
|
|||
template `==`*[N](a, b: FixedBytes[N]): bool =
|
||||
distinctBase(a) == distinctBase(b)
|
||||
|
||||
template `==`*[N](a, b: DynamicBytes[N]): bool =
|
||||
template `==`*[minLen, maxLen](a, b: DynamicBytes[minLen, maxLen]): bool =
|
||||
distinctBase(a) == distinctBase(b)
|
||||
|
||||
proc `==`*(a, b: Address): bool {.inline.} =
|
||||
|
@ -239,7 +241,7 @@ func hash*[N](bytes: FixedBytes[N]): Hash =
|
|||
template toHex*[N](x: FixedBytes[N]): string =
|
||||
toHex(distinctBase x)
|
||||
|
||||
template toHex*[N](x: DynamicBytes[N]): string =
|
||||
template toHex*[minLen, maxLen](x: DynamicBytes[minLen, maxLen]): string =
|
||||
toHex(distinctBase x)
|
||||
|
||||
template toHex*(x: Address): string =
|
||||
|
@ -248,14 +250,6 @@ template toHex*(x: Address): string =
|
|||
template fromHex*(T: type Address, hexStr: string): T =
|
||||
T fromHex(distinctBase(T), hexStr)
|
||||
|
||||
func fromHex*[N](T: type DynamicBytes[N], hexStr: string): T =
|
||||
if hexStr.len > N * 2:
|
||||
raise newException(ValueError, "hex input too large")
|
||||
T hexToSeqByte(hexStr)
|
||||
|
||||
template fromHex*[N](T: type FixedBytes[N], hexStr: string): T =
|
||||
T fromHex(distinctBase(T), hexStr)
|
||||
|
||||
template skip0xPrefix(hexStr: string): int =
|
||||
## Returns the index of the first meaningful char in `hexStr` by skipping
|
||||
## "0x" prefix
|
||||
|
@ -269,3 +263,24 @@ proc strip0xPrefix*(s: string): string =
|
|||
else:
|
||||
s
|
||||
|
||||
func fromHex*[minLen](T: type DynamicBytes[minLen, maxLen], hexStr: string): T =
|
||||
let prefixLen = skip0xPrefix(hexStr)
|
||||
let hexDataLen = hexStr.len - prefixLen
|
||||
|
||||
if hexDataLen < minLen * 2:
|
||||
raise newException(ValueError, "hex input too small")
|
||||
|
||||
if hexDataLen > maxLen * 2:
|
||||
raise newException(ValueError, "hex input too large")
|
||||
|
||||
T hexToSeqByte(hexStr)
|
||||
|
||||
template fromHex*[N](T: type FixedBytes[N], hexStr: string): T =
|
||||
T fromHex(distinctBase(T), hexStr)
|
||||
|
||||
proc toArray*[N](data: DynamicBytes[N, N]): array[N, byte] =
|
||||
copyMem(addr result[0], unsafeAddr distinctBase(data)[0], N)
|
||||
|
||||
template bytes*(data: DynamicBytes): seq[byte] =
|
||||
distinctBase data
|
||||
|
||||
|
|
Loading…
Reference in New Issue