Suppose that I've the following contract code:
pragma solidity ^0.4.23;
contract pensCollection{
struct Pen{
uint productCode;
address ownerAddress;
}
address public owner;
// history of a pen.
mapping(uint => address[]) public __history;
// One account can hold many pens.
mapping(address => Pen[]) public __inventary;
constructor () public{
owner = msg.sender;
}
function addPen(uint _productCode, address _ownerAddress) public returns (address) {
Pen memory _pen = Pen({
productCode : _productCode,
ownerAddress : _ownerAddress
});
__inventary[_ownerAddress].push(_pen);
// Add history entry for this new pen.
__history[_productCode].push(_ownerAddress);
return msg.sender;
}
function exchangePen(address _buyer, uint _productCode) public returns (bool) {
// Search for pen in the inventary.
for (uint i = 0; i < (__inventary[msg.sender].length); i++) {
// If I find it then change its owner address.
if (__inventary[msg.sender][i].productCode == _productCode) {
Pen memory _pen = Pen(
{
productCode : _productCode,
ownerAddress : _buyer
});
__inventary[_buyer].push(_pen);
__history[_productCode].push(_buyer);
delete __inventary[msg.sender][i];
return true;
}
}
return false;
}
function getHistoryForPen(uint _productCode) public view returns (address[]) {
return __history[_productCode];
}
}
This contract should allow users to register a series of pens into a smart contract. There is a mapping where for each owner address I've an array of Pen
where Pen is a struct. I can add pen to the collection (__inventary
variable) by using the method addPen(...)
. Also I can exchange pens with the function exchangePen(...)
where the given pen is trasferred to the buyer address and removed from the old owner.
There is also an array, called __history
, where all the movments (sellings/buyings) are registered and the user can get this array by calling the appropriate method.
When I compile this code with remix online I get the warning of the gas usage, because if I'm correct, storing data in the contract state is a bad practise that cost a lot of gas and that can cause runtime exception of running out of gas.
One of my question is: How can I cause this exception? How many pen should I insert before get gasLimit exception?
The other question is: Should I deploy a contract that represent only one pen with the method for trasfering and for history? I mean is the following contract better then the previuos one?
pragma solidity ^0.4.23;
contract PenContract{
struct Pen{
uint productCode;
address ownerAddress;
}
address public owner;
Pen public _pen;
// history of a pen.
address[] public __history;
constructor (uint _productCode, address _ownerAddress) public{
owner = msg.sender;
_pen.productCode = _productCode;
_pen.ownerAddress = _ownerAddress;
// Add history entry for this new pen.
__history.push(_ownerAddress);
}
function exchangePen(address _buyer) public returns (bool) {
_pen.ownerAddress = _buyer;
__history.push(_buyer);
return true;
}
function getHistoryForPen() public view returns (address[]) {
return __history;
}
}
In other words, given the fact that deploying a smart contract cost 32k gas (here) is it better to have one contract that manage all the pens and that let you add others (possibily causing the problem of the gas limit) or it is better to deploy one contract for each pen (can also this cause the problem?) ?
Thanks in advance.