Storage

使用返回的變數(Array.push)修改狀態

  • October 9, 2019

在我的聯繫人中,我希望在一個地方找到現有對象(結構),然後在多個地方使用它來讀取和修改它 - 但似乎不可能?

contract A
{
   struct Prop
   {
   }

   struct App
   {
       Prop[] props;
   }

   App[] apps;

   function AddProp(string memory name) public
   {
       App memory a = FindApp(name);

       if(bytes(a.name).length > 0)
           a.props.push(Prop()); // TypeError: Data location must be "memory" for return parameter in function, but "storage" was given.

       else
           revert('Application not found');        
   }

   function FindApp(string memory name) public returns (App memory) // can't return 'storage'
   {
       for(uint256 i = 0; i < apps.length; i++)
       {
           if(apps[i].name == name)
           {
               return apps[i];
           }
       }

       return App();
   }

}

我必須更改很多東西才能編譯此程式碼,但是您缺少的重要部分是公共函式不能返回儲存引用(因為外部呼叫者對此無能為力),而是內部(或private) 函式可以:

pragma solidity 0.5.11;

contract A
{
   struct Prop
   {
       uint256 foo; // empty structs are not allowed
   }

   struct App
   {
       string name; // added this because it was used elsewhere
       Prop[] props;
   }

   App[] apps;

   function AddProp(string memory name) public
   {
       App storage a = FindApp(name); // storage

       if(bytes(a.name).length > 0)
           a.props.push(Prop(0));
       else
           revert('Application not found');        
   }

   function FindApp(string memory name) internal view returns (App storage) // storage
   {
       bytes32 hash = keccak256(abi.encodePacked(name));
       for(uint256 i = 0; i < apps.length; i++)
       {
           // string equality is not defined, have to compare hashes
           if (keccak256(abi.encodePacked(apps[i].name)) == hash)
           {
               return apps[i];
           }
       }

       revert("Not found."); // Wasn't sure what to do here... you can't just return a new App because you need to return something from storage
   }
}

引用自:https://ethereum.stackexchange.com/questions/76565