When trying to create a contract wrapper with web3j generate solidity generate --abiFile=myJson.json --outputDir=src/java/ --package=my.package, i run into this error:
Unsupported type encountered: tuple
What is the status regarding this, is supporting tuples on the roadmap?
...
{"constant":false,"inputs":[{"components":[{"internalType":"address","name":"makerAddress","type":"address"},{"internalType":"address","name":"takerAddress","type":"address"},{"internalType":"address","name":"feeRecipientAddress","type":"address"},{"internalType":"address","name":"senderAddress","type":"address"},{"internalType":"uint256","name":"makerAssetAmount","type":"uint256"},{"internalType":"uint256","name":"takerAssetAmount","type":"uint256"},{"internalType":"uint256","name":"makerFee","type":"uint256"},{"internalType":"uint256","name":"takerFee","type":"uint256"},{"internalType":"uint256","name":"expirationTimeSeconds","type":"uint256"},{"internalType":"uint256","name":"salt","type":"uint256"},{"internalType":"bytes","name":"makerAssetData","type":"bytes"},{"internalType":"bytes","name":"takerAssetData","type":"bytes"},{"internalType":"bytes","name":"makerFeeAssetData","type":"bytes"},{"internalType":"bytes","name":"takerFeeAssetData","type":"bytes"}],"internalType":"struct LibOrder.Order[]","name":"orders","type":"tuple[]"}],"name":"batchCancelOrders","outputs":[],"payable":true,"stateMutability":"payable","type":"function"}
...
I also have this problem. How can I solve it?
Same here. I read that it was fixed and merged in new versions but even if I'm using v4.8.4 of web3j, it still doesn't support tuples. I don't think that's the case but for your information, I'm trying to generate wrappers via Gradle and my development environment is on WSL. How can we solve this problem?
I tried to simplify the contract I wrote here:
pragma solidity >=0.6.0;
pragma experimental ABIEncoderV2;
import "@openzeppelin/contracts/math/SafeMath.sol";
contract Wallet {
using SafeMath for uint;
struct Consumer {
string id;
Item[] itemStructs;
}
struct Item {
string itemId;
uint quantity;
}
mapping (address => Consumer) public consumers;
mapping (address => mapping(string => bool)) public containsItem;
function addItemToWallet(address _address, Item memory _item) public {
Consumer storage consumer = consumers[_address];
bool isAdded = false;
for (uint i = 0; i<consumer.itemStructs.length; i++) {
if (keccak256(bytes(consumer.itemStructs[i].itemId)) == keccak256(bytes(_item.itemId))) {
require(containsItem[_address][_item.itemId] = true);
consumer.itemStructs[i].quantity = consumer.itemStructs[i].quantity.add(_item.quantity);
isAdded = true;
}
}
if (isAdded == false) {
consumer.itemStructs.push(_item);
containsItem[_address][_item.itemId] = true;
}
}
}
It also gives this error when I run ./gradlew generateContractWrappers:
Starting a Gradle Daemon (subsequent builds will be faster)
> Task :compileSolidity
Compiler run successful. Artifact(s) can be found in directory build/resources/main/solidity.
The message received from the daemon indicates that the daemon has disappeared.
Build request sent: Build{id=7484af22-3964-481c-874c-272d0ec2aabb, currentDir=/home/kay/ethereum-projects/loyalty-solidity-smart-contracts}
Attempting to read last messages from the daemon log...
Daemon pid: 19295
log file: /home/kay/.gradle/daemon/6.8.2/daemon-19295.out.log
----- Last 20 lines from daemon log file - daemon-19295.out.log -----
2021-02-19T16:01:08.687+0300 [DEBUG] [org.gradle.launcher.daemon.server.DefaultIncomingConnectionHandler] Starting executing command: Build{id=7484af22-3964-481c-874c-272d0ec2aabb, currentDir=/home/kay/ethereum-projects/loyalty-solidity-smart-contracts} with connection: socket connection from /127.0.0.1:41293 to /127.0.0.1:56444.
2021-02-19T16:01:08.691+0300 [ERROR] [org.gradle.launcher.daemon.server.DaemonStateCoordinator] Command execution: started DaemonCommandExecution[command = Build{id=7484af22-3964-481c-874c-272d0ec2aabb, currentDir=/home/kay/ethereum-projects/loyalty-solidity-smart-contracts}, connection = DefaultDaemonConnection: socket connection from /127.0.0.1:41293 to /127.0.0.1:56444] after 0.0 minutes of idle
2021-02-19T16:01:08.691+0300 [INFO] [org.gradle.launcher.daemon.server.DaemonRegistryUpdater] Marking the daemon as busy, address: [3311916f-d332-4e8d-8b27-bbbb224fb970 port:41293, addresses:[localhost/127.0.0.1]]
2021-02-19T16:01:08.692+0300 [DEBUG] [org.gradle.launcher.daemon.registry.PersistentDaemonRegistry] Marking busy by address: [3311916f-d332-4e8d-8b27-bbbb224fb970 port:41293, addresses:[localhost/127.0.0.1]]
2021-02-19T16:01:08.696+0300 [DEBUG] [org.gradle.cache.internal.DefaultFileLockManager] Waiting to acquire exclusive lock on daemon addresses registry.
2021-02-19T16:01:08.700+0300 [DEBUG] [org.gradle.cache.internal.DefaultFileLockManager] Lock acquired on daemon addresses registry.
2021-02-19T16:01:08.701+0300 [DEBUG] [org.gradle.cache.internal.DefaultFileLockManager] Releasing lock on daemon addresses registry.
2021-02-19T16:01:08.702+0300 [DEBUG] [org.gradle.launcher.daemon.server.DaemonStateCoordinator] resetting idle timer
2021-02-19T16:01:08.702+0300 [DEBUG] [org.gradle.launcher.daemon.server.DaemonStateCoordinator] daemon is running. Sleeping until state changes.
2021-02-19T16:01:08.704+0300 [INFO] [org.gradle.launcher.daemon.server.exec.StartBuildOrRespondWithBusy] Daemon is about to start building Build{id=7484af22-3964-481c-874c-272d0ec2aabb, currentDir=/home/kay/ethereum-projects/loyalty-solidity-smart-contracts}. Dispatching build started information...
2021-02-19T16:01:08.705+0300 [DEBUG] [org.gradle.launcher.daemon.server.SynchronizedDispatchConnection] thread 19: dispatching org.gradle.launcher.daemon.protocol.BuildStarted@1870be57
2021-02-19T16:01:08.708+0300 [DEBUG] [org.gradle.launcher.daemon.server.exec.EstablishBuildEnvironment] Configuring env variables: [PATH, LESSCLOSE, BROWSER, XDG_DATA_DIRS, TERM, LANG, VSCODE_GIT_IPC_HANDLE, PIPE_LOGGING, VSCODE_GIT_ASKPASS_MAIN, NVM_INC, COLORTERM, VSCODE_IPC_HOOK_CLI, LOGNAME, VSCODE_GIT_ASKPASS_NODE, PWD, TERM_PROGRAM_VERSION, GIT_ASKPASS, USES_VSCODE_SERVER_SPAWN, AMD_ENTRYPOINT, _, NVM_CD_FLAGS, SHELL, NVM_DIR, LESSOPEN, WSL_INTEROP, WSL_DISTRO_NAME, TERM_PROGRAM, HOSTTYPE, GOPATH, OLDPWD, USER, GOROOT, NAME, WSLENV, VERBOSE_LOGGING, LS_COLORS, NVM_BIN, HOME, SHLVL]
2021-02-19T16:01:08.719+0300 [DEBUG] [org.gradle.launcher.daemon.server.exec.LogToClient] About to start relaying all logs to the client via the connection.
2021-02-19T16:01:08.719+0300 [INFO] [org.gradle.launcher.daemon.server.exec.LogToClient] The client will now receive all logging from the daemon (pid: 19295). The daemon log file: /home/kay/.gradle/daemon/6.8.2/daemon-19295.out.log
2021-02-19T16:01:08.721+0300 [INFO] [org.gradle.launcher.daemon.server.exec.LogAndCheckHealth] Starting build in new daemon [memory: 512 MiB]
2021-02-19T16:01:08.734+0300 [DEBUG] [org.gradle.launcher.daemon.server.exec.ExecuteBuild] The daemon has started executing the build.
2021-02-19T16:01:08.734+0300 [DEBUG] [org.gradle.launcher.daemon.server.exec.ExecuteBuild] Executing build with daemon context: DefaultDaemonContext[uid=5dacd15e-f5c8-45a5-a2ea-e83282cbe123,javaHome=/usr/lib/jvm/java-11-openjdk-amd64,daemonRegistryDir=/home/kay/.gradle/daemon,pid=19295,idleTimeout=10800000,priority=NORMAL,daemonOpts=--add-opens,java.base/java.util=ALL-UNNAMED,--add-opens,java.base/java.lang=ALL-UNNAMED,--add-opens,java.base/java.lang.invoke=ALL-UNNAMED,--add-opens,java.prefs/java.util.prefs=ALL-UNNAMED,-XX:MaxMetaspaceSize=256m,-XX:+HeapDumpOnOutOfMemoryError,-Xms256m,-Xmx512m,-Dfile.encoding=UTF-8,-Duser.country,-Duser.language=en,-Duser.variant]
Compiler run successful. Artifact(s) can be found in directory build/resources/main/solidity.
Unsupported type encountered: tuple
Daemon vm is shutting down... The daemon has exited normally or was terminated in response to a user interrupt.
----- End of the daemon log -----
FAILURE: Build failed with an exception.
* What went wrong:
Gradle build daemon disappeared unexpectedly (it may have been killed or may have crashed)
* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.
* Get more help at https://help.gradle.org
> Task :generateContractWrappers
Unsupported type encountered: tuple
Hope you guys can help us with it, thanks in advance!
@kalekale hi, from the commands you used to generate the wrappers I can see you are using an older version of the CLI. I would recommend you delete the .web3j directory and download web3j once more the new command is web3j generate solidity .....
@kerimay hi, I used the contract that you provided and I was able to generate the wrappers fine I will dig deeper into the Gradle logs you provided to check what exactly the issue might be.
@kalekale hi, from the commands you used to generate the wrappers I can see you are using an older version of the CLI. I would recommend you delete the
.web3j directory and download web3j once more the new command isweb3j generate solidity .....@kerimay hi, I used the contract that you provided and I was able to generate the wrappers fine I will dig deeper into the Gradle logs you provided to check what exactly the issue might be.
I figured out that my general Gradle version on WSL wasn't updated and also, I had a special case with my contract. Except the method I provided here, I also had a function like this:
function getConsumerData(address _address) public view returns (Consumer memory) {
return consumers[_address];
}
It was working on Remix IDE but maybe it was a bad practice I don't know, this caused the main issue on my case. Other functions with tuples worked well. Thank you for your attention @AlexandrouR
@kerimay I do get the same issue when I try to generate the wrappers after adding the function, however, I can't compile this in Remix as I get this Invalid input source specified.
Interesting, because I can compile and deploy it in Remix with no issue. Is it maybe because of compiler version? Mine was 0.7.4
Just encountered the same problem while trying to build a wrapper.
Here is minimal example in solidity that fails.
pragma solidity ^0.6.0;
pragma experimental ABIEncoderV2;
contract Hello {
struct Input {
FooInput[] some;
}
struct FooInput {
address someAddr;
BarInput[] barInputs;
}
struct BarInput {
uint8 xyz;
}
function foo(Input memory output) public pure returns (bool){
return true;
}
}
Then I used solcjs and web3j to build a wrapper:
$ solcjs -V
0.6.0+commit.26b70077.Emscripten.clang
$ web3j -v
...
by Web3Labs
Version: 1.4.1
Build timestamp: 2021-02-16 20:28:33.742 UTC
$ solcjs --bin --abi --optimize hello.sol -o bb
hello.sol:19:14: Warning: Unused function parameter. Remove or comment out the variable name to silence this warning.
function foo(Input memory output) public pure returns (bool){
^-----------------^
$ web3j generate solidity --abiFile=bb/hello_sol_Hello.abi -o java -p foo.bar
by Web3Labs
Generating foo.bar.Hello_sol_Hello ... Unsupported type encountered: tuple
Please advise how to tackle this problem?
Have the same problem:
solc 0.8.2, web3j-cli 1.4.1
// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.8.2;
contract Multicall {
struct Call {
address target;
bytes callData;
}
function aggregate(Call[] memory calls) public returns (uint256 blockNumber, bytes[] memory returnData) {
blockNumber = block.number;
returnData = new bytes[](calls.length);
for(uint256 i = 0; i < calls.length; i++) {
(bool success, bytes memory ret) = calls[i].target.call(calls[i].callData);
require(success);
returnData[i] = ret;
}
}
}
$ solcjs Multicall.sol --optimize --bin --abi -o ./
$ web3j solidity generate -b Multicall_sol_Multicall.bin -a Multicall_sol_Multicall.abi -p cc -o ./
..
Generating cc.Multicall_sol_Multicall ... Unsupported type encountered: tuple
Most helpful comment
I also have this problem. How can I solve it?