0
votes

I have the following solidity contract

  mapping (string => bool) private proofs;
  mapping (address => string[]) public owns;

  function registerAsset(string memory assetHash) public {
    proofs[assetHash] = true;
    owns[msg.sender].push(assetHash);
  }

  function checkIfRegistered(string memory assetHash) public view returns (bool) {
    return proofs[assetHash];
  }

  function getSize(address key) public view returns (uint){
    return owns[key].length;
  }

  function getAssets(address key) public view returns (string[] memory){
    return owns[key];
  }

After I call registerAsset through async/await as below

async function registerAsset(PoExContract, assetHash) {
  const result = PoExContract.deployed().then((poe) => {
    return poe.registerAsset(assetHash)
  })
  const transaction = (result !== null) ? result : null
  return transaction
}

export function register() {
  return async (dispatch, getState) => {
    const { poExContract } = getState().contract
    const { assetHash } = getState().asset
    const transaction = await registerAsset(poExContract, assetHash)
    if (transaction) {
      dispatchAssetCreated(transaction, assetHash, dispatch)
    } else {
      dispatchCreationError(dispatch)
    }
  }

and call the getAssets method,

async function getRegisteredAssets(PoExContract, account) {
  const regsiterdAssets = PoExContract.deployed().then((poe) => {
      return poe.getAssets(account)
  })
  return regsiterdAssets
}

export function getAssets(defaultAccount){
  return async(dispatch, getState) =>{
    const { poExContract } = getState().contract
    let registeredAssets = await getRegisteredAssets(poExContract,defaultAccount)
    console.log(registeredAssets)
    dispatchAssets(registeredAssets, dispatch)
  }

I get an array with empty String at the console.log(registeredAssets)

[" "]

Where as the truffle console like

truffle(development)> let instance = await PoExContract.deployed()
undefined
truffle(development)> let assets = await instance.getAssets('0x3E7Ff8055f225a019144365a3714c43c2a831e24')
undefined
truffle(development)> assets
[ 'fb90f1afe1de770fe175af0e27a1f85901f277005bfffb8ee502a7304e85b671' ]

I dont have any clue why the JS async/await returns array with empty string, where as the same method on truffle console returns correct result.

 [ 'fb90f1afe1de770fe175af0e27a1f85901f277005bfffb8ee502a7304e85b671' ]

When i did further investigation, I found that only the recently registered asset is not included in the getAssets list, but all the previous registrations returns properly.

1
Essentially, the instance.getAssets('address') returns fine from truffle console, where as the react async/await call returns an array with empty string. Any ideas please? - prabhakar

1 Answers

0
votes

Well, returning an Array of strings from Solidity contracts is still in its infancy when I used the encoder version 2

pragma experimental ABIEncoderV2;

So, I replaced my earlier solidity contract method

function getAssets(address key) public view returns (string[] memory assets){
    assets = new string[](owns[key].length);
    for (uint i=0; i<owns[key].length; i++){
      assets[i] = owns[key][i];      
    }
  }

with the following one as STEP-1

  function getAsset(address key, uint index) public view returns (string memory asset){
    asset = owns[key][index];
  }

and get each asset (as STEP-2) by

async function getRegisteredAsset(ProofOfExContract, account, index) {
  const poe = await ProofOfExContract.deployed()
  const registeredAsset = await poe.getAsset(account, index)
  return registeredAsset
}

and loop through the react async/await like the below as STEP-3

  for (var i=0;i<numberOfAssets;i++){
    const asset = await getRegisteredAsset(proofOfExContract, defaultAccount, i)
    dispatchAccountAsset(asset,dispatch)
  }

to get the actual expected result that is same as that of the Truffle console