pragma solidity ^0.4.24;
contract setget{
uint x;
function setnumber(uint _x) public {
x=_x;
}
function getnumber() public view returns(uint){
return x;
}
}
1 Answer
Both, uint
and int
are 256-bit long in Solidity, so arbitrary sequence of 256 bits may be interpreted in both ways. For example, sequence of 256 "ones" is -1
when interpreted as int
, and is 115792089237316195423570985008687907853269984665640564039457584007913129639935
when interpreted as uint
.
I assume you are passing negative value to your function via Web3 API. Your Web3 API implementation does not do range check. It just converts your negative number into a 256-bit sequence and passes it to your smart contract, and smart contract just interprets it as uint
.
There is no reliable way for smart contract to know whether particular 256-bit sequence passed to it was initially representing int
or uint
. Though, one thing may probably help. The idea is that positive numbers have the same binary representation for both types, so in case value you got is less than or equals to maximum possible int
value, then it has never been negative. So you may add the following line to the beginning of your method:
require (_x <= 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF);
unsigned
in the on-chain side, using 2s-complement. 4. If you call it from the on-chain, then you're likely to get a compilation error, or at least a compilation warning, but in either case - not a runtime exception.uint
, so you'll need to add this assertion on the caller side, not in this function. Or you can useint
instead ofuint
, and thenrequire(_x>0)
will become useful. You'll also need to changex=_x
tox=uint(_x)
.