web3j
web3j copied to clipboard
Does Web3.j support Solidity's ABIV2?
Many projects (including 0x) uses the somewhat new ABIV2 feature from Solidity. Does Web3.j already support contracts that use it?
For more information about ABIV2, grep for ABIEncoderV2 in the Solidity release notes or read Ethers.js's blog post about the feature.
https://github.com/esaulpaugh/headlong supports it. I would like to see headlong incorporated into web3j at some point. Currently web3j is developing its own implementation.
@esaulpaugh any idea if Web3.j's own implementation supports ABIV2?
Yes, I believe this is the work in progress https://github.com/web3j/web3j/tree/feature/653-solidity-structs
that work has gone stale - would be cool if someone can pick it up. I will probably get around to it someday but I have other priorities now.
bump
any news?
@hazae41 relevant: https://github.com/web3j/web3j/issues/832
Is there any plan to support struct arrays support as @RobertoArtiles mentioned on #1206 ? @iikirilov
Given the interest here, I'll see what we can do to make this happen.
Let me speak with the team.
Given the interest here, I'll see what we can do to make this happen.
Let me speak with the team.
Has any progress or decision been made on this? It looks like ABIv2 is now default with the release of Solidity v0.8.0.
PR #1321 has been created which adds structs array support - it would be great to get input from those on this thread to verify our test coverage is complete enough for their use case. Thanks to @SweeXordious for all the work here.
Fixed and merged 🎉 Now we have support for arrays of structs and multiple arrays of structs returns. Closing... Reopen if needed.
Hi mates
Thanks for this functionality. It has been very helpful for us, enabling to work on a more structured language way making smart contracts more efficient and readable.
Having said that... using the feature for a while we found a bug decoding strings inside anidated structs.
With the following Smart contract
pragma solidity ^0.7.5;
pragma experimental ABIEncoderV2;
contract Web3jTest {
struct Address {
string city;
string postalCode;
}
struct Structure {
uint256 id;
string description;
Address _address;
bytes notaryDocument;
}
Structure private structure;
function set(Structure memory _structure) external returns(bool) {
structure = _structure;
return true;
}
function get() external view returns(Structure memory structure_) {
structure_ = structure;
}
}
To test the SC we made this quick /dirty test
try {
Web3jTest web3jTest = Web3jTest.deploy(web3j, transactionManager, gasProvider).send();
web3jTest.set(new Web3jTest.Structure(BigInteger.ONE, "This is a description", new Web3jTest.Address("This a city", "This is a postal code"), "This is a notarized document".getBytes(StandardCharsets.UTF_8))).send();
Web3jTest.Structure structure = web3jTest.get().send();
log.debug("structure: ", structure.toString());
} catch (Exception e) {
e.printStackTrace();
}
Executing this code the error is the following
java.lang.StringIndexOutOfBoundsException: String index out of range: -234
at java.lang.String.substring(String.java:1967)
at org.web3j.abi.TypeDecoder.decodeDynamicParameterFromStruct(TypeDecoder.java:583)
at org.web3j.abi.TypeDecoder.decodeDynamicStructElements(TypeDecoder.java:546)
at org.web3j.abi.TypeDecoder.decodeDynamicStruct(TypeDecoder.java:472)
at org.web3j.abi.TypeDecoder.decodeDynamicParameterFromStruct(TypeDecoder.java:588)
at org.web3j.abi.TypeDecoder.decodeDynamicStructElements(TypeDecoder.java:546)
at org.web3j.abi.TypeDecoder.decodeDynamicStruct(TypeDecoder.java:472)
at org.web3j.abi.DefaultFunctionReturnDecoder.build(DefaultFunctionReturnDecoder.java:94)
at org.web3j.abi.DefaultFunctionReturnDecoder.decodeFunctionResult(DefaultFunctionReturnDecoder.java:52)
at org.web3j.abi.FunctionReturnDecoder.decode(FunctionReturnDecoder.java:49)
at org.web3j.tx.Contract.executeCall(Contract.java:322)
at org.web3j.tx.Contract.executeCallSingleValueReturn(Contract.java:328)
at org.web3j.tx.Contract.executeCallSingleValueReturn(Contract.java:339)
at org.web3j.tx.Contract.lambda$executeRemoteCallSingleValueReturn$1(Contract.java:428)
at org.web3j.protocol.core.RemoteCall.send(RemoteCall.java:42)
@Ferparishuertas Thank you for reporting this. I will try to reproduce it and come back to you.
@Ferparishuertas Sorry for the late answer. Please check the following PR https://github.com/web3j/web3j/pull/1383 I added the structs you had issue with as a test case and everything is green currently. Let me know if there are additional cases you are having issues with. Your input is valuable.
Thank you
@SweeXordious thank you so much for your help. We have found some cases with more complex structs that are still failing in your branch when decoding string fields. Here is the smart contract example:
pragma solidity ^0.7.5;
pragma experimental ABIEncoderV2;
contract Web3jTest {
struct Struct2 {
string string1;
uint256 uintField1;
uint256 uintField2;
uint256 uintField3;
string string2;
}
struct Struct1 {
uint256 uintField1;
uint256 uintField2;
}
struct MainStruct {
uint256 id;
string name;
Struct1 struct1;
Struct2 struct2;
}
MainStruct private structure;
function set(MainStruct memory _structure) external returns(bool) {
structure = _structure;
return true;
}
function get() external view returns(MainStruct memory structure_) {
structure_ = structure;
}
}
when trying this
Web3jTest web3jTest = Web3jTest.deploy(web3j, transactionManager, gasProvider).send();
web3jTest.set(new Web3jTest.MainStruct(
BigInteger.ONE,
"test name",
new Web3jTest.Struct1(BigInteger.TEN, BigInteger.ZERO),
new Web3jTest.Struct2(
"test string 1",
BigInteger.ONE,
BigInteger.ZERO,
BigInteger.TEN,
"test string 2"
)
)).send();
Web3jTest.MainStruct mainStruct = web3jTest.get().send();
we get this error, always with index 64:
java.lang.StringIndexOutOfBoundsException: String index out of range: 64
at java.lang.String.substring(String.java:1963)
at org.web3j.abi.TypeDecoder.decodeUintAsInt(TypeDecoder.java:275)
at org.web3j.abi.TypeDecoder.decodeDynamicBytes(TypeDecoder.java:312)
at org.web3j.abi.TypeDecoder.decodeUtf8String(TypeDecoder.java:324)
at org.web3j.abi.TypeDecoder.decode(TypeDecoder.java:112)
at org.web3j.abi.TypeDecoder.decode(TypeDecoder.java:122)
at org.web3j.abi.TypeDecoder.decodeDynamicParameterFromStruct(TypeDecoder.java:597)
at org.web3j.abi.TypeDecoder.decodeDynamicStructElements(TypeDecoder.java:545)
at org.web3j.abi.TypeDecoder.decodeDynamicStruct(TypeDecoder.java:471)
at org.web3j.abi.DefaultFunctionReturnDecoder.build(DefaultFunctionReturnDecoder.java:94)
at org.web3j.abi.DefaultFunctionReturnDecoder.decodeFunctionResult(DefaultFunctionReturnDecoder.java:52)
at org.web3j.abi.FunctionReturnDecoder.decode(FunctionReturnDecoder.java:49)
at org.web3j.tx.Contract.executeCall(Contract.java:295)
at org.web3j.tx.Contract.executeCallSingleValueReturn(Contract.java:301)
at org.web3j.tx.Contract.executeCallSingleValueReturn(Contract.java:312)
at org.web3j.tx.Contract.lambda$executeRemoteCallSingleValueReturn$1(Contract.java:400)
at org.web3j.protocol.core.RemoteCall.send(RemoteCall.java:42)
thanks in advance
@lfrKain Thank you so much for letting me know. Will try to work on a more global fix for this.
@SweeXordious would be very nice to get a more pluggable solution. I am using maven plugin and had to compile a web3j from scratch and the maven plugin due to not distributed on maven repositories and a chain of dependencies.
Didnt find any doc howto handle codegen / solc config independently.
** Structs are not working anymore for me **
pragma solidity >=0.7.0;
pragma experimental ABIEncoderV2;
interface SomeInterface {
struct SomeStruct {
address addressA;
address addressB;
}
function someFunction(SomeStruct calldata params) external payable returns (uint256 result);
}
is not working - i get the tuple error mentioned in #1361
@BarBozz I am able to compile the interface that you provided no problem.
Can you please let us know which versions are you using ?
I am using latest web3j
version 4.8.4
via the web3j-gradle-plugin:4.8.4
Yes, I believe this is the work in progress https://github.com/web3j/web3j/tree/feature/653-solidity-structs
But how to package and install it? I see that the source code is provided on Git, there is no corresponding installation package