Storage
使用返回的變數(Array.push)修改狀態
在我的聯繫人中,我希望在一個地方找到現有對象(結構),然後在多個地方使用它來讀取和修改它 - 但似乎不可能?
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 } }