I am making a lottery application and here I initialized some variables...Now I also made a function to participate the users and make it payable and put some require conditions. Now when the function is called it supposed to add the user details in array made named "participantList" but when I call the value of array using the index, The transaction got reverted..
//SPDX-License-Identifier:MIT
pragma solidity ^0.8.7;
contract Lottery{
struct Participant{
address participantAddr;
uint noOfLotts;
}
address public manager;
Participant [] public participantList;
constructor(){
manager = msg.sender;
}
function participate () external payable{
require(msg.value == 2 ether,"The amount must be equal to 2 Ethers");
for(uint i = 0; i<=participantList.length; i ){
if(participantList[i].participantAddr == msg.sender){
participantList[i].noOfLotts ;
}
else{
participantList.push(Participant(msg.sender,1));
}
}
}
}
`````````````````````````````````
CodePudding user response:
I wouldn't use an Array, because you can get an out of bounds error and your transaction will be reverted.
What you can do is create a mapping for every address that participates
mapping(address => Participant) public _participantMap;
and your participate function can be changed to
function participate() external payable {
require(msg.value == 2 ether,"The amount must be equal to 2 Ethers");
if (_participantMap[msg.sender].participantAddr == address(0)) {
_participantMap[msg.sender] = Participant(msg.sender, 1);
} else {
_participantMap[msg.sender].noOfLotts = 1;
}
}
I created a quick script to test the participate function. If you run this, it will add 1 to the noOfLotts
import { ethers } from "hardhat";
async function main() {
const [owner, userOne, userTwo] = await ethers.getSigners();
const contractAddress = process.env.LOTTERY_CONTRACT_ADDRESS;
const Lottery = await ethers.getContractFactory("Lottery");
const contractInstance = await Lottery.attach(`${contractAddress}`);
await contractInstance.connect(userOne).participate({
value: ethers.utils.parseUnits("2", "ether"),
});
const participant = await contractInstance._participantMap(`${userOne.address}`);
console.log(participant);
}
main().catch((error) => {
console.error(error);
process.exitCode = 1;
});
Results after runnings the scripts a couple times
npx hardhat run scripts/2_participate.ts --network localhost
[
'0x70997970C51812dc3A010C7d01b50e0d17dc79C8',
BigNumber { value: "1" },
participantAddr: '0x70997970C51812dc3A010C7d01b50e0d17dc79C8',
noOfLotts: BigNumber { value: "1" }
]
npx hardhat run scripts/2_participate.ts --network localhost
[
'0x70997970C51812dc3A010C7d01b50e0d17dc79C8',
BigNumber { value: "2" },
participantAddr: '0x70997970C51812dc3A010C7d01b50e0d17dc79C8',
noOfLotts: BigNumber { value: "2" }
]
npx hardhat run scripts/2_participate.ts --network localhost
[
'0x70997970C51812dc3A010C7d01b50e0d17dc79C8',
BigNumber { value: "3" },
participantAddr: '0x70997970C51812dc3A010C7d01b50e0d17dc79C8',
noOfLotts: BigNumber { value: "3" }
]
Changing to userTwo in the script to add a new participant
Compiled 1 Solidity file successfully
[
'0x3C44CdDdB6a900fa2b585dd299e03d12FA4293BC',
BigNumber { value: "1" },
participantAddr: '0x3C44CdDdB6a900fa2b585dd299e03d12FA4293BC',
noOfLotts: BigNumber { value: "1" }
]
Hope this helps :)