I'm working on keeping track of data via a struct stored in a mapping.
mapping(uint256 => Session);
Here is the Session struct
:
struct Session {
// UID
uint256 id;
// Timestamp the sale starts
uint256 start;
// Timestamp the sale stops
uint256 stop;
// Last rate sync timestamp
uint256 sync;
// Current Rate
uint256 rate;
// Rate normalization: rate / 10**{decimal}
uint8 decimal;
// Current TOKEN|BNB Rate
uint256 issue;
// WEI raised
uint256 raised;
// Maximum sale quantity
uint256 max;
// Total tokens sold
uint256 sold;
// Total minutes before bnb rate update
uint256 threshold;
// Contract address of chainlink aggregator
address chainlink;
// Token Sale Owner
address owner;
// Token Contract
IBEP20 token;
}
What is the most efficient ways to modify a session?
Method 1:
/**
* @dev low level token purchase ***DO NOT OVERRIDE***
* @param _beneficiary Address performing the token purchase
*/
function buyTokens(uint256 _id, address _beneficiary) public payable open(_id) {
uint256 weiAmount = msg.value;
_preValidatePurchase(_beneficiary, weiAmount);
// calculate token amount to be created
uint256 tokens = _getTokenAmount(weiAmount);
// update state
sessions[_id].raised = sessions[_id].raised.add(weiAmount);
_processPurchase(_beneficiary, tokens);
emit TokenPurchase(
msg.sender,
_beneficiary,
weiAmount,
tokens
);
_forwardFunds();
_postValidatePurchase(_beneficiary, weiAmount);
}
Method 2:
/**
* @dev low level token purchase ***DO NOT OVERRIDE***
* @param _beneficiary Address performing the token purchase
*/
function buyTokens(uint256 _id, address _beneficiary) public payable open(_id) {
uint256 weiAmount = msg.value;
_preValidatePurchase(_beneficiary, weiAmount);
// calculate token amount to be created
uint256 tokens = _getTokenAmount(weiAmount);
// update state
Session storage sesh = sessions[_id];
sesh.raised = sesh.raised.add(weiAmount);
_processPurchase(_beneficiary, tokens);
emit TokenPurchase(
msg.sender,
_beneficiary,
weiAmount,
tokens
);
_forwardFunds();
_postValidatePurchase(_beneficiary, weiAmount);
}
For some reason in my head Method 2 is better, when I access a mapping does it have to search each time?
And the storage keyword, does that actually modify the object in storage within the mapping or am I just bonkers?
Best Answer
It is a bit hard to know in advance which method is optimal. In your scenario, gasEstimate states that the second method is less expensive.
To test your implementation I stripped everything from the contract except for the assign of the value (also I have a fake structure):
CONTRACT
creating a simple test with truffle allows us to have some information:
gasEstimate.js
the console output is
therefore the second method is less expensive