I am creating smart contract for lottery system and I want to make a time based transaction like a certain amount of players are added into the array then a time stamp should run and on specific time which I will declare should send the amount to the winner,
This is the part where I am stuck, I am trying to enter into the lottery from this this function and when conditions met I want to transfer the amount through the same function cause I want to automate the winner function:
function enter() public payable{
require(msg.value > 1 wei);
players.push(msg.sender);
if(players.length==10){
start = block.timestamp;
}
if(block.timestamp>= start+totalTime){
uint index = random()% players.length;
players[index].transfer(this.balance);
dead[index].transfer((this.balance*2)/100);
winner = players[index];
players = new address[](0);
}
This is my complete code:
pragma solidity ^0.4.26;
contract Lottery{
address public manager;
address[] public players;
address [0x000000000000000000000000000000000000dead] private dead;
address public winner;
uint start;
uint end;
uint totalTime=50;
constructor()public {
manager = msg.sender;
}
function enter() public payable{
require(msg.value > 1 wei);
players.push(msg.sender);
if(players.length==10){
start = block.timestamp;
}
if(block.timestamp>= start+totalTime){
uint index = random()% players.length;
players[index].transfer(this.balance);
dead[index].transfer((this.balance*2)/100);
winner = players[index];
players = new address[](0);
}
}
function random() private view returns (uint){
return uint(keccak256(block.difficulty,now,players));
}
function getBalance() public view returns(uint){
return address(this).balance;
}
function getPlayers() public view returns (address[]){
return players;
}
function getWinner() public view returns (address){
return winner;
}
function getTime() public view returns (uint){
return end-block.timestamp;
}
}
You can't, someone has to call the function and pay the gas fees, what you can do is having an script that listen for events and every time someone "enters" in the lottery and check if already reached the desired amount and then calls the function to get the winner, also you can't have any logic outside a function in solidity, using block difficulty and timestamp as a source of randomness if you are planing to deploy to production is better to use chainlink
Related
The error I face in remix is Gas estimation errored with the following message (see below). The transaction execution will likely fail. Do you want to force sending?
execution reverted even if I have enough money to create a contract
// SPDX-License-Identifier: MIT
pragma solidity ^0.6.0;
// Get the latest ETH/USD price from chainlink price feed
import "#chainlink/contracts/src/v0.6/interfaces/AggregatorV3Interface.sol";
contract FundMe {
// safe math library check uint256 for integer overflows
//mapping to store which address depositeded how much ETH
mapping(address => uint256) public addressToAmountFunded;
// array of addresses who deposited
address[] public funders;
//address of the owner (who deployed the contract)
address public owner;
constructor() public {
owner = msg.sender;
}
function fund() public payable {
// 18 digit number to be compared with donated amount
uint256 minimumUSD = 50 * 10 ** 18;
//is the donated amount less than 50USD?
require(getConversionRate(msg.value) >= minimumUSD, "You need to spend more ETH!");
//if not, add to mapping and funders array
addressToAmountFunded[msg.sender] += msg.value;
funders.push(msg.sender);
}
function getVersion() public view returns (uint256){
AggregatorV3Interface priceFeed = AggregatorV3Interface(0x9326BFA02ADD2366b30bacB125260Af641031331);
return priceFeed.version();
}
function getPrice() public view returns(uint256){
AggregatorV3Interface priceFeed = AggregatorV3Interface(0x9326BFA02ADD2366b30bacB125260Af641031331);
(,int256 answer,,,) = priceFeed.latestRoundData();
// ETH/USD rate in 18 digit
return uint256(answer * 10000000000);
}
function getConversionRate(uint256 ethAmount) public view returns (uint256){
uint256 ethPrice = getPrice();
uint256 ethAmountInUsd = (ethPrice * ethAmount) / 1000000000000000000;
// the actual ETH/USD conversation rate, after adjusting the extra 0s.
return ethAmountInUsd;
}
}
1)try downgrading your compiler version to 0.5
if that does not work try this
2)In remix try to increase your gas limit to probably 8000000
You need a receve/fallback function to send ETH to a contract. Try to add these to your contract code:
receive() external payable {
// React to receiving ether
}
I made a basic smart contract:
contract Coursetro {
uint counter = 0;
event SetCounter(uint value);
function setCounter(uint value) public {
counter +=1;
emit SetCounter(value);
}
function getCounter() public view returns (uint) {
return counter;
}
}
but i don't know how to set a fixed ETH price for setCounter function
for exemple how can i set the price of 1 ETH to run setCounter function?
So i could just take the 1 ETH and put it on my wallet, as a sale.
First of all, welcome to the community. I recommend adding your code to your post directly, so that it is easier to read.
You could use the 'payable' modifier to make the function able to receive ether. Then you can simply make a require statement to check if the value sent was enough. Something like this:
function setCounter(uint value) public payable {
require(msg.value >= 1 ether, "Error msg here");
// You can additionally return the surplus ether.
if (msg.value > 1) {
payable(msg.sender).transfer(msg.value - 1 ether);
}
// Now send ether to your wallet.
payable("your wallet address").transfer(1 ether);
// Rest of the logic.
counter +=1;
emit SetCounter(value);
}
Hope it is useful :)
pragma solidity >=0.4.16 <0.9.0;
contract Wallet {
uint balance = 0;
bool a = true;
function deposit(uint dep_amt) public {
balance += dep_amt;
}
function withdraw (uint wdraw_amt) public view returns(string memory error){
if(wdraw_amt<=balance){
balance -= wdraw_amt;
}
else{
error = "Insufficient Balance";
return error;
}
}
function getBalnce() public view returns (uint) {
return balance;
}
}
I'm very new to solidity and I'm trying to code a simple bank system which shows the balance and updates the balance according to the deposits and withdraws. I want to display an error in withdraw function when the amount to be withdrawn is greater than the balance but it shows an error saying:
TypeError: Function declared as view, but this expression (potentially) modifies the state and thus requires non-payable (the default) or payable.
Is there a way to possibly show the error from the same function?
If not, Please let me know an alternative.
Thanks in advance!!.
A view function promises not to modify the contract state - such as not to modify storage variables. See the docs for more info.
But your code modifies the balance variable, which is a storage variable.
function withdraw (uint wdraw_amt) public view returns(string memory error){
if(wdraw_amt<=balance){
balance -= wdraw_amt; // <-- here
}
and updates the balance according to the deposits and withdraws
Since one of your requirements is to actually update the storage variable, you need to remove the view modifier in order to be able to do that.
function withdraw (uint wdraw_amt) public returns(string memory error){
Users will then need to send a transaction (not a call) to execute the withdraw() function.
When you have a function executed by a transaction (and not by a call), you can get the string output in two ways.
Revert reason message
function withdraw(uint wdraw_amt) public {
if (wdraw_amt <= balance) {
balance -= wdraw_amt;
} else {
revert("Insufficient Balance");
}
}
Event log
event Error(string _message);
function withdraw(uint wdraw_amt) public {
if (wdraw_amt <= balance) {
balance -= wdraw_amt;
} else {
emit Error("Insufficient Balance");
}
}
Trying to test solidity using Remix IDE. I keep getting the error:
Gas estimation errored with the following message (see below). The transaction > execution will likely fail. Do you want to force sending?
Does anybody have an idea about what might be giving me this error. It I am trying to sell products using the ethereum smart contracts. I have used the Remix IDE to create this contract with value = 0.
I am successfully able to create the contract and add_product but I am unable to Buy. The last line give me the error mentionned above.
The solidity file I am testing againt is the following: As you can see I create a Sell contract which would allow a user to sell products using the blockchain and a buyer to retrieve the product paying the price in ethereum. If anyone has a better solution for me to use for this exact use-case I am opened to suggestions.
pragma solidity ^0.4.0;
contract Sell {
struct Product_Quantity{
string _product_name;
uint256 _product_quantity;
uint256 _price_unity;
bool isValue;
}
struct Seller{
address _id;
mapping(string => Product_Quantity) products;
}
Seller public seller;
mapping (address => Product_Quantity) product_owners;
function Sell(){
seller._id = msg.sender;
}
function add_product(string product_name, uint256 product_quantity, uint256 price_unity) {
if(msg.sender != seller._id) throw;
if(seller.products[product_name].isValue){
seller.products[product_name]._product_quantity += product_quantity;
}
else{
seller.products[product_name] = Product_Quantity(product_name, product_quantity, price_unity, true);
}
}
function Buy( string product_name, uint256 quantity) payable {
if(product_owners[msg.sender].isValue){
product_owners[msg.sender]._product_quantity += quantity;
}
else{
product_owners[msg.sender] = Product_Quantity(product_name, quantity, seller.products[product_name]._price_unity, true);
}
seller.products[product_name]._product_quantity -= quantity;
seller._id.transfer(seller.products[product_name]._price_unity * quantity);
}
}
That's a very generic Remix error message. Fortunately, today I'm seeing new error messages on Remix (nice update guys!), which makes it easier to debug the problem.
When someone tries to buy a product, you should check if the value passed (in wei) is the right amount to buy that product and quantity.
Since you're not checking that, a buyer can buy a product with an amout equals to 0, which means the contract will have no wei to send to the seller at the end of the buy() function. That will throw an exception and the transaction will be reverted.
I updated your code to run on solidity 0.4.23 (latest version), made some code refactoring and add a modifier to the buy() function to check if the amount passed is correct.
pragma solidity ^0.4.23;
contract Sell {
struct Product_Quantity{
string _product_name;
uint256 _product_quantity;
uint256 _price_unity;
bool isValue;
}
mapping (address => Product_Quantity) product_owners;
struct Seller{
address _id;
mapping(string => Product_Quantity) products;
}
Seller public seller;
constructor() public {
seller._id = msg.sender;
}
function add_product (string product_name, uint256 product_quantity, uint256 price_unity) public {
require(msg.sender == seller._id);
if (seller.products[product_name].isValue) {
seller.products[product_name]._product_quantity += product_quantity;
}
else{
seller.products[product_name] = Product_Quantity(product_name, product_quantity, price_unity, true);
}
}
modifier hasEnoughEther (string product_name, uint256 quantity) {
require (seller.products[product_name].isValue); // does the product exists?
uint256 neededEther = seller.products[product_name]._price_unity * quantity;
require (msg.value == neededEther); // did the buyer sent the correct value?
_;
}
function buy (string product_name, uint256 quantity) payable public hasEnoughEther (product_name, quantity) {
if (product_owners[msg.sender].isValue) {
product_owners[msg.sender]._product_quantity += quantity;
} else {
product_owners[msg.sender] = Product_Quantity(product_name, quantity, seller.products[product_name]._price_unity, true);
}
seller.products[product_name]._product_quantity -= quantity;
seller._id.transfer(seller.products[product_name]._price_unity * quantity);
}
}
In my case, I needed to fund my contract so it can perform operations.
In your case you are trying to use a MODIFIER function with arguments but have not passed any parameters to it in the Buy function.
And in my case I was trying to trigger a non-payable function with some ether in the VALUE field of the Deploy and Run Transactions tab.
This is our MEG-Token-Distribution 1.0. We need a help from someone.
Link for full code.
How we can make access for mint function (token owner is EggithCrowdsale)?
How we can change rate depend on msg.value (if > 20 ETH price another)?
contract EggithToken is MintableToken {
string public constant name = "EggithToken";
string public constant symbol = "MEG";
uint8 public constant decimals = 18;
}
contract EggithCrowdsale is Crowdsale {
function EggithCrowdsale(uint256 _startTime, uint256 _endTime, uint256 _rate, address _wallet)
Crowdsale(_startTime, _endTime, _rate, _wallet)
{
}
// creates the token to be sold.
// override this method to have crowdsale of a specific mintable token.
function createTokenContract() internal returns (MintableToken) {
return new EggithToken();
}
}
"How we can change rate depend on msg.value (if > 20 ETH price another)?"
uint public constant regularPrice = 100;
uint public constant moreThan20EthContributionPrice = 75;
function () payable {
//fallback function that is called when ETH is sent to contract
... some code ...
uint price = calculatePrice();
... some code ...
}
function calculatePrice() internal constant returns (uint) {
if (msg.value > 20 ether) return moreThan20EthContributionPrice;
return regularPrice;
}