Solidity Error Handling

If anyone wanna try a “Assert” error, can try with this function that i do :

Note : The “assert” is run when some conditions are not expected that could be,
in this case if i have 1 and subtract 1 the expected ( in assert ) is 0, but if i put 1, the
error go be executed because that is not true, this is only for test, in real cases
i think this is a good practice for the most functions, because if somebody wants to hack the function and has the assert … the transaction fails, is not the best for security but solve some cases for unexpected things :slight_smile:

sorry for my bad english, i hope anyone can understand :slight_smile: :heart:

function test() public {
        
        uint256 have = 1;
        uint256 sub = 1;

        assert(have - sub == 1);

}
2 Likes

Asserts are very useful to validate an expected behavior of an operation, but in this case, the validation is not true.

1 - 1 = 0, so the assert will fail because that condition is not true. The expected behavior is 0.

Carlos Z

2 Likes

Hey @ismael_zamora,

Yes… because the condition in assert() should always be true, we can’t actually demonstrate an example of assert() failing unless we “force” the condition to do the opposite… which is what your function does, and you’ve explained its purpose nicely :ok_hand:

I would say that assert() is more definite than that, and that it checks for conditions that will never occur, unless our code fundamentally fails to do what it’s been designed to do. This is what’s called an invariance.

Rather than being used to prevent attacks aimed at manipulating weaknesses, ambiguities and/or bugs in how the smart contract code has been written, the job of assert() is more to prevent a catastrophic failure in the code’s own environment, in its “fundamental laws” so to speak.

In terms of when to use it, we need to consider what the consequences of such a fundamental failure would actually be, and weigh that up against the additional cost of gas to execute it.

It’s important to realise that certain attacks could still succeed whether or not there is an assert() statement. So, it’s also important to consider other smart-contract security measures, and not just to rely on assert(). You’ll learn about some of these other security measures later on :slight_smile:

2 Likes

I am getting type error - Operator not compatible.

Hi Filip, In require function I am getting the error " operator not compatible" please take a look at it.

pragma solidity 0.8.13;

contract HelloBank{

    mapping(address => uint)balance;
    address owner;
    constructor()
    {
         owner = msg.sender;
    }
    modifier onlyOwner(){

        require(owner == msg.sender);
        _;// run the function
    }

    function addBalance(uint _amt) public onlyOwner {

        balance[msg.sender]+=_amt;
    }

    function getbalance() public view returns(uint)
    {
        return balance[msg.sender];
    }

    function transfer(address recpt, uint _amount) public {
        **require(balance[msg.sender >= _amount], "Insufficient Balance");**
        require(msg.sender != recpt);
        uint prevBalance = balance[msg.sender];
        _transfer(msg.sender,recpt,_amount);
        assert(prevBalance == balance[msg.sender]- _amount);
    }

    function _transfer(address from, address to, uint _amount) private {

        balance[from] -= _amount;
        balance[to] += _amount;

    }
}

Hi @Gaurav_Sahoo,

Your condition in the require statement needs to compare the caller’s balance in the mapping…

balance[msg.sender]

with the transfer amount …

_amount

So, the error is caused by the incorrect position of the closing square barackets …

require(balance[msg.sender] >= _amount, "Insufficient Balance");

Once you’ve corrected the require() statement and deployed and tested your contract, you will find that when the transfer() function is called, the assert() statement is failing when it shouldn’t.

Your code is saying that the SENDER’S previous balance should be equal to their updated balance (after the transfer) LESS the amount transferred. So this will never evaluate to true. Can you see why, and then correct it?

Just let me know if you have any questions.

Hey there,

I am currently watching the “require” lecture, and I have a small question: In the lecture, you set owner address by using a constructor and setting the owner variable to msg.sender.
why is it that we have to create a constructor to set the owner address to msg.sender?
and why can’t we just set it on the same line as you set the owner variable?

Thank you,
-Bogdan Manzar

1 Like

You can set the owner in both ways, either in constructor, or with address owner = msg.sender;
Constructor is optional, it is just a way to set state variable that you can´t change later. It depends on your needs, whether you want modifiable or immutable values.

1 Like

The constructor will execute only one time, when the contract is deployed, there you can specify all the initialization arguments that the contract needs to execute itself properly (like who is the owner of this contract, and other stuffs like access control that you will see later in Smart Contract 201)

So in order to specify the owner of the contract, its assigned in the constructor, where msg.sender is the account that execute the contract (at this moment, msg.sender is the deployer of the contract).

You could assign an address directly in the variable declaration.

Like:

address owner = "0x0asdsad...";

It also might work, but if you want to assign the deployer (which ever address might be), its easier to just use the constructor and pass the msg.sender as the owner.

Carlos Z

Hi, can I use a pay modifier to request an ERC token to be used to pay with or instead of ETH?