function that changes a uint variable of days give error - solidity - function

I have a uint variable that contains days, through a function I wish I could have the ability to change but it gives me this error when I compile the code:
unexpected "days" after "time"
this is my code:
uint public cliff = 0 days;
function changeCliff(uint time) public onlyOwner {
cliff = time days;
}
how can i do it?

These suffixes cannot be applied to variables. For example, if you want to interpret a function parameter in days, you can in the following way:
function f(uint start, uint daysAfter) public {
if (block.timestamp >= start + daysAfter * 1 days) {
// ...
}
}
Source: docs
So applied to your code:
cliff = time * 1 days;

Related

Is it necessary to write a return statement in Solidity?

pragma solidity ^0.8.0;
contract Counter {
uint public number;
string public name;
constructor(string memory input_name, uint input_number){
name = input_name;
number = input_number;
}
function add () public {
number ++;
}
function subtract() public {
number --;
}
function update_name(string memory update) public {
name = update;
}
I wrote a very basic contract here and I'm wondering why I should write a return statement for each of my functions as it is already returns a value.
Could someone explain my error or the point of the return statement here?
Solidity have the "implicit return" feature, so as you noticed, you may skip the "return" statement in some cases. However, it's discourages, since you're not explicit enough and may cause a lot of confusion and issues.
For details please check the following links:
https://medium.com/#pareshmasani/ethereum-smart-contract-implicit-return-can-go-wrong-33b41c93dbba
https://github.com/ethereum/solidity/issues/3134
https://blog.openzeppelin.com/instadapp-audit/

How to handle timestamp in Solidity

I have written a smart contract which gets the block.timestamp and limits the caller to call the contract until the 2 hours passed as following:
mapping(address => uint256) public coffeKitchenLatestAqcuiredBalances;
function requestStarCoinFromCoffeeKitchenFaucet() public {
address callerAddress = msg.sender;
uint256 userLastRetrieveTime = coffeKitchenLatestAqcuiredBalances[callerAddress];
if (userLastRetrieveTime != 0){
uint256 epochNow = block.timestamp;
require(userLastRetrieveTime < epochNow - 7200,"You need to wait for 2 hours from your last call");
}
}
However I did not manage to extract to timestamp to limit the call time should be from 8AM to 6PM.
How can I format the epoch timestamp and check it on the smart contract call?
A great example of retrieving the hour from timestamp is in this library.
Since you might not want to import the whole library for just one function, here's a minimal implementation:
pragma solidity ^0.8;
library TimestampHelper {
uint constant SECONDS_PER_DAY = 24 * 60 * 60;
uint constant SECONDS_PER_HOUR = 60 * 60;
function getHour(uint timestamp) internal pure returns (uint hour) {
uint secs = timestamp % SECONDS_PER_DAY;
hour = secs / SECONDS_PER_HOUR;
}
}
contract MyContract {
function foo() external view {
uint currentHour = TimestampHelper.getHour(block.timestamp);
require(
currentHour >= 8 && currentHour <= 18,
"We're closed now. Opened from 8 AM to 6 PM UTC."
);
}
}

if statement to activate a function after a time period (solidity)

I want the following function to activate after 6 mins(360 secs) of contract deployment because my task requires a withdrawal lock. should I put if (block.timestamp > 360) before the function or inside the function just before the remaining code?
function withdraw(uint256 amount) external updateReward(msg.sender) nonReentrant {
if (block.timestamp > 360) {
s_totalSupply -= amount;
s_balances[msg.sender] -= amount;
emit WithdrewStake(msg.sender, amount);
// transfer: send tokens from contract back to msg.sender.
bool success = s_stakingToken.transfer(msg.sender, amount);
if (!success) {
revert TransferFailed(); // revert resets everything done in a failed transaction.
}}
}
But I'm not even sure if if (block.timestamp > 360) is the right code for this case.
Figured it out for you my brother:
pragma solidity ^0.8.7;
import "hardhat/console.sol";
contract TimeTest{
uint256 public initialTime;
constructor () public{
initialTime = block.timestamp;
}
function withdraw() public {
uint256 nowTime = block.timestamp-initialTime; // time between deployment of contract and now.
console.log(nowTime);
if (nowTime > 60) {
console.log("Time is up");
}
}
}
The reason why you have to do that is because block.timestamp doesnt represent the time since the contract was deployed, but the time since the unix epoch. The name of the variable is a little misleading.
You can find more info here: https://docs.soliditylang.org/en/v0.8.13/units-and-global-variables.html
Or here:https://programtheblockchain.com/posts/2018/01/12/writing-a-contract-that-handles-time/ (just know that "now" doesnt exist anymore since version 0.0.7. "now" was equivalent to "block.timestamp". But the tutorial is still valid if you replace "now" with "block.timestamp".

Unable to retrieve right values

I am unable to retrieve values on this code.
//SPDX-License-Identifier: GPL-3.0
pragma solidity 0.8.1;
contract Storage{
int number;
function storePositive(int256 nump) public{
number = nump;
}
function storeNegative(int256 numn) public{
number = -numn;
}
function retreivep() public view returns(int256){
return number;
}
function retreiven() public view returns(int256){
return number;
}
}
I am trying to retrieve separate values for positive and negative numbers stored. All it is showing me is
0:int256: 0 on both retrievep and retrieven.
P.S. This is my first ever Solidity code, so please explain on an elementary level.

What is the best approach in Solidity for pagination (straightforward and based on some filter(s)) capabilities?

Let's suppose that we have following structures in Solidity contract :
struct EntityA {
string lessThen32ByteString1;
string moreThen32ByteString1;
string lessThen32ByteString2;
string moreThen32ByteString3;
bool flag;
uint var1;
uint var2;
uint var3;
uint var4;
ProposalStatus proposalStatus;}
// 100K entities EntityA[] public items;
We have now following implementation (with helper functions for string to byte32 conversion, splitting string to a few byte32 parts and so on) :
function getChunkOfPart1EntityADetails(uint filterAsUint, uint offset, uint limit) public constant
returns (bytes32[100] lessThen32ByteString1Arr, bytes32[100] moreThen32ByteString1PrefixArr, bytes32[100] moreThen32ByteString1SuffixArr) {
}
function getChunkOfPart2EntityADetails(uint filterAsUint, uint offset, uint limit) public constant
returns (bytes32[100] lessThen32ByteString2Arr, bytes32[100] moreThen32ByteString2PrefixArr, bytes32[100] moreThen32ByteString2SuffixArr) {
}
function getChunkOfPart3EntityADetails(uint filterAsUint, uint offset, uint limit) public constant
returns (bool[100] flagArr, uint[100] var1Arr, uint[100] var2Arr, uint[100] var3Arr, uint[100] var4Arr, ProposalStatus[100] proposalStatusArr,) {
}
Current implementation does not look good from design perspective, furthermore each additional filter support requires contract changes due to absence any query language support.
Use case example : retrieve 10 entities based on specified proposalStatus and offset 50 (6th page, page size is 10 entities (maybe 20, 50, 100))
I know I'm late but here you go. This will return an array of uints. You can then use this array on the client to resolve the id's in the getter for the array that stores your data.
struct Zombie {
//data
};
Zombie[] public zombies;
function paginateAllZombies(uint _resultsPerPage, uint _page) external view returns (uint[]) {
Zombie[] memory result = new Zombie[](_resultsPerPage);
for(uint i = _resultsPerPage * _page - _resultsPerPage; i < _resultsPerPage * _page; i++ ){
result[i] = i;
} //CONVERT TO SAFEMATH
return result;
}
So once you get this returned you can .map() the result in your client app and call zombies(uint _index).
If you need more details on this approach please check out cryptozombies.io
Not sure if this is the best approach though.
Hopefully in the future you can just do:
function paginateAllZombies(uint _resultsPerPage, uint _page) external view returns (Zombie[]) {
uint[] memory result = new uint[](_resultsPerPage);
for(uint i = _resultsPerPage * _page - _resultsPerPage; i < _resultsPerPage * _page; i++ ){
result[i] = zombies[i];
} //CONVERT TO SAFEMATH
return result;
}