5

I have a struct Question in my smart contract. After generating the java wrapper class of my smart contract using web3j, Inside the wrapper class Question is not recognized, looks like web3j is not generating struct code in the wrapper class.

In short, web3j does generate a java wrapper class but forgets to handle the struct.

pragma solidity ^0.8.16;


contract Quiz{

struct Question{
    string statement;
     string[4] options;
    uint correctIndex;
}

    Question[] questions;


    constructor() payable{
        addQuestions();
    }


    function addQuestions()public payable{
         questions.push(Question("Who is the CEO of Pakistan?", ["Shehbaz Sharif","Gen. Bajwa","Imran Khan","Zardari"], 1));
         questions.push(Question("Capital of Pakistan?", ["Lahore","Quetta","Karachi","Islamabad"], 3));
         questions.push(Question("When android acquried firebase offically?", ["2011","2014","2013","2015"], 1));
         questions.push(Question("Advantages of decentralized App?", ["Speed, efficiency and accuracy","Trust and transparency","Savings","All of these"], 3));
         questions.push(Question("What are the application of smart contracts?", ["retailer-supplier","Trade Efficency","Trust","All of these"], 3));
    }

    function getQuestions()public view returns(Question[] memory){
        Question[] memory questionList = new Question[](5);
        for (uint i = 0; i < 5; i++) {
          Question storage question = questions[i];
          questionList[i] = question;
        }
        return questionList;
    }

    

    function checkQuestion(uint qIndex, uint choosedAnsIndex)public view returns(bool){
        Question memory question = questions[qIndex];

        if(question.correctIndex == choosedAnsIndex){
            return true;
        }

        return false;
    }



}

Here's the generated java wrapper class Quiz_sol_Quiz.java.

Any help would be highly appreciated.

9
  • is it solved ???
    – 0xAnon
    Commented Aug 30, 2022 at 12:14
  • 1
    By the way this is the easy case :/ giving an array of Questions as parameter is the hard one
    – Majd TL
    Commented Aug 30, 2022 at 13:15
  • First of all don't store strings at all on your solidity smart contract. The gas usage will be huge. Store all the content on IPFS and just store the hash on the smart contract. Commented Sep 3, 2022 at 8:41
  • For getQuestions you can just return questions without for loops or making a new array.
    – Ryan Sea
    Commented Sep 3, 2022 at 18:52
  • Can you post the error that you get when you try the code? Also maybe define the question more clearly? Commented Sep 4, 2022 at 15:01

1 Answer 1

0

Web3j offers parent classes to implement struct on Java: StaticStruct and DynamicStruct. Below is an example of my struct and its implementation on Java.

struct Value {
    string _offer;
    uint256 _availableSince;
    uint256 _availabilityEnd;
    bool _isConsumed;
    uint256 _lockedUntil;
}

class Value: DynamicStruct {

    private lateinit var offer: String
    private lateinit var availableSince: BigInteger
    private lateinit var availabilityEnd: BigInteger
    private var isConsumed: Boolean = false
    private lateinit var lockedUntil: BigInteger

    constructor(
        offer: String,
        availableSince: BigInteger,
        availabilityEnd: BigInteger,
        isConsumed: Boolean,
        lockedUntil: BigInteger
    ) : super(
        Utf8String(offer), Uint256(availableSince),
        Uint256(availabilityEnd), Bool(isConsumed),
        Uint256(lockedUntil)
    ) {
        this.offer = offer
        this.availableSince = availableSince
        this.availabilityEnd = availabilityEnd
        this.isConsumed = isConsumed
        this.lockedUntil = lockedUntil
    }

    constructor(
        offer: Utf8String,
        availableSince: Uint256,
        availabilityEnd: Uint256,
        isConsumed: Bool,
        lockedUntil: Uint256
    ) : super(offer, availableSince, availabilityEnd, isConsumed, lockedUntil) {
        this.offer = offer.value
        this.availableSince = availableSince.value
        this.availabilityEnd = availabilityEnd.value
        this.isConsumed = isConsumed.value
        this.lockedUntil = lockedUntil.value
    }

}
7
  • 1
    Yeah thanks for your answer but my case is different. I've an array inside my struct and then that struct is itself any array. how would you deal with it? Commented Oct 5, 2022 at 7:42
  • The Problem is with Dynamic arrays of type Struct. Web3j has a bug and it doesn't generate the Struct correctly. The only possible way is a workaround without changing the contract. Commented Oct 5, 2022 at 7:43
  • Kindly try generating java code of the contract code I provided in the question, then you will realize the real problem, ig. Commented Oct 5, 2022 at 7:47
  • Solidity support arrays. When you define a Function you have to define an a TypeReference which also supports StaticArray and DynamicArray. Here is a code sample stackoverflow.com/questions/47601052/…
    – Gleichmut
    Commented Oct 5, 2022 at 7:49
  • that answer might be applicable in previous versions of web3j where we directly interact with abi files but now web3j has been much improved that we create java file to interact. So how can i do that in java file? Commented Oct 5, 2022 at 10:58

Not the answer you're looking for? Browse other questions tagged or ask your own question.