Solidity – Understanding the Differences Between Memory and Storage

solidity

I'm very new to Solidity and running into this issue.

enter image description here

As you can see in this picture, I'm trying to set up a scenario where there exists 1 state variable called text. Then, I want to run a transaction that calls doStuff. doStuff creates a copy of text and stores it in testString. I then want to modify this testString in another function, so I indicate a "pass by reference" using the storage keyword next to the parameter called _text.

Obviously this doesn't work because I'm getting an error that I can't implicitly cast a string memory to a string storage. So my question is: how do I create a copy (by using memory), and then pass that copy by reference to be modified (using storage)? What is the best practice/workaround here? Any comments about how to properly use memory vs storage would also be greatly appreciated.

Here is the code:

// SPDX-License-Identifier: GPL-3.0

pragma solidity >=0.7.0 <0.9.0;

contract Jacob {
    string text;
    
    function doStuff() public view returns (string memory) {
        string memory testString = text;
        
        updateTestString(testString);
    
        return (testString);
    }
    
    function updateTestString(string storage _text) private view {
        _text = "Hello, World!";
    }
}

Best Answer

I think this is what you want.

I took the liberty of tidying up and making it closer to best practice. "Do Stuff" can't be view or pure because deep down you want to update the state. You can assign a memory variable to storage but you can't convert the way you were trying to do it. The public function makes the state variable readable.

// SPDX-License-Identifier: GPL-3.0

pragma solidity 0.8.7;

contract Jacob {
    
    string public text; // makes it readable
    
    event Updated(address sender, string text);
    
    function doStuff(string memory _text) public returns (string memory) {
        updateTestString(_text);
        return text;
    }
    
    function updateTestString(string memory _text) private {
        text = _text;
        emit Updated(msg.sender, _text); // best practice, because the state has changed
    }
}

Hope it helps.

Related Topic