Passing structs is a bad bad idea even between functions in the same contract. If you play around with structs a lot in your code, you may want to consider the effects of passing structs around and how you update them.
Contrary to what most people think, passing structs as variables affects your contract size limit as well, especially if you don't choose how you store and update the struct carefully. If your contracts are small you are unlikely to hit into this limit but on a big project, you will have a problem. How impactful? lets take a look.
Factors: my test contract where all this is happening is 18kb, just taking a snippet of code from it.
struct mysharesStruct {
uint256 amount;
uint256 amountETH;
uint256 matchedETH;
uint8 duration;
uint256 expiry;
address subscriber;
}
mysharesStruct sharefile;//assign struct to var (declaring var type at same time)
function createShareLease(uint256 tokens, uint256 ethRequired, uint8 lease_days) external {
sharefile = mysharesStruct(tokens, ethRequired, 0, lease_days, 0, msg.sender, 0);
}
Passing the struct to a variable as mysharesStruct sharefile;
takes up a small amount of memory.
Depending on your coding approach (as i have expanded this into a discussion on the impact of passing structs in the first place) the problem begins when then inside the function you want to use your struct, if you then assign values to your struct using the approach above:
sharefile = mysharesStruct(tokens, ethRequired, 0, lease_days, 0, msg.sender, 0);
you will notice that Remix compiler then shows a contract size limit warning! That's a huge jump in memory consumed. This is because the struct is stored in memory when its being assigned values.
Its the equivalent of this code:
mysharesStruct[] public sharefile;//assign struct to var (declaring var type at same time)
Used inside the functions as:
mysharesStruct memory structVar = mysharesStruct(tokens, ethRequired, 0, lease_days, 0, msg.sender, 0);
My recommendation to solidity developers working on big projects is to to not pass and update structs like above but instead, as below:
mapping(address => mysharesStruct) private _shareMapping;
struct mysharesStruct {
uint256 amount;
uint256 amountETH;
uint256 matchedETH;
uint8 duration;
uint256 expiry;
address subscriber;
}
Place the struct in a mapping and then inside our function we assign values to it as;
function createShareLease(uint256 tokens, uint256 ethRequired, uint8 lease_days) external {
_shareMapping[msg.sender].amount = tokens;
_shareMapping[msg.sender].amountETH = ethRequired;
_shareMapping[msg.sender].duration = lease_days;
_shareMapping[msg.sender].subscriber = msg.sender;
}
You will notice as soon as you use that approach, the contract limit warning disappears. The difference here is that we are not passing our struct as a variable, but instead are choosing to store it in a mapping and then access and update it directly from there.
This is well worth your consideration if you want to avoid hitting contract size limits easily when playing around with structs in your code.
QYuQianchen answer of passing variables is the smarter way overall, big picture considered.