Im new to Solidity, I got a problem that when I call purchaseCard
function, it always returns the error The called function should be payable if you send value and the value you send should be less than your current balance.
on Remix IDE.
I think the problem is at the complexity of my structs or I probably called variables not allowed. But I still cant find fix after many days researching.
These are my structs.
struct Card {
string name;
uint price;
}
mapping(uint => Card) public cards;
uint public numberOfTypes;
struct Purchase {
Card card;
uint purchaseDate;
}
struct User {
uint numberOfCards;
Purchase[] purchase;
bool exist;
}
mapping(address => User) public users;
And these are my functions, I will make it short.
// function addCard(string memory _name, uint _price) public isOwner;
// function removeCard(uint _id) public isOwner;
// function checkExistedUser(address _userAddress) public view returns(bool);
function purchaseCard(uint _id) public {
User storage user = users[msg.sender];
if (!checkExistedUser(msg.sender)) {
user.exist = true;
user.numberOfCards = 0;
}
Purchase storage purchase = user.purchase[user.numberOfCards];
purchase.card = cards[_id];
purchase.purchaseDate = block.timestamp;
user.numberOfCards++;
}
// function expiredCard(uint _id) public;
// function showRemainingDate(uint _id) public view returns(uint);
// function showPurchasedCards() public view returns (Purchase[] memory);
This is my full code: https://github.com/SnowyField1906/code/blob/main/purchase.sol
Thank you very much, I hope to learn more things.
In this case, you cannot create an empty 'space' for purchase
array in storage before fill it because the type of this operation is an array and not a mapping!
To solve this issue, you can use the push()
method (available only for storage array) to fill purchase() array into Purchase
struct.
Following your logic, you must change purchaseCard()
method in this way:
function purchaseCard(uint _id) public {
User storage user = users[msg.sender];
if (!checkExistedUser(msg.sender)) {
user.exist = true;
user.numberOfCards = 0;
}
user.purchase.push(Purchase(cards[_id], block.timestamp));
user.numberOfCards++;
}
In Solidity, If you have to send/receive ETHs then the payable
function should be used. Try this:
function purchaseCard(uint _id) public payable {
or add payable
to your constructor.
pls refer to this: https://solidity-by-example.org/payable/
And btw pls next time share the complete code snippet.
I can't able to understand the entire code and flow.. but while debugging..
the revert occurs in the belowline of the purchasecard function
Purchase storage purchase = user.purchase[user.numberOfCards];
It seems like you are accessing the user mapping which does not contain any User Struct..
I think you forgot to assing the value to the user mapping in the addCard Function.
I may be wrong and I hope it helps..
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.