松露控制台命令的结果与react redux async / await实体合同方法不同

时间:2019-04-20 10:18:16

标签: reactjs react-redux solidity truffle

我有以下固定合同

  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];
  }

按如下所示通过async / await调用registerAsset后

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)
    }
  }

并调用getAssets方法,

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)
  }

我在console.log(registeredAssets)处得到一个带有空字符串的数组

[" "]

像松露控制台一样

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

我不知道为什么JS async / await返回带有空字符串的数组,而与松露控制台上的相同方法返回正确的结果一样。

 [ 'fb90f1afe1de770fe175af0e27a1f85901f277005bfffb8ee502a7304e85b671' ]

当我做进一步调查时,我发现getAssets列表中仅不包括最近注册的资产,而所有先前的注册均正确返回。

1 个答案:

答案 0 :(得分:0)

好吧,当我使用编码器版本2时,从Solidity合同返回字符串数组仍处于起步阶段

pragma experimental ABIEncoderV2;

因此,我替换了以前的固定合同方法

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];      
    }
  }

,以下是STEP-1

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

并通过以下方式获取每项资产(作为STEP-2)

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

并像下面的STEP-3一样循环遍历react async / await

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

获得与Truffle控制台相同的实际预期结果