I don't understand what's wrong, why I am getting this error on function testing.
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.7;
import "#openzeppelin/contracts/utils/Address.sol";
contract Voting {
address public owner;
uint public counter;
uint public minCandidates = 2;
uint public maxCandidates;
uint public immutable Comission;
struct Candidate {
uint balance;
bool isExistOnThisVoting;
}
struct _Voting {
bool started;
address Winner;
uint StartDate;
uint WinnerBalance;
uint Bank;
uint Period;
mapping(address => Candidate) Candidates;
}
mapping(uint => _Voting) private Votings;
modifier onlyOwner() {
require(msg.sender == owner, "Sorry, but you are not an owner!");
_;
}
constructor(uint _maxCandidates, uint _comission) {
owner = msg.sender;
Comission = _comission;
maxCandidates = _maxCandidates;
}
function addVoting(address[] calldata _candidates, uint _period) public onlyOwner {
require(minCandidates <= _candidates.length && _candidates.length < maxCandidates,
"The number of candidates must comply with the voting rules!"
);
Votings[counter].Period = _period;
for( uint i = 0; i < _candidates.length; i++) {
addCandidate(counter, _candidates[i]);
}
emit votingDraftCreated(counter);
counter++;
}
function editVotingPeriod(uint _id, uint _newPeriod) public onlyOwner {
require(Votings[_id].started = false, "The voting has already begun!");
Votings[_id].Period = _newPeriod;
}
function addCandidate(uint _id, address _candidate) public onlyOwner {
require(address(_candidate) != address(0), "This candidate with zero address!");
require(Address.isContract(_candidate) == false, "A contract can't be a candidate!");
require(Votings[_id].started, "The voting has already begun!");
Votings[_id].Candidates[_candidate].isExistOnThisVoting = true;
emit candidateInfo(_id, _candidate, true);
}
function deleteCandidate(address _candidate, uint _id) public onlyOwner {
require(Votings[_id].started, "The voting has already begun!");
Votings[_id].Candidates[_candidate].isExistOnThisVoting = false;
emit candidateInfo(_id, _candidate, false);
}
function startVoting(uint _id) public onlyOwner {
Votings[_id].started = true;
Votings[_id].StartDate = block.timestamp;
emit votingStarted(_id, block.timestamp);
}
function takePartInVoting(uint _id, address _candidate) public payable {
require(Address.isContract(msg.sender) == false, "A contract can't vote!");
require(Votings[_id].started, "The voting doesn't start!");
require(Votings[_id].StartDate + Votings[_id].Period > block.timestamp, "The voting has ended!");
require(checkCandidate(_id, _candidate), "This candidates does not exist in this voting!");
Votings[_id].Candidates[_candidate].balance += msg.value;
Votings[_id].Bank += msg.value;
if (Votings[_id].Candidates[_candidate].balance > Votings[_id].WinnerBalance) {
Votings[_id].WinnerBalance = Votings[_id].Candidates[_candidate].balance;
Votings[_id].Winner = _candidate;
}
}
function withDrawPrize(uint _id) public {
require(Votings[_id].started, "The voting doesn't start!");
require(Votings[_id].StartDate + Votings[_id].Period < block.timestamp, "The voting is not ended yet!");
require(msg.sender == Votings[_id].Winner, "You are not a winner!");
require(Votings[_id].Bank > 0, "You have already receive your prize!");
uint amount = Votings[_id].Bank;
uint ownerComission = (Comission * amount) / 100;
uint clearAmount = amount - ownerComission;
Votings[_id].Bank = 0;
payable(owner).transfer(ownerComission);
payable(msg.sender).transfer(clearAmount);
}
function checkCandidate(uint _id, address _candidate) public view returns(bool) {
return(Votings[_id].Candidates[_candidate].isExistOnThisVoting);
}
function getVotingInfo(uint256 _id) public view returns (
bool,
uint256,
uint256,
uint256,
uint256,
address
) {
return(
Votings[_id].started,
Votings[_id].StartDate,
Votings[_id].WinnerBalance,
Votings[_id].Bank,
Votings[_id].Period,
Votings[_id].Winner);
}
function setMaxCandidates(uint _maxCandidates) public onlyOwner {
require(minCandidates <= _maxCandidates, "Minimum number of candidates is 2");
maxCandidates = _maxCandidates;
}
event candidateInfo(uint indexed id, address indexed candidate, bool existOnThisVoting);
event votingDraftCreated(uint indexed id);
event votingStarted(uint indexed id, uint startDate);
}
Here is the contract and the test for it:
const { time, loadFixture } = require("#nomicfoundation/hardhat-network-helpers");
const { ethers } = require("hardhat");
const { expect } = require("chai");
describe("Voting", function () {
async function deploy() {
const [owner, user] = await ethers.getSigners();
const Voting = await ethers.getContractFactory("Voting");
const myVoting = await Voting.deploy(5, 10);
return { myVoting, owner, user };
}
it("An owner can change voting's period", async function () {
const { myVoting, owner } = await loadFixture(deploy);
await myVoting.connect(owner).editVotingPeriod(0, 200);
const _votingInfo = await myVoting.getVotingInfo(0);
expect(_votingInfo[2]).to.equal(200);
});
it("Owner can create another voting", async function () {
const { myVoting, owner, user } = await loadFixture(deploy);
const counter_before = await myVoting.counter();
let candidates = new Array();
for (i = 1; i < 4; i++) candidates.push(owner.address);
await myVoting.connect(owner).addVoting(candidates, 100);
const is_candidate = await myVoting.checkCandidate(counter_before, user.address);
expect(is_candidate).to.equal(false);
});
And only two tests are failing with message -> Error: VM Exception while processing transaction: reverted with reason string 'The voting has already begun!'
Could somebody help me to understand why did I get this error?
I don't understand why I got this error.
I found a bug in the solidity code. You're using = instead of == in this line:
require(Votings[_id].started = false, "The voting has already begun!");
I'm not sure this alone will fix your problem, but try again!
Related
i make simple code, but have error "TypeError: Explicit type conversion not allowed from "uint256" to "address"." Can you help me? I even asked the gpt bot about this error, but it confused me even more)))
in the beginning there was a simple idea - 10k nft, 30 of them immediately after the deposit, the minimum price is indicated and everyone can buy without restriction
`pragma solidity ^0.8.4;
import "#openzeppelin/contracts/token/ERC721/ERC721.sol";
contract Sptzrawef is ERC721 {
// Define the token name, symbol, and maximum supply
uint256 public totalSupply = 10000;
string public tokenURI;
// Define the owner of the contract
address public owner;
// Define the minimum price of the token
uint256 public minPrice;
// Define the mapping for the token ownership
mapping(address => mapping(uint256 => bool)) public tokenOwnership;
// The constructor function
constructor() ERC721("Sptzrawef", "SP") {
tokenURI = "https://nftstorage.link/ipfs/ba.................q3oq/";
owner = msg.sender;
minPrice = 0.025 ether;
totalSupply = 10000;
// Mint 30 tokens immediately upon deployment
for (uint256 i = 1; i <= 30; i++) {
tokenOwnership[msg.sender][i] = true;
}
}
// Function to mint new tokens
function mint(address _to, uint256 _tokenId) public {
require(msg.sender == owner);
require(_tokenId <= totalSupply);
require(tokenOwnership[_to][_tokenId] == false);
tokenOwnership[_to][_tokenId] = true;
totalSupply++;
}
// Function to buy the token
function buy(uint256 _tokenId) public payable {
require(msg.value >= minPrice);
require(tokenOwnership[msg.sender][_tokenId] == false);
require(_tokenId <= totalSupply);
tokenOwnership[msg.sender][_tokenId] = true;
}
function balanceOf() public view returns (uint256) {
return totalSupply;
}
function tokenOfOwnerByIndex(address _owner, uint256 _index) public view returns (uint256) {
uint256 count = 0;
for (uint256 i = 1; i <= totalSupply; i++) {
if (tokenOwnership[_owner][i]) {
if (count == _index) {
return i;
}
count++;
}
}
return 0;
}
function ownerOf(uint256 _tokenId) public view override returns (address) {
require(_tokenId <= totalSupply);
for (uint256 i = 0; i < totalSupply; i++) {
address wallet = address(i); - error at this line
if (tokenOwnership[wallet][_tokenId]) {
return wallet;
}
}
return address(0);
}
}`
I think you are using ownerOf function in the wrong way.
try to create a new "getWalletAddress" function, for example, and use it in this way:
function getWalletAddress(uint256 _tokenId) public view returns (address) {
require(_tokenId <= totalSupply);
for (uint256 i = 0; i < totalSupply; i++) {
address wallet = ownerOf(i);
if (tokenOwnership[wallet][_tokenId]) {
return wallet;
}
}
return address(0);
}
}
Or if you want to override the "ownerOf" function then you should go for this code:
function ownerOf(uint256 _tokenId) public view overrides returns (address) {
require(_tokenId <= totalSupply);
for (uint256 i = 0; i < totalSupply; i++) {
address wallet = _ownerOf(i);
if (tokenOwnership[wallet][_tokenId]) {
return wallet;
}
}
return address(0);
}
}
I hope this help resolve your issue
address is 20bytes and uint256 is 32bytes.
Therefore, you need to use uint160 for the type of i to convert it to address.
Or please convert i into uint160 before converting it to address
address wallet = address(uint160(i));
I am getting an Error in the IDE:
UnimplementedFeatureError: Copying of type struct ChatGroups.Message memory[] memory to storage not yet supported.
And I really don't know what to do with everything that I made ( It's commented in French )
There is the full code, and I really tried to find how can I implement what do I want with a different approach if someone could help for that and if I can preserv this code.
Thanks a lot for the people that are going to help !
pragma solidity ^0.6.12;
contract ChatGroups {
struct Group {
string name;
address[] members;
Message[] messages;
}
struct Message {
uint id;
string text;
address author;
bool deleted;
}
Group[] groups;
address[] users;
event GroupCreated(uint groupId, string groupName);
event MessagePublished(uint groupId, uint messageId, string messageText, address messageAuthor);
event MessageDeleted(uint groupId, uint messageId);
event UserAddedToGroup(uint groupId, address user);
event UserRemovedFromGroup(uint groupId, address user);
function createGroup(string memory groupName) public {
require(isUser(msg.sender), "Unauthorized user");
groups.push(Group({
name: groupName,
members: new address[](1),
messages: new Message[](0)
}));
groups[groups.length - 1].members[0] = msg.sender;
emit GroupCreated(groups.length, groupName);
}
function publishMessage(uint groupId, string memory messageText) public {
require(isUser(msg.sender), "Unauthorized user");
Group storage group = groups[groupId - 1];
require(isMember(group, msg.sender), "Unauthorized user");
group.messages.push(Message({
id: group.messages.length + 1,
text: messageText,
author: msg.sender,
deleted: false
}));
emit MessagePublished(groupId, group.messages[group.messages.length - 1].id, messageText, msg.sender);
}
function deleteMessage(uint groupId, uint messageId) public {
require(isUser(msg.sender), "Unauthorized user");
Group storage group = groups[groupId - 1];
require(isMember(group, msg.sender) && group.messages[messageId - 1].author == msg.sender, "Unauthorized user");
group.messages[messageId - 1].deleted = true;
emit MessageDeleted(groupId, messageId);
}
function removeUser(uint groupId, address user) public {
require(isUser(msg.sender), "Unauthorized user");
Group storage group = groups[groupId - 1];
require(isAdmin(group, msg.sender), "Unauthorized user");
require(isMember(group, user), "Unauthorized user");
uint index = getMemberIndex(group, user);
group.members[index] = group.members[group.members.length - 1];
group.members.length--;
emit UserRemovedFromGroup(groupId, user);
}
function addUser(uint groupId, address user) public {
require(isUser(msg.sender), "Unauthorized user");
Group storage group = groups[groupId - 1];
require(isAdmin(group, msg.sender), "Unauthorized user");
require(!isMember(group, user), "User already member of group");
group.members.push(user);
emit UserAddedToGroup(groupId, user);
}
function isUser(address user) private view returns (bool) {
for (uint i = 0; i < users.length; i++) {
if (users[i] == user) {
return true;
}
}
return false;
}
function isMember(Group memory group, address user) public view returns (bool) {
if (group.members[0] == user) {
return true;
}
for (uint i = 1; i < group.members.length; i++) {
if (group.members[i] == user) {
return true;
}
}
return false;
}
function isAdmin(Group memory group, address user) public view returns (bool) {
if (group.members[0] == user) {
return true;
}
for (uint i = 1; i < group.members.length; i++) {
if (group.members[i] == user) {
return true;
}
}
return false;
}
function getMemberIndex(Group storage group, address user) private view returns (uint) {
for (uint i = 0; i < group.members.length; i++) {
if (group.members[i] == user) {
return i;
}
}
return group.members.length;
}
}
While compiling it, I'm getting this error, and I really have no solutions in my mind...
In your smart contract, there are some issues related to your logic in different operation. Thought, the main issue that you shared in this thread refers to a struct inside another struct (in this case, I say about Message[] struct).
The error say that you cannot pass a struct array initializing at runtime because this object is memorized inside storage space.
In details, you have to change the implementation for valorized attribute related to group struct (method: createGroup(string memory groupName)). The change to make is:
Group storage group = groups.push();
group.name = groupName;
group.members = new address[](1);
group.members[0] = msg.sender;
In this way, you create before a space into storage memory array, and then you fill it with the variable (if them has been valorized). At this point, you have to change the method called publishMessage() changing this line:
Group storage group = groups[groupId - 1];
with:
Group storage group = groups[groupId];
This same improvement you have to do in: deleteMessage() and addUser().
In following lines, I put your smart contract with my changes:
// SPDX-License-Identifier: MIT
pragma solidity ^0.6.12;
pragma experimental ABIEncoderV2;
contract ChatGroups {
struct Group {
string name;
address[] members;
Message[] messages;
}
struct Message {
uint id;
string text;
address author;
bool deleted;
}
Group[] groups;
address[] users;
event GroupCreated(uint groupId, string groupName);
event MessagePublished(uint groupId, uint messageId, string messageText, address messageAuthor);
event MessageDeleted(uint groupId, uint messageId);
event UserAddedToGroup(uint groupId, address user);
event UserRemovedFromGroup(uint groupId, address user);
function createGroup(string memory groupName) public {
require(isUser(msg.sender), "Unauthorized user");
// NOTE: I changed at this point your original implementation
Group storage group = groups.push();
group.name = groupName;
group.members = new address[](1);
group.members[0] = msg.sender;
emit GroupCreated(groups.length, groupName);
}
function publishMessage(uint groupId, string memory messageText) public {
require(isUser(msg.sender), "Unauthorized user");
Group storage group = groups[groupId];
require(isMember(group, msg.sender), "Unauthorized user");
group.messages.push(Message({
id: group.messages.length + 1,
text: messageText,
author: msg.sender,
deleted: false
}));
emit MessagePublished(groupId, group.messages[group.messages.length - 1].id, messageText, msg.sender);
}
function deleteMessage(uint groupId, uint messageId) public {
require(isUser(msg.sender), "Unauthorized user");
Group storage group = groups[groupId];
require(isMember(group, msg.sender) && group.messages[messageId - 1].author == msg.sender, "Unauthorized user");
group.messages[messageId - 1].deleted = true;
emit MessageDeleted(groupId, messageId);
}
function removeUser(uint groupId, address user) public {
require(isUser(msg.sender), "Unauthorized user");
Group storage group = groups[groupId - 1];
require(isAdmin(group, msg.sender), "Unauthorized user");
require(isMember(group, user), "Unauthorized user");
uint index = getMemberIndex(group, user);
group.members[index] = group.members[group.members.length - 1];
// NOTE: The attribute length() is only read-only, you cannot modify or handle the length of array using in this way!
group.members.length;
emit UserRemovedFromGroup(groupId, user);
}
function addUser(uint groupId, address user) public {
require(isUser(msg.sender), "Unauthorized user");
Group storage group = groups[groupId];
require(isAdmin(group, msg.sender), "Unauthorized user");
require(!isMember(group, user), "User already member of group");
group.members.push(user);
emit UserAddedToGroup(groupId, user);
}
function isUser(address user) private view returns (bool) {
for (uint i = 0; i < users.length; i++) {
if (users[i] == user) {
return true;
}
}
return false;
}
function isMember(Group memory group, address user) public view returns (bool) {
if (group.members[0] == user) {
return true;
}
for (uint i = 1; i < group.members.length; i++) {
if (group.members[i] == user) {
return true;
}
}
return false;
}
function isAdmin(Group memory group, address user) public view returns (bool) {
if (group.members[0] == user) {
return true;
}
for (uint i = 1; i < group.members.length; i++) {
if (group.members[i] == user) {
return true;
}
}
return false;
}
function getMemberIndex(Group storage group, address user) private view returns (uint) {
for (uint i = 0; i < group.members.length; i++) {
if (group.members[i] == user) {
return i;
}
}
return group.members.length;
}
}
P.S.: I think that you have to integrate users before call the various method inside users array. Although, the smart contract logic give you this error: "Unauthorized user". I think you should think better about this aspect
i have written a simple contract in solidity as seen below
/**
* #title Lottery
* #notice Enter lottery by paying some amount
* #notice pick a random number( verifiably random)
* #notice winner be selected every xtimes
*/
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.7;
import "#chainlink/contracts/src/v0.8/VRFConsumerBaseV2.sol";
import "#chainlink/contracts/src/v0.8/interfaces/VRFCoordinatorV2Interface.sol";
import "#chainlink/contracts/src/v0.8/interfaces/KeeperCompatibleInterface.sol";
// ============= Errors ====================
error Lottery__NotEnoughFunds();
error Lottery__TransferFailed();
error Lottery__NotOpen();
error Raffle__UpkeepNotNeeded(uint256 currentBalance, uint256 numPlayers, uint256 raffleState);
contract Lottery is VRFConsumerBaseV2, KeeperCompatibleInterface {
// ============= Type declaration ===========
enum LotteryState {
OPEN,
CALCULATING
}
// ======== state variables ============
uint256 private immutable i_entranceFee;
address payable[] private s_players;
bytes32 private immutable i_gasLane;
uint64 private immutable i_subscriptionId;
uint32 private immutable i_callbackGasLimit;
uint16 private constant REQUEST_CONFIRMATION = 3;
uint32 private constant NUM_WORDS = 1;
VRFCoordinatorV2Interface private immutable i_vrfCoordinator;
address private s_recentwinner;
LotteryState private s_lotteryState;
uint256 private s_lastTimeStamp;
uint256 private immutable i_interval;
// ========== Events ==================
event LotteryEnter(address indexed player);
event RandomwinnerRequest(uint256 indexed requestId);
event WinnerPicked(address indexed winner);
// ========= constructor ============
constructor(
address vrfCoordinatorV2,
uint256 entranceFee,
uint32 callbackGasLimit,
uint256 interval,
bytes32 gasLane,
uint64 subscriptionId
) VRFConsumerBaseV2(vrfCoordinatorV2) {
i_entranceFee = entranceFee;
i_vrfCoordinator = VRFCoordinatorV2Interface(vrfCoordinatorV2);
i_gasLane = gasLane;
i_subscriptionId = subscriptionId;
i_callbackGasLimit = callbackGasLimit;
s_lotteryState = LotteryState.OPEN;
i_interval = interval;
s_lastTimeStamp = block.timestamp;
}
// ========== functions ============
function enterLottery() public payable {
if (msg.value < i_entranceFee) {
revert Lottery__NotEnoughFunds();
}
if (s_lotteryState != LotteryState.OPEN ) {
revert Lottery__NotOpen();
}
s_players.push(payable(msg.sender));
emit LotteryEnter(msg.sender);
}
function checkUpkeep(
bytes memory /* checkData */
)
public
view
override
returns (
bool upkeepNeeded,
bytes memory /* performData */
)
{
bool isOpen = LotteryState.OPEN == s_lotteryState;
bool timePassed = ((block.timestamp - s_lastTimeStamp) > i_interval);
bool hasPlayers = s_players.length > 0;
bool hasBalance = address(this).balance > 0;
upkeepNeeded = (timePassed && isOpen && hasBalance && hasPlayers);
// return (upkeepNeeded, "0x0"); // can we comment this out?
}
function performUpkeep( bytes calldata /* performData */) external override {
( bool upKeepNeeded, ) = checkUpkeep("");
if(!upKeepNeeded){
revert Raffle__UpkeepNotNeeded(
address(this).balance,
s_players.length,
uint256(s_lotteryState)
);
}
// Request a random number
// Once we get it , do something with it
s_lotteryState = LotteryState.CALCULATING;
uint256 requestId = i_vrfCoordinator.requestRandomWords(
i_gasLane,
i_subscriptionId,
REQUEST_CONFIRMATION,
i_callbackGasLimit,
NUM_WORDS
);
emit RandomwinnerRequest(requestId);
}
function fulfillRandomWords(uint256 /*requestId*/, uint256[] memory randomWords) internal override {
// Modulo function
uint256 winnerIndex = randomWords[0] % s_players.length;
address payable recentWinner = s_players[winnerIndex];
s_recentwinner = recentWinner;
s_lotteryState = LotteryState.OPEN;
s_players = new address payable[](0);
s_lastTimeStamp = block.timestamp;
(bool success, ) = recentWinner.call{value: address(this).balance}("");
if (!success) {
revert Lottery__TransferFailed();
}
emit WinnerPicked(recentWinner);
}
// =============== View /Pure functions =============
function getEntraceFee() public view returns (uint256) {
return i_entranceFee;
}
function getPlayers(uint256 index) public view returns (address) {
return s_players[index];
}
function getRecentWinner() public view returns (address) {
return s_recentwinner;
}
function getRaffleState() public view returns (LotteryState) {
return s_lotteryState;
}
function getNumWords() public pure returns (uint256) {
return NUM_WORDS;
}
function getRequestConfirmations() public pure returns (uint256) {
return REQUEST_CONFIRMATION;
}
function getLastTimeStamp() public view returns (uint256) {
return s_lastTimeStamp;
}
function getInterval() public view returns (uint256) {
return i_interval;
}
function getNumberOfPlayers() public view returns (uint256) {
return s_players.length;
}
}
and it deploy script
const { network, ethers } = require("hardhat");
const {
developmentChains,
networkConfig,
VERIFICATION_BLOCK_CONFIRMATIONS,
} = require("../helper-hardhat-config");
const { verify } = require("../utils/verify");
const VR_FUND_AMOUNT = ethers.utils.parseEther("4");
module.exports = async function ({ getNamedAccounts, deployments }) {
const { deploy, log } = deployments;
const { deployer } = await getNamedAccounts();
const chainId = network.config.chainId;
let vrfCoordinatorV2Address, subscriptionId;
if (developmentChains.includes(network.name)) {
const vrfCoordinatorV2Mock = await ethers.getContract(
"VRFCoordinatorV2Mock"
);
vrfCoordinatorV2Address = vrfCoordinatorV2Mock.address;
const transactionResponse = await vrfCoordinatorV2Mock.createSubscription();
const transactionReceipt = await transactionResponse.wait(1);
subscriptionId = transactionReceipt.events[0].args.subId;
// fund the subscription
await vrfCoordinatorV2Mock.fundSubscription(subscriptionId, VR_FUND_AMOUNT);
} else {
vrfCoordinatorV2Address = networkConfig[chainId]["vrfCoordinatorV2"];
subscriptionId = networkConfig[chainId]["subscriptionId"];
}
const entranceFee = networkConfig[chainId]["entranceFee"];
const gasLane = networkConfig[chainId]["gasLane"];
const callbackGasLimit = networkConfig[chainId]["callbackGasLimit"];
const interval = networkConfig[chainId]["interval"];
const args = [
vrfCoordinatorV2Address,
entranceFee,
gasLane,
subscriptionId,
callbackGasLimit,
interval,
];
const lottery = await deploy("Lottery", {
from: deployer,
args: args,
log: true,
waitConfirmations: network.config.blockConfirmations || 1,
});
if (
!developmentChains.includes(network.name) &&
process.env.ETHERSCAN_API_KEY
) {
log("Verifying.....");
await verify(lottery.address, args);
}
log("-----------------------------------");
};
module.exports.tags = ["all", "lottery"];
mock deploy script
const { network } = require("hardhat")
const { developmentChains } = require("../helper-hardhat-config")
const BASE_FEE = ethers.utils.parseEther("0.25") // 0.25 is this the premium in LINK?
const GAS_PRICE_LINK = 1e9 // link per gas, is this the gas lane? // 0.000000001 LINK per gas
module.exports = async function ({ getNamedAccounts, deployments }) {
const { deploy, log } = deployments
const { deployer } = await getNamedAccounts()
const chainId = network.config.chainId
const args =[BASE_FEE, GAS_PRICE_LINK]
// If we are on a local development network, we need to deploy mocks!
if(developmentChains.includes(network.name)){
log("Local Network Detected! Deploying mocks...")
// deploy a mock vrfCoordinator
await deploy("VRFCoordinatorV2Mock",{
from:deployer,
log:true,
args:args,
})
log("Mocks Deployed!")
log("------------------------------------------")
}
}
module.exports.tags = ["all", "mocks"]
and helper configuration
const { ethers } = require("hardhat")
const networkConfig = {
5:{
name:"goerli",
vrfCoordinatorV2:"0x2Ca8E0C643bDe4C2E08ab1fA0da3401AdAD7734D",
entranceFee: ethers.utils.parseEther("0.01"),
gasLane:"0x79d3d8832d904592c0bf9818b621522c988bb8b0c05cdc3b15aea1b6e8db0c15",
subscriptionId:"0",
callbackGasLimit:"500000",
interval:"30"
},
31337:{
name:"hardhat",
entranceFee: ethers.utils.parseEther("0.01"),
gasLane:"0x79d3d8832d904592c0bf9818b621522c988bb8b0c05cdc3b15aea1b6e8db0c15",
callbackGasLimit:"500000",
interval:"30"
}
}
const developmentChains = ["hardhat", "localhost"]
module.exports = {
networkConfig,
developmentChains
}
when run yarn hardhat deploy, i encounter an error
as below
An unexpected error occurred:
Error: ERROR processing C:\Users\amoko\Desktop\blockchain\lottery\deploy\01-deploy-lottery.js:
Error: value out-of-bounds (argument="callbackGasLimit", value="0x79d3d8832d904592c0bf9818b621522c988bb8b0c05cdc3b15aea1b6e8db0c15", code=INVALID_ARGUMENT, version=abi/5.7.0)
at Logger.makeError (C:\Users\amoko\Desktop\blockchain\lottery\node_modules\#ethersproject\logger\src.ts\index.ts:269:28)
at Logger.throwError (C:\Users\amoko\Desktop\blockchain\lottery\node_modules\#ethersproject\logger\src.ts\index.ts:281:20)
at Logger.throwArgumentError (C:\Users\amoko\Desktop\blockchain\lottery\node_modules\#ethersproject\logger\src.ts\index.ts:285:21)
at NumberCoder.Coder._throwError (C:\Users\amoko\Desktop\blockchain\lottery\node_modules\#ethersproject\abi\src.ts\coders\abstract-coder.ts:68:16)
at NumberCoder.encode (C:\Users\amoko\Desktop\blockchain\lottery\node_modules\#ethersproject\abi\src.ts\coders\number.ts:35:18)
at C:\Users\amoko\Desktop\blockchain\lottery\node_modules\#ethersproject\abi\src.ts\coders\array.ts:71:19
at Array.forEach (<anonymous>)
at pack (C:\Users\amoko\Desktop\blockchain\lottery\node_modules\#ethersproject\abi\src.ts\coders\array.ts:54:12)
at TupleCoder.encode (C:\Users\amoko\Desktop\blockchain\lottery\node_modules\#ethersproject\abi\src.ts\coders\tuple.ts:54:20)
at AbiCoder.encode (C:\Users\amoko\Desktop\blockchain\lottery\node_modules\#ethersproject\abi\src.ts\abi-coder.ts:111:15)
at DeploymentsManager.executeDeployScripts (C:\Users\amoko\Desktop\blockchain\lottery\node_modules\hardhat-deploy\src\DeploymentsManager.ts:1222:19)
at processTicksAndRejections (node:internal/process/task_queues:96:5)
at runNextTicks (node:internal/process/task_queues:65:3)
at listOnTimeout (node:internal/timers:528:9)
at processTimers (node:internal/timers:502:7)
at DeploymentsManager.runDeploy (C:\Users\amoko\Desktop\blockchain\lottery\node_modules\hardhat-deploy\src\DeploymentsManager.ts:1052:5)
at SimpleTaskDefinition.action (C:\Users\amoko\Desktop\blockchain\lottery\node_modules\hardhat-deploy\src\index.ts:438:5)
at Environment._runTaskDefinition (C:\Users\amoko\Desktop\blockchain\lottery\node_modules\hardhat\src\internal\core\runtime-environment.ts:308:14)
at Environment.run (C:\Users\amoko\Desktop\blockchain\lottery\node_modules\hardhat\src\internal\core\runtime-environment.ts:156:14)
at SimpleTaskDefinition.action (C:\Users\amoko\Desktop\blockchain\lottery\node_modules\hardhat-deploy\src\index.ts:584:32)
error Command failed with exit code 1.
i need help on figuring out why is it is propagting this error and how to fix it
I have tried changing the callbackgasLimit but it still brings the error. i expect the contract to get deployed on my localhost network when i run yarn hardhat deploy
i discovered that i had used a wrong variable(raffleState) in defining the event "Raffle__UpkeepNotNeeded" so it was leading to a significant increase in gas fees which were exceeding the max gas limit set for the testnet hence the error
Can't make it gives the prize for all winners, just the first one person that putted the right combination. I think there is a problem with findWinners function but I can't find it. If I make address A the good combination, then B with a not good one, and finally C with also a good one, it only gives the prize to A.
pragma solidity ^0.5.1;
contract Lottery {
Game[] ListGames;
// uint public nbGames = ListGames.length;
uint price = 100000;
uint[6] winnerGame;
// winnerGame = [1,2,3,4,5,6];
address payable[] ListWinners;
uint winnersPayed = 0;
uint expiredGames = 0;
struct Game {
address payable gamer;
uint[6] numbers;
uint date;
bool valid;
}
function setWinner(uint[6] memory _winnerGame) public {
winnerGame = _winnerGame;
}
function findWinners() public returns (address payable[] memory) {
uint size = ListGames.length;
bool win = true;
for (uint j = 0; j < size; j++) {
for (uint i=0; i<6 ; i++) {
if ((ListGames[j].numbers[i] != winnerGame[i]) || !ListGames[j].valid) {
win = false;
}
}
if (win) {
ListGames[j].valid = false;
expiredGames ++;
ListWinners.push(ListGames[j].gamer);
}
}
return ListWinners;
}
function payer() public returns (uint) {
uint nbWinners = ListWinners.length;
uint prize;
if (nbWinners - winnersPayed != 0) {
prize = address(this).balance / (nbWinners- winnersPayed);
for (uint i = 0; i < nbWinners; i++) {
if(ListWinners[i] != address(0)) {
ListWinners[i].transfer(prize);
delete ListWinners[i];
winnersPayed++;
require(ListWinners[i] == address(0));
}
}
}
return nbWinners;
}
modifier costs(uint amount) {
require(msg.value >= amount);
_;
}
function postGame(uint[6] memory _numbers) public payable costs(price) {
Game memory newGame = Game(msg.sender, _numbers, block. timestamp, true);
ListGames.push(newGame);
}
function numberValidGames() public view returns (uint) {
return ListGames.length - expiredGames;
}
function getWinnersList() public view returns (address payable [] memory) {
return ListWinners;
}
function getTime() public view returns (uint) {
return block.timestamp;
}
function getBalance() public view returns (uint) {
return address(this).balance;
}
}
I have the following contract that i plan on using as an external contract in a different contract:
pragma solidity ^0.4.24;
import "./Ownable.sol";
import "./oraclizeAPI.sol";
interface EtherHiLoRandomNumberRequester {
function incomingRandomNumber(address player, uint8 randomNumber) external;
function incomingRandomNumberError(address player) external;
}
interface EtherHiLoRandomNumberGenerator {
function generateRandomNumber(address player, uint8 max) external returns (bool);
}
/// #title EtherHiLoRandom
/// #dev the contract than handles the EtherHiLo random numbers
contract EtherHiLoRandom is usingOraclize, Ownable, EtherHiLoRandomNumberGenerator {
uint8 constant FAILED_ROLE = 69;
uint public rngCallbackGas;
mapping(bytes32 => uint) private failedRolls;
mapping(bytes32 => address) private rollIdToPlayer;
mapping(bytes32 => uint8) private rollIdToMax;
mapping(bytes32 => address) private rollIdToCaller;
constructor() public {
oraclize_setProof(proofType_Ledger);
setRNGCallbackGasConfig(1500000, 10000000000);
}
function generateRandomNumber(address player, uint8 max) external returns (bool) {
bytes32 rollId = oraclize_newRandomDSQuery(0, 7, rngCallbackGas);
if (failedRolls[rollId] == FAILED_ROLE) {
delete failedRolls[rollId];
delete rollIdToPlayer[rollId];
delete rollIdToMax[rollId];
delete rollIdToCaller[rollId];
return false;
}
rollIdToPlayer[rollId] = player;
rollIdToMax[rollId] = max;
rollIdToCaller[rollId] = msg.sender;
return true;
}
function __callback(bytes32 rollId, string _result, bytes _proof) public {
require(msg.sender == oraclize_cbAddress());
address player = rollIdToPlayer[rollId];
address caller = rollIdToCaller[rollId];
uint8 max = rollIdToMax[rollId];
// avoid reorgs
if (player == address(0)) {
failedRolls[rollId] = FAILED_ROLE;
return;
}
delete failedRolls[rollId];
delete rollIdToPlayer[rollId];
delete rollIdToMax[rollId];
delete rollIdToCaller[rollId];
EtherHiLoRandomNumberRequester requester = EtherHiLoRandomNumberRequester(caller);
if (oraclize_randomDS_proofVerify__returnCode(rollId, _result, _proof) != 0) {
requester.incomingRandomNumberError(player);
} else {
uint8 randomNumber = uint8(uint(keccak256(_result)) % max);
requester.incomingRandomNumber(player, randomNumber);
}
}
/// OWNER / MANAGEMENT RELATED FUNCTIONS
function transferBalance(address to, uint amount) public onlyOwner {
to.transfer(amount);
}
function setRNGCallbackGasConfig(uint gas, uint price) public onlyOwner {
rngCallbackGas = gas;
oraclize_setCustomGasPrice(price);
}
function destroyAndSend(address _recipient) public onlyOwner {
selfdestruct(_recipient);
}
}
And I have the following test:
pragma solidity ^0.4.24;
import "truffle/Assert.sol";
import "truffle/DeployedAddresses.sol";
import "../contracts/EtherHiLoRandom.sol";
contract TestEtherHiLoRandom is EtherHiLoRandomNumberRequester {
function incomingRandomNumber(address player, uint8 randomNumber) {
//require(false, "incomingRandomNumber");
}
function incomingRandomNumberError(address player) {
//require(false, "incomingRandomNumberError");
}
function testInitialBalanceUsingDeployedContract() {
EtherHiLoRandom subject = EtherHiLoRandom(DeployedAddresses.EtherHiLoRandom());
bool result = subject.generateRandomNumber(msg.sender, 5);
Assert.isTrue(result, "generateRandomNumber failed");
Assert.isTrue(true, "itchy balls");
}
}
My test fails in TestEtherHiLoRandom when it calls oraclize_newRandomDSQuery. The error that i get is:
TestEtherHiLoRandom
1) testInitialBalanceUsingDeployedContract
> No events were emitted
0 passing (3s) 1 failing
1) TestEtherHiLoRandom
testInitialBalanceUsingDeployedContract:
Error: VM Exception while processing transaction: revert
at Object.InvalidResponse (node_modules/truffle/build/webpack:/~/web3/lib/web3/errors.js:38:1)
at node_modules/truffle/build/webpack:/~/web3/lib/web3/requestmanager.js:86:1
at node_modules/truffle/build/webpack:/packages/truffle-provider/wrapper.js:134:1
at XMLHttpRequest.request.onreadystatechange (node_modules/truffle/build/webpack:/~/web3/lib/web3/httpprovider.js:128:1)
at XMLHttpRequestEventTarget.dispatchEvent (node_modules/truffle/build/webpack:/~/xhr2/lib/xhr2.js:64:1)
at XMLHttpRequest._setReadyState (node_modules/truffle/build/webpack:/~/xhr2/lib/xhr2.js:354:1)
at XMLHttpRequest._onHttpResponseEnd (node_modules/truffle/build/webpack:/~/xhr2/lib/xhr2.js:509:1)
at IncomingMessage.<anonymous> (node_modules/truffle/build/webpack:/~/xhr2/lib/xhr2.js:469:1)
at endReadableNT (_stream_readable.js:1056:12)
at _combinedTickCallback (internal/process/next_tick.js:138:11)
at process._tickCallback (internal/process/next_tick.js:180:9)
Any idea what i'm doing wrong? I haven't yet ran it on any test networks, only my local testrpc (i'm using ethereum-bridge and have verified that the Oraclize contract is properly deployed on the testrpc).