Solidity: Why does a faulty input set my boolean to "true"? - boolean

I'm using remix.ethereum.org
I wrote this very simple smart contract:
pragma solidity ^0.4.19;
contract TicTacToe {
bool myBool = false;
uint8 myUint8;
uint256 myUint256;
string myString = "myString";
bytes myBytes = "myString";
function setMyBoolean(bool myBoolArgument) public {
myBool = myBoolArgument;
}
function getMyBoolean() public view returns(bool) {
return myBool;
}
}
As you can see the default value for myBool is false
I can change this by calling the function setMyBoolean.
If I use this argument and type in true, myBool will be set to true
If I use this argument and type in false, myBool will be set to false
But if I type in any other combination of letters, myBool will be set to true as well. This surprises me because the default setting for myBool is false.
Why does this happen?

It's working as intended because this is the way that remix and abi encoder decided to handle booleans
// "false" will be converting to `false` and "true" will be working
// fine as abiCoder assume anything in quotes as `true`
if (type === 'bool' && args[i] === 'false') {
args[i] = false
}
https://github.com/ethereum/remix/blob/807ffd9772b07dafb343c08faf44c78ee456de77/remix-lib/src/execution/txHelper.js#L18

I assume that the value input is evaluated as as a string and, as the string exists and It Is not empty, It Is evaluated as true.

Related

How to take input in swift

I was trying to get Boolean data with readLine()! but cannot input it
There was a compilation error saying
error: cannot convert value of type 'String' to specified type 'Bool'
readLine() returns a String?. You cannot implicitly convert a String to Bool.
Swift does not know what strings you consider to be a valid boolean value. Are 0 and 1 considered boolean values by your app? no and yes? falsch and wahr? Swift does not know. You need to parse it yourself, for example:
let myBool: Bool
switch stringInput.lowercased() {
case "false", "no", "0": myBool = false
case "true", "yes", "1": myBool = true
default:
print("Invalid input")
return
}
print(myBool)

What is the default value of a basic Boolean in Swift?

I want to know about Bool in Swift.
If Bool is a basic primitive datatype, why is a Boolean's default value nil?
var test: Bool!
print(test) // nil
In Java the Boolean default value is false:
Default value of 'boolean' and 'Boolean' in Java
Bool, Bool! and Bool? all are different in Swift.
1. Bool is a non-optional data type that can have values - true/false. You need to initialize it in the initializer or while declaring it before using it.
var x : Bool = false
var x: Bool
init()
{
x = false
}
2. Bool? is an optional data type that can have values - nil/true/false. In order to use this type, you need to unwrap it using if let or force unwrapping.
var x: Bool?
if let value = x
{
//TODO: use value instead of x
}
3. Bool! is an implicitly unwrapped optional data type that can have values - nil/true/false. The difference here is it must contain a value before using it else it will result in runtime exception. Since it is implicitly unwrapped, no need to unwrap it using if let or force unwrapping.
var x: Bool! //Must contain value before using
Strictly spoken there is no default value in Swift.
Either the Bool is non-optional then you have to assign a (default) value
or if the Bool is an optional, then it is nil – which is no value in terms of Swift.
Bool in Swift is not a primitive. Everything in Swift are objects. Your variable test is a Bool!, which is an implicitly unwrapped optional and the default value is nil.
If you use this code (not an optional),
var test: Bool
print(test)
You will get an error:
variable 'test' used before being initialized
So in Swift you have to initialize stuff before you use it, for example:
var test: Bool = false

Bool in swift - playgrounds

I'm Learning swift using playgrounds. Can I declare a bool and have it be only true or false so I can use it as a condition for a function?
Simply writing:
var boolean = true
will create a boolean named 'boolean' and will be equal to true.
You can change it's value to false by writing
boolean = false
later on. The boolean variable will be true or false, not at the same time. I don't wanna be rude but you should check simple variable types and learn from there. It's easier that way.
You can declare a Boolean variable using "Bool" type annotation . For Example
var boolean = false
or
var boolean = Bool()
if you want to use in an if else condition . you can do like that
if boolean == true {
// Statements
}
Here , boolean is variable name .You can take any variable name.

Swift Boolean checking

So in Objective-C when using Booleans it's possible, and encouraged, to write code using a variable's non-zero value as it's boolean value, which means you can write code like this:
if (someBool) {
// Stuff
}
Also, there are reasons why code like the following is discouraged:
if (someBool == YES) {
// Might run into problems here
}
The reasons why checking a boolean against another boolean are better explained here, but briefly the issue is just that when you're comparing equality to YES or NO directly, you're actually comparing against 1 and 0, respectively. Since Objective-C allows for using non-zero values as a truth value, you could end up comparing something that should be considered true against YES and have the expression resolve to NO, e.g.
int trueNumber = 2;
if (trueNumber == YES) {
// Doesn't run because trueNumber != 1
}
Is this still an issue in Swift? Code style issues aside, if I see something like the following
var someBool = true
if someBool == true {
// stuff
}
is that going to be an issue, or does it not really matter? Are these C-style comparisons still happening under the hood, or is there something built into the Swift BooleanType that prevents these issues?
The if <something> {} structure in Swift requires the <something> to conform to the BooleanType protocol which is defined like this:
public protocol BooleanType {
/// The value of `self`, expressed as a `Bool`.
public var boolValue: Bool { get }
}
If the type doesn't conform to this protocol, a compile-time error is thrown. If you search for this protocol in the standard library you find that the only type that conforms to this protocol is Bool itself. Bool is a type that can either be true or false. Don't think of it as the number 1 or 0, but rather as On/Off Right/Wrong.
Now this protocol can be conformed to by any nominal type you want, e.g.:
extension Int : BooleanType {
public var boolValue : Bool {
return self > 0
}
}
Now if you do this (you shouldn't honestly), you're defining it by yourself what "True" and "False" means. Now you'd be able to use it like this (again, don't do this):
if 0 {
...
}
Swift has Bool type. This is different from objective-c's BOOL which is not actual type. It is actually typedef unsigned char. When swift expects Bool you have to give it Bool otherwise it is compile error. The following code will not compile because check is not Bool
let check = 2
if check {
}
But this will work because == returns Bool
let check = 2
if check == 2 {
}
To understand the ObjC style, you need to go back to C. In C, this statement:
if (something) {
// Do something
}
will evaluate to false if something is null or 0. Everything else evaluate to true. The problem is C doesn't have a boolean type. Objective-C added YES and NO which is basically 1 and 0. So:
if (aBoolValue == YES) { } // Work as expected
if (anIntValue == YES) { } // False unless anIntValue == 1
The "discouraged" recommendation was to align with the behaviour in C. Swift has no such backward compatibility requirements. You can't write these:
if anIntValue { } // Syntax error
if anObject { } // Syntax error
Instead, the expression must evaluate to a boolean value:
if anIntValue != 0 { } // Ok
if anObject != nil { } // Ok

The implicit unwrapping of an optional boolean

The implicit unwrapping of a Bool type does not seem to work:
var aBoolean: Bool! // nil
aBoolean = false // false
aBoolean // false
aBoolean == true // false
aBoolean == false // true
if aBoolean {
"Hum..." // "Hum..."
} else {
"Normal"
}
if aBoolean! {
"Hum..."
} else {
"Normal" // "Normal"
}
If I had declared aBoolean like var aBoolean: Bool?, this would have been the expected behavior but here, I don't get it.
Is this the correct behavior? I didn't find any doc about it.
Thanks!
The first test is checking whether aBoolean stores a value rather than nil, which it does:
if aBoolean {
"Hum..." // "Hum..."
else {
"Normal"
}
The second test is checking against the actual boolean value stored in aBoolean, which is false:
if aBoolean! {
"Hum..."
} else {
"Normal" // "Normal"
}
This is Illustrated in the Swift book in the "Implicitly Wrapped Optionals" section. I think the implicit unwrapping just doesn't apply with if-statements. I agree it is strange but here is the Apple example:
You can still treat an implicitly unwrapped optional like a normal optional, to check if it contains a value:
let assumedString: String! = "An implicitly unwrapped optional string."
if assumedString {
println(assumedString)
}
// prints "An implicitly unwrapped optional string."
Excerpt From: Apple Inc. “The Swift Programming Language.” iBooks. https://itun.es/us/jEUH0.l
Not an answer, but if this is indeed the intended behavior with implicitly unwrapped booleans it's rather disturbing. As soon as you use the expression in any logic proposition it will get unwrapped:
var aBoolean: Bool! = false
if !aBoolean {
"I'm unwrapping" // "I'm unwrapping"
}
if aBoolean == false {
"I'm unwrapping" // "I'm unwrapping"
}
Say you have this in your code an at some point your model changes and the condition is reversed, you delete the NOT.
if aBoolean {
"I'm unwrapping" // <- ouch
}
You just got screwed. Makes me want to avoid the implicit unwrapping.
You are making two different truth-checks.
Given:
var aBoolean: Bool! // nil
aBoolean = false // false
if aBoolean {
"Hum..." // "Hum..."
else {
"Normal"
}
if aBoolean! {
"Hum..."
} else {
"Normal" // "Normal"
}
...in the first if aBoolean, the value is not being unwrapped, it is simply testing the optional type to determine if it stores a value.
In the second if aBoolean!, you are testing the truth-value of the unwrapped Bool.
To see that it is indeed being implicitly-unwrapped (when not used in a conditional), try:
println("value of implicitly-unwrapped aBoolean: \(aBoolean)")
...this will print 'true' when aBoolean is set to true, 'false' when it is set to false, and 'nil' when it has not yet been assigned.
Here is the behavior clearly shown:
> var bool1 : Bool!
bool1: Bool! = nil
> bool1 = false
> (bool1 ? "yes" : "no")
$R19: (String) = "yes"
In the above, since bool1 is an optional (which becomes a Some instance), the conditional of simply bool1 evaluates to true (it is not nil).
> var bool2 : Bool = false
bool2: Bool = false
> (bool2 ? "yes" : "no")
$R25: (String) = "no"
When bool2 is not an optional, the conditional of simply bool2 evaluates to false (the value of bool2)
When declaring a variable as "implicitly unwrapped", using the !, it is still an Optional
This type of variable behaves very much like the standard variable type in Objective-C. It can be assigned to nil, but when you access members you do not need to explicitly unwrap it. In this way it is "unsafe" just like in ObjC because you can be accessing properties from nil
Thus, it is used most commonly when bridging from Objective-C. However, it is still an optional, with the only difference being you don't need to unwrap it to access the contents.
I believe this was added mostly to support interop between Swift and Obj-C and might be good practice to sparingly use it in pure Swift code. (Swift guidelines are a fuzzy thing right now and someone might prove me wrong soon!)