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

Error: Missing bytes[] handling for ABI #131

Open
yongkangchia opened this issue Apr 22, 2024 · 1 comment
Open

Error: Missing bytes[] handling for ABI #131

yongkangchia opened this issue Apr 22, 2024 · 1 comment

Comments

@yongkangchia
Copy link

Problem:

The current limitation of the go-tron-sdk that it does not process []bytes well.Specifically func GetPaddedParam(param []Param) ([]byte, error) does not handle []bytes (code).

I was trying to encode and call foo(bytes[]) but wasnt able to. i dont think "bytes[]" is handled.

Solution:

this clause here for slices doesn't deal with byte elements:

gotron-sdk/pkg/abi/abi.go

Lines 116 to 151 in 1e82440

if ty.T == eABI.SliceTy || ty.T == eABI.ArrayTy {
if ty.Elem.T == eABI.AddressTy {
tmp, ok := v.([]interface{})
if !ok {
return nil, fmt.Errorf("unable to convert array of addresses %+v", p)
}
v = make([]eCommon.Address, 0)
for i := range tmp {
addr, err := convetToAddress(tmp[i])
if err != nil {
return nil, err
}
v = append(v.([]eCommon.Address), addr)
}
}
if (ty.Elem.T == eABI.IntTy || ty.Elem.T == eABI.UintTy) &&
ty.Elem.Size > 64 {
tmp := make([]*big.Int, 0)
tmpSlice, ok := v.([]string)
if !ok {
return nil, fmt.Errorf("unable to convert array of unints %+v", p)
}
for i := range tmpSlice {
var value *big.Int
// check for hex char
if strings.HasPrefix(tmpSlice[i], "0x") {
value, _ = new(big.Int).SetString(tmpSlice[i][2:], 16)
} else {
value, _ = new(big.Int).SetString(tmpSlice[i], 10)
}
tmp = append(tmp, value)
}
v = tmp
}
}

see the byte handling here:

gotron-sdk/pkg/abi/abi.go

Lines 161 to 166 in 1e82440

if ty.T == eABI.BytesTy || ty.T == eABI.FixedBytesTy {
var err error
if v, err = convertToBytes(ty, v); err != nil {
return nil, err
}
}

the bytes array should be handled at when

ty.T == eABI.SliceTy

@yongkangchia
Copy link
Author

Proposed Solution

// Existing code
	if ty.T == eABI.SliceTy || ty.T == eABI.ArrayTy {
				// ..... previous code

				// handle bytes[]
				if ty.Elem.T == eABI.BytesTy || ty.Elem.T == eABI.FixedBytesTy {
					fmt.Println("Processing bytes slice/array")
					fmt.Println("Type of v:", reflect.TypeOf(v))

					switch v.(type) {
					// print the type of v
					case []interface{}:
						tmp, ok := v.([]interface{})
						if !ok {
							return nil, fmt.Errorf("unable to convert array of bytes %+v", p)
						}
						bytesSlice := make([][]byte, len(tmp))

						for i := range tmp {
							if tmp[i] == nil {
								// Handle empty byte array
								bytesSlice[i] = []byte{}
							} else {
								value, err := convertToBytes(*ty.Elem, tmp[i])
								if err != nil {
									return nil, fmt.Errorf("unable to convert bytes element %+v: %v", tmp[i], err)
								}
								bytesSlice[i] = value.([]byte)
							}
						}
						v = bytesSlice
					case string:
						tmp, ok := v.(string)
						if !ok {
							return nil, fmt.Errorf("unable to convert string to bytes %+v", p)
						}
						var jsonArray []string
						// Using json array to parse string
						err := json.Unmarshal([]byte(tmp), &jsonArray)
						if err != nil {
							return nil, fmt.Errorf("unable to parse string as JSON array %+v: %v", tmp, err)
						}
						bytesSlice := make([][]byte, len(jsonArray))
						for i, elem := range jsonArray {
							if elem == "" {
								// Handle empty byte string
								bytesSlice[i] = []byte{}
							} else {
								if strings.HasPrefix(elem, "0x") {
									elem = elem[2:]
								}
								bytesSlice[i], err = hex.DecodeString(elem)
								if err != nil {
									return nil, fmt.Errorf("unable to decode byte string %+v: %v", elem, err)
								}
							}
						}
						v = bytesSlice

					case []uint8:
						tmp, ok := v.([][]uint8)
						bytesSlice := make([][]byte, len(tmp))
						for i := range tmp {
							if !ok {
								return nil, fmt.Errorf("unable to convert array of bytes %+v", p)
							}
							if len(tmp[i]) == 0 {
								// Handle empty byte array
								bytesSlice[i] = nil
							} else {
								bytesSlice[i] = tmp[i]
							}
						}
						v = bytesSlice
					default:
						fmt.Println("Invalid bytes slice/array:", v)
						return nil, fmt.Errorf("invalid param %+v", v)
					}
				}
			}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant