why solidity function returns always false even if it should returns true? - solidity

Here is my problem. I have a contract in solidity :
contract test {
function testfunc(uint _number) external pure returns (bool) {
return _number >= 0;
}
}
Here is example :
This function retuns always false, even if I set a positive number... why ? it's not logic...
Do you have an explanation ?
Thanks for all,
Regards,

it is returning true, try to redeploy the contract.

Related

Testing ChainlinkClient callbacks - how to bypass recordChainlinkFulfillment?

I've got a Chainlink client contract which makes a DirectRequest to an oracle. The oracle does its thing and then returns the answer via the typical callback selector passed in via the ChainlinkRequest. It all works well, but I'd like to write some tests that test the callback implementation
My client contract is as follows:
contract PriceFeed is Ownable, ChainlinkClient {
function updatePrice() onlyOwner returns (bytes32 requestId) {
// makes Chainlink request specifying callback via this.requestCallback.selector
}
function requestCallback(bytes32 _requestId, uint256 _newPrice) public
recordChainlinkFulfillment(_requestId) {
price = _newPrice;
}
}
The problem arises when the test code calls requestCallback(...) and the code hits the recordChainlinkFulfillment(...) modifier. The ChainlinkClient complains that the requestId being passed in by the test below isn't in the underling private pendingRequests mapping maintained by the ChainlinkClient.
The simplified version of ChainlinkClient looks like this:
contract ChainlinkClient {
mapping(bytes32 => address) private pendingRequests;
modifier recordChainlinkFulfillment(bytes32 _requestId) {
require(msg.sender == pendingRequests[_requestId], "Source must be the oracle of the request");
delete pendingRequests[_requestId];
emit ChainlinkFulfilled(_requestId);
_;
}
}
My Foundry/Solidity test is as follows:
contract PriceFeedTest is Test {
function testInitialCallback() public {
priceFeed.requestCallback("abc123", 1000000); // fails on this line
assertEq(1000000, priceFeed.price(), "Expecting price to be 1000000");
}
}
The code fails on first line of the testInitialCallback() line with: Source must be the oracle of the request
How can I trick the ChainklinkClient into allowing my callback to get past the modifier check? AFAIK I can't access and pre-populate the private pendingRequests mapping. Is there another way?
I know that Foundry provides Cheatcodes to help in testing and there's a stdstorage cheatcode, but I'm not familiar on how to construct a call to stdstorage to override pendingRequests if thats even possible with a cheatcode.
contract PriceFeedTest is Test {
function testInitialCallback2() public {
stdstore
.target(address(priceFeed))
.sig("pendingRequests()")
.with_key("abc123")
.checked_write(address(this));
priceFeed.requestCallback("abc123", 1000000);
assertEq(1000000, priceFeed.price(), "Expecting price to be 1000000");
}
}
The above code throws the following error: No storage use detected for target
Any help would be greatly appreciated. Many thanks.
When you execute the updatePrice function in your test, you should be able to strip out the requestId from the transaction receipt event. Once you have that, you can then use it in your call to requestCallback. Check out this example unit test from the hardhat starter kit for an example of this

How can I delete an element from a nested mapping

I have a nested mapping that goes from address to planId to struct(subscription)
mapping(address => mapping(uint => subscription)) public subscriptions
I have a function to cancel a specific plan that has been created but when I trigger the function I got an error that says
The transaction ran out of gas. Please increase the Gas Limit.
When I debugged the error the debugger points the error inside the cancel function at the code line below
function cancel(uint planId) external {
Subscription storage subscription = subscriptions[msg.sender][planId];
require(
subscription.subscriber != address(0),
'this subscription does not exist'
);
delete subscriptions[msg.sender][planId]; // this one
emit SubscriptionCancelled(msg.sender, planId, block.timestamp);
}
How can I fix that error?
Thanks
I am facing a similar problem. Here's what I did, I realized that it's not possible to assign a default value to a nested mapping once you change it.
In your example, you can try assigning a struct with different values(which you can consider as a replacement for default) and then it wont throw error.
Following is my example:
// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.8.0;
contract test{
mapping(address=> mapping(uint => uint)) public address_id_liked;
function register(uint id) external{
address_id_liked[msg.sender][id] = 1;
}
function test_(uint index) external view returns(uint) {
uint out = address_id_liked[msg.sender][index];
return(out);
}
function ops(uint id, uint num) external {
address_id_liked[msg.sender][id] = num;
}
}
In the ops function, I wanted my mapping to have a default value but it's not happening. So I tried inputting the value which I want to assign to nested mapping. And it's taking all uint values except 0(the default)
P.S- I was using mapping(address=> mapping(uint => bool)) public address_id_liked previously. But I am unable to delete/assign false, hence I tried with uint.
Hope this helps!

Don't Understand the Compiler

There's something I don't understand. I am getting confused about the cursor of the compilor and where it goes upon certain function calls. Here is an example:
pragma solidity 0.8.7;
contract Example {
function f1() public returns(uint) {
uint output1 = 1;
f2();
return output1;
}
function f2() private returns(uint) {
uint output2 = 2;
return output2;
}
}
This contract runs a function f1, whcih simply calls another function f2, and outputs a variable's value.
Now, I always thought that it was the first return statement which the compiler reads that will be outputted to the user (in this case, I thought output2 would be emitted). However, for some reason that I don't understand, output1 is emitted.
Could someone explain to me how the compiler reads this and why the output is the way it is in this case, please?

Is this a remix,compiler or an openzeplin bug?

I just wrote a simple code to test openzeplin Safemath library. I am using the latest version of remix ide and compiling for ^0.5.0.
Remix is using 0.5.0_commit.1d4f565a compiler
The environment is JavaScript VM
EVM Version is the compiler default
The add function does not seem to be working in the code given below
I have tried x.sub(1) it throws an exception as expected, i have also tried initializing x to different values but still does not work.
pragma solidity ^0.5.0;
import "./SafeMath.sol";
contract SimpleStorage {
using SafeMath for uint;
uint x;
event incremented(uint x);
constructor() public{
x=0;
}
function increment() public {
x.add(1);
emit incremented(x);
}
function get() external view returns (uint) {
return x;
}
}
Expected output is an increment by one on every call to the function but getting the same value every time. Emit also shows the same value.
Well, it's your bug :)
Instead of x.add(1) try x = x.add(1). Add function is not inplace, new value is returned and you need to assign the new value to x.

eth.call on web3 interface returns null value for contract function returning array of bytes32/strings

I am trying to run a bidding smart contract on a private blockchain and my smart contract is working on the Remix IDE and the same works on my private chain except for one function [dataOwnedBy()] which is suposed to return an array of bytes32 but returns all zero values in geth console.
I have compiled and deployed my smart contract using truffle.
The function which is not working is : (along with data declaration snippet and other function prototypes)
struct data{
bytes32 data_id;
address bidder;
uint bid;
}
mapping(bytes32=>data) bidInfo;
mapping(address=>data[]) dataOwned; //data owned by each address
address[] dataOwners; //list of address who own data
function Bid(bytes32 data_id) public payable { ... }
function closeBid(bytes32 data_id) public { ... }
function whoOwns(bytes32 _data_id) constant public returns (address){ ... }
function dataOwnedBy(address _addr) constant public returns (bytes32[10]){
uint length = dataOwned[_addr].length;
bytes32[10] memory _idArray;
for (uint i=0;i<length;i++){
_idArray[i] = (dataOwned[_addr][i].data_id);
}
return _idArray;
}
After closing the bid, when I query the above function with the winner's address, it returns array of size 10 bytes32 values, all equal to zero, where it should be returning the data_ids owned by the address.!
Version Information from console
> web3.version.api
"0.20.1"
truffle(development)> version
Truffle v3.4.11 (core: 3.4.11)
Solidity v0.4.15 (solc-js)
This is the console output :
playbid.whoOwns("data_id1")
"0x7d8eb703bd863313325b784ac35017614484f2e7"
playbid.dataOwnedBy("0x7d8eb703bd863313325b784ac35017614484f2e7")
["0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000"]
Instead the first value of the array should be the hex of "data_id1".
Don't know what is going wrong here, but it works perfectly fine on Remix IDE.
Thanks in advance !
As your code is working OK in remix, there is no problem with the smart contract code. I experienced same issue when I wanted to return some arrays back to my web3j powered java app. I also tested web3js and encountered the same problem. The returned array was broken the same way.
I ended up in serializing and deserializing arrays to strings with a delimiter, both in inputs and outputs.