Skip to content

Commit cf833ba

Browse files
authored
Bug fix: Same inner struct name of different libraries result in failure in compilation for wrapper generated (#2060)
Signed-off-by: tonykwok1992 <[email protected]>
1 parent 7672ba2 commit cf833ba

File tree

10 files changed

+219
-8
lines changed

10 files changed

+219
-8
lines changed

codegen/src/main/java/org/web3j/codegen/SolidityFunctionWrapper.java

+26-8
Original file line numberDiff line numberDiff line change
@@ -457,20 +457,29 @@ private List<TypeSpec> buildStructTypes(final List<AbiDefinition> functionDefini
457457
final List<AbiDefinition.NamedType> orderedKeys = extractStructs(functionDefinitions);
458458
int structCounter = 0;
459459
final List<TypeSpec> structs = new ArrayList<>();
460+
final Map<String, Integer> structNamesCountPreview = new HashMap<>();
461+
462+
for (final AbiDefinition.NamedType namedType : orderedKeys) {
463+
final String internalType = namedType.getInternalType();
464+
if (internalType != null && !internalType.isEmpty()) {
465+
final String structName = getStructName(internalType);
466+
structNamesCountPreview.putIfAbsent(structName, 0);
467+
structNamesCountPreview.compute(structName, (s, count) -> count + 1);
468+
}
469+
}
470+
460471
for (final AbiDefinition.NamedType namedType : orderedKeys) {
461472
final String internalType = namedType.getInternalType();
462473
final String structName;
463474
if (internalType == null || internalType.isEmpty()) {
464475
structName = "Struct" + structCounter;
465476
} else {
466-
final String fullStructName =
467-
internalType.substring(internalType.lastIndexOf(" ") + 1);
468-
final String tempStructName =
469-
fullStructName.substring(fullStructName.lastIndexOf(".") + 1);
470-
structName =
471-
SourceVersion.isName(tempStructName)
472-
? tempStructName
473-
: "_" + tempStructName;
477+
String tempStructName = getStructName(internalType);
478+
if (structNamesCountPreview.getOrDefault(tempStructName, 0) > 1) {
479+
structName = getStructName(internalType.replace(".", "_"));
480+
} else {
481+
structName = tempStructName;
482+
}
474483
}
475484

476485
final TypeSpec.Builder builder =
@@ -574,6 +583,15 @@ private List<TypeSpec> buildStructTypes(final List<AbiDefinition> functionDefini
574583
return structs;
575584
}
576585

586+
@NotNull
587+
private static String getStructName(String internalType) {
588+
final String fullStructName = internalType.substring(internalType.lastIndexOf(" ") + 1);
589+
final String tempStructName = fullStructName.substring(fullStructName.lastIndexOf(".") + 1);
590+
final String structName =
591+
SourceVersion.isName(tempStructName) ? tempStructName : "_" + tempStructName;
592+
return structName;
593+
}
594+
577595
private String adjustToNativeTypeIfNecessary(NamedType component) {
578596
if (useNativeJavaTypes && structClassNameMap.get(component.structIdentifier()) == null) {
579597
if (ARRAY_SUFFIX.matcher(component.getType()).find()

codegen/src/test/java/org/web3j/codegen/SolidityFunctionWrapperGeneratorTest.java

+11
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,17 @@ public void testDeployMethodGenerated() throws Exception {
207207
compareJavaFile("MetaCoin", true);
208208
}
209209

210+
@Test
211+
public void testSameInnerStructName() throws Exception {
212+
testCodeGeneration("sameinnerstructname", "SameInnerStructName", JAVA_TYPES_ARG, false);
213+
testCodeGeneration("sameinnerstructname", "SameInnerStructName", SOLIDITY_TYPES_ARG, false);
214+
}
215+
216+
@Test
217+
public void testSameInnerStructNameCompareJavaFile() throws Exception {
218+
compareJavaFile("SameInnerStructName", true);
219+
}
220+
210221
private void compareJavaFile(String inputFileName, boolean useBin) throws Exception {
211222
String contract = inputFileName.toLowerCase();
212223
String packagePath =
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// SPDX-License-Identifier: UNLICENSED
2+
pragma solidity ^0.8.20;
3+
4+
library Foo {
5+
struct Info {
6+
bool dummy;
7+
}
8+
}
9+
10+
library Bar {
11+
struct Info {
12+
bool dummy;
13+
}
14+
}
15+
contract SameInnerStructName {
16+
17+
constructor() {
18+
19+
}
20+
function test(Foo.Info calldata foo, Bar.Info calldata bar) external {
21+
revert();
22+
}
23+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
[]
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
6055604b600b8282823980515f1a607314603f577f4e487b71000000000000000000000000000000000000000000000000000000005f525f60045260245ffd5b305f52607381538281f3fe730000000000000000000000000000000000000000301460806040525f80fdfea264697066735822122084a12bad14446abd271fd63e8490580f720401bd246b20d3c4c44a014f9b353064736f6c63430008140033
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
[]
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
6055604b600b8282823980515f1a607314603f577f4e487b71000000000000000000000000000000000000000000000000000000005f525f60045260245ffd5b305f52607381538281f3fe730000000000000000000000000000000000000000301460806040525f80fdfea264697066735822122050486bc1933b68f15a8374411ab7b0405b4f544c21aa8c14252f303a3b358ce464736f6c63430008140033
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"components":[{"internalType":"bool","name":"dummy","type":"bool"}],"internalType":"struct Foo.Info","name":"foo","type":"tuple"},{"components":[{"internalType":"bool","name":"dummy","type":"bool"}],"internalType":"struct Bar.Info","name":"bar","type":"tuple"}],"name":"test","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
608060405234801561000f575f80fd5b5060f18061001c5f395ff3fe6080604052348015600e575f80fd5b50600436106026575f3560e01c8063b1a29dbb14602a575b5f80fd5b60406004803603810190603c91906084565b6042565b005b5f80fd5b5f80fd5b5f80fd5b5f60208284031215606057605f604a565b5b81905092915050565b5f60208284031215607b57607a604a565b5b81905092915050565b5f806040838503121560975760966046565b5b5f60a285828601604e565b925050602060b1858286016069565b915050925092905056fea2646970667358221220024a769b6d57f11f6f5df0145ce9d31d8dd2ec08b9a923116f016e14a0912bb464736f6c63430008140033
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,153 @@
1+
package org.web3j.unittests.java;
2+
3+
import java.math.BigInteger;
4+
import java.util.Arrays;
5+
import java.util.Collections;
6+
import java.util.List;
7+
import org.web3j.abi.TypeReference;
8+
import org.web3j.abi.datatypes.Bool;
9+
import org.web3j.abi.datatypes.Function;
10+
import org.web3j.abi.datatypes.StaticStruct;
11+
import org.web3j.abi.datatypes.Type;
12+
import org.web3j.crypto.Credentials;
13+
import org.web3j.protocol.Web3j;
14+
import org.web3j.protocol.core.RemoteCall;
15+
import org.web3j.protocol.core.RemoteFunctionCall;
16+
import org.web3j.protocol.core.methods.response.TransactionReceipt;
17+
import org.web3j.tx.Contract;
18+
import org.web3j.tx.TransactionManager;
19+
import org.web3j.tx.gas.ContractGasProvider;
20+
21+
/**
22+
* <p>Auto generated code.
23+
* <p><strong>Do not modify!</strong>
24+
* <p>Please use the <a href="https://docs.web3j.io/command_line.html">web3j command line tools</a>,
25+
* or the org.web3j.codegen.SolidityFunctionWrapperGenerator in the
26+
* <a href="https://github.com/web3j/web3j/tree/main/codegen">codegen module</a> to update.
27+
*
28+
* <p>Generated with web3j version none.
29+
*/
30+
@SuppressWarnings("rawtypes")
31+
public class SameInnerStructName extends Contract {
32+
public static final String BINARY = "608060405234801561000f575f80fd5b5060f18061001c5f395ff3fe6080604052348015600e575f80fd5b50600436106026575f3560e01c8063b1a29dbb14602a575b5f80fd5b60406004803603810190603c91906084565b6042565b005b5f80fd5b5f80fd5b5f80fd5b5f60208284031215606057605f604a565b5b81905092915050565b5f60208284031215607b57607a604a565b5b81905092915050565b5f806040838503121560975760966046565b5b5f60a285828601604e565b925050602060b1858286016069565b915050925092905056fea2646970667358221220024a769b6d57f11f6f5df0145ce9d31d8dd2ec08b9a923116f016e14a0912bb464736f6c63430008140033";
33+
34+
private static String librariesLinkedBinary;
35+
36+
public static final String FUNC_TEST = "test";
37+
38+
@Deprecated
39+
protected SameInnerStructName(String contractAddress, Web3j web3j, Credentials credentials,
40+
BigInteger gasPrice, BigInteger gasLimit) {
41+
super(BINARY, contractAddress, web3j, credentials, gasPrice, gasLimit);
42+
}
43+
44+
protected SameInnerStructName(String contractAddress, Web3j web3j, Credentials credentials,
45+
ContractGasProvider contractGasProvider) {
46+
super(BINARY, contractAddress, web3j, credentials, contractGasProvider);
47+
}
48+
49+
@Deprecated
50+
protected SameInnerStructName(String contractAddress, Web3j web3j,
51+
TransactionManager transactionManager, BigInteger gasPrice, BigInteger gasLimit) {
52+
super(BINARY, contractAddress, web3j, transactionManager, gasPrice, gasLimit);
53+
}
54+
55+
protected SameInnerStructName(String contractAddress, Web3j web3j,
56+
TransactionManager transactionManager, ContractGasProvider contractGasProvider) {
57+
super(BINARY, contractAddress, web3j, transactionManager, contractGasProvider);
58+
}
59+
60+
public RemoteFunctionCall<TransactionReceipt> test(Foo_Info foo, Bar_Info bar) {
61+
final Function function = new Function(
62+
FUNC_TEST,
63+
Arrays.<Type>asList(foo,
64+
bar),
65+
Collections.<TypeReference<?>>emptyList());
66+
return executeRemoteCallTransaction(function);
67+
}
68+
69+
@Deprecated
70+
public static SameInnerStructName load(String contractAddress, Web3j web3j,
71+
Credentials credentials, BigInteger gasPrice, BigInteger gasLimit) {
72+
return new SameInnerStructName(contractAddress, web3j, credentials, gasPrice, gasLimit);
73+
}
74+
75+
@Deprecated
76+
public static SameInnerStructName load(String contractAddress, Web3j web3j,
77+
TransactionManager transactionManager, BigInteger gasPrice, BigInteger gasLimit) {
78+
return new SameInnerStructName(contractAddress, web3j, transactionManager, gasPrice, gasLimit);
79+
}
80+
81+
public static SameInnerStructName load(String contractAddress, Web3j web3j,
82+
Credentials credentials, ContractGasProvider contractGasProvider) {
83+
return new SameInnerStructName(contractAddress, web3j, credentials, contractGasProvider);
84+
}
85+
86+
public static SameInnerStructName load(String contractAddress, Web3j web3j,
87+
TransactionManager transactionManager, ContractGasProvider contractGasProvider) {
88+
return new SameInnerStructName(contractAddress, web3j, transactionManager, contractGasProvider);
89+
}
90+
91+
public static RemoteCall<SameInnerStructName> deploy(Web3j web3j, Credentials credentials,
92+
ContractGasProvider contractGasProvider) {
93+
return deployRemoteCall(SameInnerStructName.class, web3j, credentials, contractGasProvider, getDeploymentBinary(), "");
94+
}
95+
96+
public static RemoteCall<SameInnerStructName> deploy(Web3j web3j,
97+
TransactionManager transactionManager, ContractGasProvider contractGasProvider) {
98+
return deployRemoteCall(SameInnerStructName.class, web3j, transactionManager, contractGasProvider, getDeploymentBinary(), "");
99+
}
100+
101+
@Deprecated
102+
public static RemoteCall<SameInnerStructName> deploy(Web3j web3j, Credentials credentials,
103+
BigInteger gasPrice, BigInteger gasLimit) {
104+
return deployRemoteCall(SameInnerStructName.class, web3j, credentials, gasPrice, gasLimit, getDeploymentBinary(), "");
105+
}
106+
107+
@Deprecated
108+
public static RemoteCall<SameInnerStructName> deploy(Web3j web3j,
109+
TransactionManager transactionManager, BigInteger gasPrice, BigInteger gasLimit) {
110+
return deployRemoteCall(SameInnerStructName.class, web3j, transactionManager, gasPrice, gasLimit, getDeploymentBinary(), "");
111+
}
112+
113+
public static void linkLibraries(List<Contract.LinkReference> references) {
114+
librariesLinkedBinary = linkBinaryWithReferences(BINARY, references);
115+
}
116+
117+
private static String getDeploymentBinary() {
118+
if (librariesLinkedBinary != null) {
119+
return librariesLinkedBinary;
120+
} else {
121+
return BINARY;
122+
}
123+
}
124+
125+
public static class Foo_Info extends StaticStruct {
126+
public Boolean dummy;
127+
128+
public Foo_Info(Boolean dummy) {
129+
super(new org.web3j.abi.datatypes.Bool(dummy));
130+
this.dummy = dummy;
131+
}
132+
133+
public Foo_Info(Bool dummy) {
134+
super(dummy);
135+
this.dummy = dummy.getValue();
136+
}
137+
}
138+
139+
public static class Bar_Info extends StaticStruct {
140+
public Boolean dummy;
141+
142+
public Bar_Info(Boolean dummy) {
143+
super(new org.web3j.abi.datatypes.Bool(dummy));
144+
this.dummy = dummy;
145+
}
146+
147+
public Bar_Info(Bool dummy) {
148+
super(dummy);
149+
this.dummy = dummy.getValue();
150+
}
151+
}
152+
}
153+

0 commit comments

Comments
 (0)