web3j icon indicating copy to clipboard operation
web3j copied to clipboard

dynamic data encode utf8String have bug

Open harrylee2015 opened this issue 3 years ago • 3 comments

After dynamic array encoding, the value is not expected, there are error characters!

harrylee2015 avatar Jul 04 '22 11:07 harrylee2015

I looked at the source code and fixed it locally. dynameic arrary for utf8-string have a bug.

https://github.com/web3j/web3j/blob/master/abi/src/main/java/org/web3j/abi/TypeEncoder.java#L346

fixed function.

private static <T extends Type> String encodeArrayValuesOffsets(DynamicArray<T> value) {
        StringBuilder result = new StringBuilder();
        boolean arrayOfBytes =
                !value.getValue().isEmpty() && value.getValue().get(0) instanceof DynamicBytes;
        boolean arrayOfString =
                !value.getValue().isEmpty() && value.getValue().get(0) instanceof Utf8String;
        boolean arrayOfDynamicStructs =
                !value.getValue().isEmpty() && value.getValue().get(0) instanceof DynamicStruct;
        if (arrayOfBytes || arrayOfString) {
            long offset = 0;
            for (int i = 0; i < value.getValue().size(); i++) {
                if (i == 0) {
                    offset = value.getValue().size() * MAX_BYTE_LENGTH;
                } else {
                    int bytesLength =
                            arrayOfBytes
                                    ? ((byte[]) value.getValue().get(i - 1).getValue()).length
                                    : ((String) value.getValue().get(i - 1).getValue()).getBytes().length;
                    int numberOfWords = (bytesLength + MAX_BYTE_LENGTH - 1) / MAX_BYTE_LENGTH;
                    int totalBytesLength = numberOfWords * MAX_BYTE_LENGTH;
                    offset += totalBytesLength + MAX_BYTE_LENGTH;
                }
                result.append(
                        Numeric.toHexStringNoPrefix(
                                Numeric.toBytesPadded(
                                        new BigInteger(Long.toString(offset)), MAX_BYTE_LENGTH)));
            }
        } else if (arrayOfDynamicStructs) {
            result.append(encodeStructsArraysOffsets(value));
        }
        return result.toString();
    }

I want to help people in need!

harrylee2015 avatar Jul 06 '22 03:07 harrylee2015

You are right, thank you!

shehuan avatar Jun 07 '23 10:06 shehuan