Repository: LFDT-web3j/web3j (Java)

Issue:
Can not generate java class of static struct in some case.
The generated code does not contain the struct that is defined in static array

**Solidity**
```    
struct Player {
       address addr; 
       uint256 timeLeft; 
}
struct Config{ 
        uint64 index; 
        Player[2] players; 
    }
```
**Generated warpper**
```
public static class Config extends StaticStruct {
        public BigInteger index;
        public List<Player> players;
}
```
I can not find the Class of _Player_ . 
But it successfully generates when I modity the static array to dynamic, like this:
```
struct Config{ 
        uint64 index; 
        Player[] players; 
    }
```

- Is it unimplemented feature or bug? 
- Should I avoid to use struct in static array when i try to generate wrapper?

> web3j version: 4.11.1






Fix (patch):
diff --git a/codegen/src/main/java/org/web3j/codegen/SolidityFunctionWrapper.java b/codegen/src/main/java/org/web3j/codegen/SolidityFunctionWrapper.java
index b29dd6c18..0559fca03 100644
--- a/codegen/src/main/java/org/web3j/codegen/SolidityFunctionWrapper.java
+++ b/codegen/src/main/java/org/web3j/codegen/SolidityFunctionWrapper.java
@@ -129,7 +129,7 @@ public class SolidityFunctionWrapper extends Generator {
     private final boolean abiFuncs;
     private final int addressLength;
 
-    private final HashMap<Integer, ClassName> structClassNameMap = new HashMap<>();
+    private final HashMap<String, ClassName> structClassNameMap = new HashMap<>();
 
     private final List<NamedType> structsNamedTypeList = new ArrayList<>();
 
@@ -587,10 +587,6 @@ private List<TypeSpec> buildStructTypes(final List<AbiDefinition> functionDefini
     private static String getStructName(String internalType) {
         final String fullStructName = internalType.substring(internalType.lastIndexOf(" ") + 1);
         String tempStructName = fullStructName.substring(fullStructName.lastIndexOf(".") + 1);
-        int arrayPos = tempStructName.indexOf("[");
-        if (arrayPos > -1) {
-          tempStructName = tempStructName.substring(0, arrayPos);
-        }
         final String structName =
                 SourceVersion.isName(tempStructName) ? tempStructName : "_" + tempStructName;
         return structName;
@@ -611,6 +607,7 @@ private String adjustToNativeTypeIfNecessary(NamedType component) {
     }
 
     private NamedType normalizeNamedType(NamedType namedType) {
+        // dynamic array
         if (namedType.getType().endsWith("[]") && namedType.getInternalType().endsWith("[]")) {
             return new NamedType(
                     namedType.getName(),
@@ -620,6 +617,18 @@ private NamedType normalizeNamedType(NamedType namedType) {
                             .getInternalType()
                             .substring(0, namedType.getInternalType().length() - 2),
                     namedType.isIndexed());
+        } else if (namedType.getType().startsWith("tuple[")
+                && namedType.getInternalType().contains("[")
+                && namedType.getInternalType().endsWith("]")) { // static array
+
+            return new NamedType(
+                    namedType.getName(),
+                    namedType.getType().substring(0, namedType.getType().indexOf("[")),
+                    namedType.getComponents(),
+                    namedType
+                            .getInternalType()
+                            .substring(0, namedType.getInternalType().indexOf("[")),
+                    namedType.isIndexed());
         } else {
             return namedType;
         }
@@ -628,7 +637,7 @@ private NamedType normalizeNamedType(NamedType namedType) {
     @NotNull
     private List<AbiDefinition.NamedType> extractStructs(
             final List<AbiDefinition> functionDefinitions) {
-        final HashMap<Integer, AbiDefinition.NamedType> structMap = new LinkedHashMap<>();
+        final HashMap<String, AbiDefinition.NamedType> structMap = new LinkedHashMap<>();
         functionDefinitions.stream()
                 .flatMap(
                         definition -> {
@@ -637,7 +646,7 @@ private List<AbiDefinition.NamedType> extractStructs(
                             parameters.addAll(definition.getOutputs());
                             return parameters.stream()
                                     .map(this::normalizeNamedType)
-                                    .filter(namedType -> namedType.getType().startsWith("tuple"));
+                                    .filter(namedType -> namedType.getType().equals("tuple"));
                         })
                 .forEach(
                         namedType -> {
@@ -646,7 +655,7 @@ private List<AbiDefinition.NamedType> extractStructs(
                                     .map(this::normalizeNamedType)
                                     .filter(
                                             nestedNamedStruct ->
-                                                    nestedNamedStruct.getType().startsWith("tuple"))
+                                                    nestedNamedStruct.getType().equals("tuple"))
                                     .forEach(
                                             nestedNamedType ->
                                                     structMap.put(
@@ -2288,7 +2297,7 @@ public boolean isIndexed() {
             return namedType.isIndexed();
         }
 
-        public int structIdentifier() {
+        public String structIdentifier() {
             return namedType.structIdentifier();
         }
     }
diff --git a/core/src/main/java/org/web3j/protocol/core/methods/response/AbiDefinition.java b/core/src/main/java/org/web3j/protocol/core/methods/response/AbiDefinition.java
index d08b1ad8c..e13d61295 100644
--- a/core/src/main/java/org/web3j/protocol/core/methods/response/AbiDefinition.java
+++ b/core/src/main/java/org/web3j/protocol/core/methods/response/AbiDefinition.java
@@ -275,12 +275,11 @@ public void setComponents(final List<NamedType> components) {
             this.components = components;
         }
 
-        public int structIdentifier() {
+        public String structIdentifier() {
             return ((internalType == null ? type : internalType.isEmpty() ? type : internalType)
                             + components.stream()
-                                    .map(namedType -> String.valueOf(namedType.structIdentifier()))
-                                    .collect(Collectors.joining()))
-                    .hashCode();
+                                    .map(NamedType::structIdentifier)
+                                    .collect(Collectors.joining()));
         }
 
         public int nestedness() {