Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

merge from develop to main #12

Merged
merged 5 commits into from
Jul 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
80 changes: 54 additions & 26 deletions encdec/encode.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,54 +18,55 @@ import (
`dataTypes` is a comma-separated string of types. Eg: "string, uint, bool, uint".
- The sequence of types in `dataTypes` must match the sequence of values in `input`.
*/
func AbiEncode(inputValues string, dataTypes string) (res string) {
if len(inputValues) == 0 {
func AbiEncode(inputValuesStr string, dataTypesStr string) (res string) {
if len(inputValuesStr) == 0 {
res = "0x"
return res
}

// Split each input into a slice of string values
inputAsSlice := strings.Split(inputValues, ",")
typesAsSlice := strings.Split(dataTypes, ",")
if len(inputAsSlice) != len(typesAsSlice) {
panic(fmt.Sprintf("Number of input values does not match number of types - %d inputs to %d types", len(inputAsSlice), len(typesAsSlice)))
inputValuesSlice := strings.Split(inputValuesStr, ",")
dataTypesSlice := strings.Split(dataTypesStr, ",")
if len(inputValuesSlice) != len(dataTypesSlice) {
panic(fmt.Sprintf("Number of input values does not match number of types - %d inputs to %d types", len(inputValuesSlice), len(dataTypesSlice)))

}

// convert strings to the appropriate types
// TODO zubin resume here. Add other types. Complete the tests.
typedInputValuesSlice := make([]any, len(typesAsSlice))
for idx, ty := range typesAsSlice {
typedInputValuesSlice := make([]any, len(dataTypesSlice))

for idx, ty := range dataTypesSlice {
_ty := strings.TrimSpace(ty)
inp := inputAsSlice[idx]
inpValue := inputValuesSlice[idx]

switch _ty {
case "string":
typedInputValuesSlice[idx] = inputAsSlice[idx]
typedInputValuesSlice[idx] = inputValuesSlice[idx]
case "address":
typedInputValuesSlice[idx] = common.HexToAddress(inputAsSlice[idx])
case "uint", "uint256":
typedValue, ok := new(big.Int).SetString(inp, 10)
typedInputValuesSlice[idx] = common.HexToAddress(inputValuesSlice[idx])

// ints and uints greater than 64 bits need special treatment using BigInt.
case "uint", "uint128", "uint256", "int", "int128", "int256":
typedValue, ok := new(big.Int).SetString(inpValue, 10)
if !ok {
panic(fmt.Sprintf("Error converting %q of type %s to big.Int", inp, _ty))
panic(fmt.Sprintf("Error converting %q of type %s to big.Int", inpValue, _ty))
}
typedInputValuesSlice[idx] = typedValue

case "uint8", "uint16", "uint32", "uint64":
var bitsize int
if _ty == "uint8" {
bitsize = 8
} else {
// convert the last two characters into int and assign it to bitsize
bsize, err := strconv.Atoi(_ty[4:])
if err != nil {
panic(fmt.Sprintf("Unsupported bitsize %q in %s", bsize, _ty))
}
bitsize = bsize

// convert the last two characters into int and assign it to bitsize
bsize, err := strconv.Atoi(_ty[4:])
if err != nil {
panic(fmt.Sprintf("Unsupported bitsize %q in %s", bsize, _ty))
}
bitsize = bsize

typedValue, err := strconv.ParseUint(inp, 10, bitsize)
typedValue, err := strconv.ParseUint(inpValue, 10, bitsize)
if err != nil {
panic(fmt.Sprintf("Error converting %q of type %s to big.Int", inp, _ty))
panic(fmt.Sprintf("Error converting %q of type %s to uint%d: %s", inpValue, _ty, bitsize, err))
}
if bitsize == 8 {
typedInputValuesSlice[idx] = uint8(typedValue)
Expand All @@ -79,13 +80,40 @@ func AbiEncode(inputValues string, dataTypes string) (res string) {
if bitsize == 64 {
typedInputValuesSlice[idx] = uint64(typedValue)
}
case "int8", "int16", "int32", "int64":
var bitsize int

// convert the last two characters into int and assign it to bitsize
bsize, err := strconv.Atoi(_ty[3:])
if err != nil {
panic(fmt.Sprintf("Unsupported bitsize %q in %s", bsize, _ty))
}
bitsize = bsize

typedValue, err := strconv.ParseInt(inpValue, 10, bitsize)
if err != nil {
panic(fmt.Sprintf("Error converting %q of type %s to int%d", inpValue, _ty, bitsize))
}
if bitsize == 8 {
typedInputValuesSlice[idx] = int8(typedValue)
}
if bitsize == 16 {
typedInputValuesSlice[idx] = int16(typedValue)
}
if bitsize == 32 {
typedInputValuesSlice[idx] = int32(typedValue)
}
if bitsize == 64 {
typedInputValuesSlice[idx] = int64(typedValue)
}

default:
panic(fmt.Sprintf("Unsupported type %q", _ty))
}

}

var args abi.Arguments = dataTypesToAbiArgs(dataTypes)
var args abi.Arguments = dataTypesToAbiArgs(dataTypesStr)
values, err := args.PackValues(typedInputValuesSlice)
if err != nil {
panic(fmt.Sprintf("Error packing input values: %v", err))
Expand Down
52 changes: 35 additions & 17 deletions encdec/encode_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,49 +20,67 @@ func TestAbiEncode(t *testing.T) {
want: "0x",
},
{
name: "HappyPath#2-multiple scalar types",
name: "Uint Encoding OK",
input: "64,128,256",
dataTypes: "uint64,uint128,uint256",
want: "0x000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000100",
},
{
name: "Int Encoding OK",
input: "64,128,256",
dataTypes: "int64,int128,int256",
want: "0x000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000100",
},
{
name: "int & uint - positive integers",
input: "-256,256",
dataTypes: "int256,uint256",
want: "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000000000000000000000000000000000000000000000000000000000000100",
},
{
name: "int & uint - negative integer",
input: "0,0,256,256",
dataTypes: "int,uint,int256,uint256",
want: "0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000100",
},
{
name: "HappyPath-multiple scalar types",
input: "8,1234567,hextool",
dataTypes: "uint16, uint, string",
want: "0x0000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000012d68700000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000007686578746f6f6c00000000000000000000000000000000000000000000000000",
},
{
name: "HappyPath#3-with address",
name: "HappyPath-with address",
input: "8,0x208AA722Aca42399eaC5192EE778e4D42f4E5De3,hextool is rad",
dataTypes: "uint32,address,string",
want: "0x0000000000000000000000000000000000000000000000000000000000000008000000000000000000000000208aa722aca42399eac5192ee778e4d42f4e5de30000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000000e686578746f6f6c20697320726164000000000000000000000000000000000000",
},
{
name: "HappyPath#3-with address",
name: "HappyPath-with address",
input: "8,0x208AA722Aca42399eaC5192EE778e4D42f4E5De3,hextool is rad",
dataTypes: "uint32,address,string",
want: "0x0000000000000000000000000000000000000000000000000000000000000008000000000000000000000000208aa722aca42399eac5192ee778e4d42f4e5de30000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000000e686578746f6f6c20697320726164000000000000000000000000000000000000",
},
{
name: "HappyPath#3-panics with mismatched input length",
name: "HappyPath-panics with mismatched input length",
panics: true,
input: "hextool is rad",
dataTypes: "uint32,address,string",
want: "Number of input values does not match number of types",
},
{
name: "HappyPath#4-panics with unknown type",
name: "HappyPath-panics with unknown type",
panics: true,
input: "8,0x208AA722Aca42399eaC5192EE778e4D42f4E5De3,hextool is rad",
dataTypes: "uint999,address,string",
want: "Unsupported type",
},
// {
// name: "HappyPath#4-multiple scalars including address",
// inputHex: "00000000000000000000000000000000000000000000000000000000000003e90000000000000000000000000000000000000000000000000000000000000060000000000000000000000000208aa722aca42399eac5192ee778e4d42f4e5de300000000000000000000000000000000000000000000000000000000000000057a7562696e000000000000000000000000000000000000000000000000000000",
// dataTypes: "uint16, string, address",
// want: []any{uint16(1001), "zubin", common.HexToAddress("0x208aa722aca42399eac5192ee778e4d42f4e5de3")},
// },
// {
// name: "HappyPath#5-empty input",
// inputHex: "0x",
// dataTypes: "address",
// want: []any{},
// },
{
name: "HappyPath-multiple scalars including address",
input: "1981,0x208AA722Aca42399eaC5192EE778e4D42f4E5De3",
dataTypes: "int64,address",
want: "0x00000000000000000000000000000000000000000000000000000000000007bd000000000000000000000000208aa722aca42399eac5192ee778e4d42f4e5de3",
},
}
for _, tc := range tests {
t.Run(tc.name, func(t *testing.T) {
Expand Down
Loading