简体   繁体   中英

how to reference Web3j array type in java or kotlin

Error section -

how do I reference array types from the web3j library? I have a contract function which returns an array of addresses of whoever accessed the contract. I want to get these as arrays into a java/kotlin project. here's the code -

//gets an array of addresses from the contract
fun getAddressValues(): RemoteCall<Array<Address>> {
    val function = Function(
        functionGetAddressValues,
        listOf(),
        listOf<TypeReference<*>>(object : TypeReference<Array<Address>>() {})
    )
    // TODO: NOTE - THIS ARRAY IS FROM THE WEB3J LIBRARY "org.web3j.abi.datatypes.Array"
    return executeRemoteCallSingleValueReturn(function, Array<Address>().javaClass) // TODO: error
}

I just want to get the class type for the array so that I can pass it on to this function -

executeRemoteCallSingleValueReturn(function, Array<Address>().javaClass) // TODO: error

And the error is on -

Array<Address>().javaClass

here's the contract code if you want a look -

// SPDX-License-Identifier: GPL-3.0

pragma solidity >=0.7.0 <0.9.0;

contract VotingContract {
    address[] addressStorage;

    uint256 partyOneVotes;
    uint256 partyTwoVotes;
    uint256 partyThreeVotes;

    constructor() {
        partyOneVotes = 0;
        partyTwoVotes = 0;
        partyThreeVotes = 0;
    }

    function registerVote(uint256 num) public {
        require(
            num < 4 && num > 0,
            "the given number is invalid as the number is out of range"
        );
        bool a = false;
        address messageSender = msg.sender;
        uint256 i;
        for (i = 0; i < addressStorage.length; i++) {
            if (messageSender == addressStorage[i]) {
                a = false;
                //set to true to block multiple entries.
            }
        }
        require(a == false, "Your vote has already been registered");
        addressStorage.push(messageSender);
        if (num == 1) {
            partyOneVotes++;
        } else if (num == 2) {
            partyTwoVotes++;
        } else {
            partyThreeVotes++;
        }
    }

    function getAddressValues() public view returns (address[] memory) {
        return addressStorage;
    }

    function getPartyOneVotes() public view returns (uint256) {
        return partyOneVotes;
    }

    function getPartyTwoVotes() public view returns (uint256) {
        return partyTwoVotes;
    }

    function getPartyThreeVotes() public view returns (uint256) {
        return partyThreeVotes;
    }
}

This is the contract function I am talking about -

function getAddressValues() public view returns (address[] memory) {
    return addressStorage;
}

Any form of help is appriciated...

Maybe you are using the wrong type for you array. I use DynamicArray instead of Array.

This peace of code call a function with an address in parameter and return an DynamicArray. The values of the DynamicArray are displayed on the console :

val function = org.web3j.abi.datatypes.Function("getTokensFromOwner",
                                                       inputParameters, 
                                                       Arrays.asList<TypeReference<*>>(object: TypeReference<org.web3j.abi.datatypes.DynamicArray<Uint256>>() {}))
        
val encodedFunction = FunctionEncoder.encode(function)
val transaction = Transaction.createEthCallTransaction("0xD8e5D841C0db4c4b95fa9fCEc48936F51Aeeaed8", "0x6Ac98A430D17ef564091bA470785f1389d0b9371", encodedFunction)
val response: EthCall = web3j.ethCall(transaction, DefaultBlockParameter.valueOf("latest")).sendAsync().get()  // get the result of the smartcontract
val value = response.value
        
val someTypes = FunctionReturnDecoder.decode(value, function.outputParameters)
        
var tokens: DynamicArray<Uint256> = DynamicArray((someTypes.get(0).value as ArrayList<Uint256>).toList())
        
for (token: Uint256 in tokens.value)
{
    Log.v("token ", token.value.toString())
}

smart contract function :

function getTokensFromOwner(address owner) external view returns (uint256[] memory)
{
    uint256 nbTokens = balanceOf(owner);
    uint256[] memory tokensId = new uint256[](nbTokens);
    for (uint256 i=0; i< nbTokens;i++)
    {
      tokensId[i] = (tokenOfOwnerByIndex(owner, i));
    }
    
    return tokensId;
}

I hope that example will help you :)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM