From ea7037dc487a227dbe235cd5cffc705eef0357f0 Mon Sep 17 00:00:00 2001 From: Olivier Guimbal Date: Thu, 3 Mar 2022 18:35:42 +0100 Subject: [PATCH] Add some real-life encoding tests --- src/Eth/Abi/Encode.elm | 13 ---- tests/EncodeAbi.elm | 146 +++++++++++++++++++++++++++++++++++------ 2 files changed, 125 insertions(+), 34 deletions(-) diff --git a/src/Eth/Abi/Encode.elm b/src/Eth/Abi/Encode.elm index f321e85..f1f6fb6 100644 --- a/src/Eth/Abi/Encode.elm +++ b/src/Eth/Abi/Encode.elm @@ -46,19 +46,6 @@ import String.UTF8 as UTF8 {-| -} - --- type Encoding --- = AddressE Address --- | UintE BigInt --- | IntE BigInt --- | BoolE Bool --- | DBytesE Hex --- | BytesE Hex --- | StringE String --- | ListE (List Encoding) --- | CustomE String - - functionCall : String -> List Encoding -> Result String Hex functionCall abiSig args = abiEncodeList_ args diff --git a/tests/EncodeAbi.elm b/tests/EncodeAbi.elm index 2032f5e..5deb3c5 100644 --- a/tests/EncodeAbi.elm +++ b/tests/EncodeAbi.elm @@ -1,9 +1,9 @@ module EncodeAbi exposing (..) -import BigInt exposing (BigInt) -import Eth.Abi.Encode as Abi -import Eth.Types exposing (Hex) -import Eth.Utils exposing (hexToString, remove0x) +import BigInt exposing (fromInt) +import Eth.Abi.Encode as E +import Eth.Types exposing (Address, Hex) +import Eth.Utils exposing (hexToString, remove0x, unsafeToAddress, unsafeToHex) import Expect import String exposing (join) import String.Extra exposing (wrapWith) @@ -47,9 +47,9 @@ pointers = ] encoded = - Abi.abiEncodeList - [ Abi.uint <| BigInt.fromInt 1 - , Abi.uint <| BigInt.fromInt 2 + E.abiEncodeList + [ E.uint <| BigInt.fromInt 1 + , E.uint <| BigInt.fromInt 2 ] in expectHex exp encoded @@ -69,8 +69,8 @@ pointers = ] encoded = - Abi.abiEncodeList - [ Abi.list [ Abi.uint <| BigInt.fromInt 2 ] + E.abiEncodeList + [ E.list [ E.uint <| BigInt.fromInt 2 ] ] in expectHex exp encoded @@ -91,9 +91,9 @@ pointers = ] encoded = - Abi.abiEncodeList - [ Abi.uint <| BigInt.fromInt 1 - , Abi.list [ Abi.uint <| BigInt.fromInt 2 ] + E.abiEncodeList + [ E.uint <| BigInt.fromInt 1 + , E.list [ E.uint <| BigInt.fromInt 2 ] ] in expectHex exp encoded @@ -115,16 +115,115 @@ pointers = ] encoded = - Abi.abiEncodeList - [ Abi.uint <| BigInt.fromInt 1 - , Abi.list [ Abi.uint <| BigInt.fromInt 2 ] - , Abi.uint <| BigInt.fromInt 3 + E.abiEncodeList + [ E.uint <| BigInt.fromInt 1 + , E.list [ E.uint <| BigInt.fromInt 2 ] + , E.uint <| BigInt.fromInt 3 ] in expectHex exp encoded ] +someCallBody : List SomeStruct -> Result String Hex +someCallBody elts = + let + eltsEncoded = + elts |> List.map encodeSubStruct |> E.list + + someToken = + unsafeToAddress "0x0eb3a705fc54725037cc9e008bdede697f62f335" + in + E.abiEncodeList [ E.uint (fromInt 8), E.address someToken, eltsEncoded ] + + + + +-- struct SomeStruct { +-- bytes32 someBytes32Str; +-- address token; +-- bytes callData; +-- bool someBool; +-- } +type alias SomeStruct = + { someBytes32Str : String + , token : Address + , callData : Hex + , someBool : Bool + } + + +encodeSubStruct : SomeStruct -> E.Encoding +encodeSubStruct o = + let + nameEncoded = + o.someBytes32Str + |> E.stringToHex + |> unsafeToHex + |> E.staticBytes + in + E.tuple [ nameEncoded, E.address o.token, E.bytes o.callData, E.bool o.someBool ] + + +complexStruct : Test +complexStruct = + describe "Encoding complex struct" + [ test "Encode struct with empty array" <| + \_ -> + let + encoded = + someCallBody [] + + expected = + [ "0000000000000000000000000000000000000000000000000000000000000008" -- id + , "0000000000000000000000000eb3a705fc54725037cc9e008bdede697f62f335" -- out otken + , "0000000000000000000000000000000000000000000000000000000000000060" -- array pointer + , "0000000000000000000000000000000000000000000000000000000000000000" -- array len + ] + in + Expect.equal (Ok (unsafeToHex <| join "" expected)) encoded + , test "Encode struct with array elements" <| + \_ -> + let + encoded = + someCallBody + [ { someBytes32Str = "ZeroEx" + , token = otherToken + , callData = unsafeToHex "0x11111111111111111111111111111111111111111111111111111111111111112222" + , someBool = True + } + ] + + expected = + [ + "0000000000000000000000000000000000000000000000000000000000000008" -- id + , "0000000000000000000000000eb3a705fc54725037cc9e008bdede697f62f335" -- token + , "0000000000000000000000000000000000000000000000000000000000000060" -- array pointer + , "0000000000000000000000000000000000000000000000000000000000000001" -- array len + , "0000000000000000000000000000000000000000000000000000000000000020" -- first elt pointer + , "5a65726f45780000000000000000000000000000000000000000000000000000" -- "ZeroEx" + , "0000000000000000000000002170ed0880ac9a755fd29b2688956bd959f933f8" -- token + , "0000000000000000000000000000000000000000000000000000000000000080" -- pointer to calldata (two lines below) + , "0000000000000000000000000000000000000000000000000000000000000001" -- boolean "true" + , "0000000000000000000000000000000000000000000000000000000000000022" -- calldata len + , "1111111111111111111111111111111111111111111111111111111111111111" -- calldata + , "2222000000000000000000000000000000000000000000000000000000000000" -- calldata (part 2) + ] + in + expectHex expected encoded + ] + + +coalesce : a -> Maybe a -> a +coalesce a ma = + case ma of + Nothing -> + a + + Just v -> + v + + expectHex : List String -> Result String Hex -> Expect.Expectation expectHex expected result = case result of @@ -132,7 +231,12 @@ expectHex expected result = Expect.fail e Ok hex -> - Expect.equal (expected |> join "" |> wrapWith 64 " ") (hex |> hexToString |> remove0x |> wrapWith 64 " ") + Expect.equal (wrapWith 64 " " <| join "" expected) (wrapWith 64 " " <| remove0x <| hexToString <| hex) + + +otherToken : Eth.Types.Address +otherToken = + unsafeToAddress "0x2170ed0880ac9a755fd29b2688956bd959f933f8" @@ -144,23 +248,23 @@ encodeInt = describe "Int Encoding" [ test "-120" <| \_ -> - Abi.abiEncode (Abi.int <| BigInt.fromInt -120) + E.abiEncode (E.int <| BigInt.fromInt -120) |> Result.map Eth.Utils.hexToString |> Expect.equal (Ok "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff88") , test "120" <| \_ -> - Abi.abiEncode (Abi.int <| BigInt.fromInt 120) + E.abiEncode (E.int <| BigInt.fromInt 120) |> Result.map Eth.Utils.hexToString |> Expect.equal (Ok "0x0000000000000000000000000000000000000000000000000000000000000078") , test "max positive int256" <| \_ -> BigInt.fromIntString "57896044618658097711785492504343953926634992332820282019728792003956564819967" - |> Maybe.map (Abi.int >> Abi.abiEncode >> Result.map Eth.Utils.hexToString) + |> Maybe.map (E.int >> E.abiEncode >> Result.map Eth.Utils.hexToString) |> Expect.equal (Just (Ok "0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff")) , test "max negative int256" <| \_ -> BigInt.fromIntString "-57896044618658097711785492504343953926634992332820282019728792003956564819968" - |> Maybe.map (Abi.int >> Abi.abiEncode >> Result.map Eth.Utils.hexToString) + |> Maybe.map (E.int >> E.abiEncode >> Result.map Eth.Utils.hexToString) |> Expect.equal (Just (Ok "0x8000000000000000000000000000000000000000000000000000000000000000")) ]