Solidity Error Handling

Welcome to the forum discussion for this section. Here you can ask questions or post feedback.

3 Likes

Hi Filip,

can you please take a look of the screenshot I have?
I do not know why there is an error, I think it looks fine…

Thank you very much for your help!

You need to specify what type the functions returns.

When you write ‘returns’ you need to write for example returns (uint) or returns (string).

That’s why it says it expects a ‘(’.

6 Likes

filip nobody can read your code this lesson thing on the side messes up everythig please fix this this is so annoying if i have to learn something but i cant even see everything thats going on

and please make sure all your links open in a new window

3 Likes

im able to delete all persons when i use the contract creator function

If i deploy contract using this address
//0xCA35b7d915458EF540aDe6068dFe2F44E8fa733c i can also delete
the person that was created using this address
//0x4B0897b0513fdC7C541B6d9D7E929C4e5364D2dB

I understand that it can be annoying. Some people like large text so that they can have the video in a small window next to the code, so I’ve been getting tons of messages telling me to increase the font.

That unfortunately leads to all code not being on the screen at the same time.

2 Likes

I’m not sure I understand the problem. Could you clarify the issue and attach your code so I can have a look?

i found a work around and look at the code you posted on github i didnt see that earlier, im much slower than you and if i follow you i cant keep up right away so you already far ahead and im stll trying to write the code but than all of a sudden there is only half of the code on the screen, well anyways like i said i just use the github code as reference

but please make sure you have links opened in a new window

oh and regarding the code
i first thought that only the msg.sender can delete the code but also the contract creator can delete the records

Ok, I see.

To clarify about the owner and msg.sender. Msg.sender changes all the time. Anyone can be msg.sender. It’s the current caller of the function. The owner is one specific address. That’s why we check if msg.sender == owner in the delete function, so that only the owner is able to delete people. Does that make sense? :slight_smile:

3 Likes

The example used for assert concerns me, or at least brings up a question. Before watching the video, I hadn’t realized that we need to do checks to ensure that the final balance after a simple subtraction operation is required, but that’s okay, it’s good to be safe. However, what does this mean in terms of concurrent operations on the same account? What if two different actions on the blockchain result in two different smart contracts executing on the same account? It’s very possible that one subtracts tokens and checks, while the other adds tokens and checks. If so, then both operations will likely fail due to the assert, which is a good thing.

Therefore, my question is, is there something in Ethereum programming that’s equivalent to a semaphore? I have no idea how this could work, or if you’d even want this to work! Can someone please explain the problem involved in implementing something like this, as well as why you might not even want this?

Great question! Actually, there can be no concurrent operation on a smart contracts. There is an absolute ordering of transactions that are decided by the miners (unless there are forks/orphans etc). So state changes in a contract happens on a transaction by transaction basis, and that ordering is done by the miners keeping track of the blockchain. Does that make sense? :slight_smile:

In other words, smart contracts and blockchains are basically distributed state machines.

3 Likes

I’m glad someone mentioned this! It’s extremely annoying and frustrating. Makes it way harder to process the lessons. It’s very easy to have the videos on another device / screen / browser tab while you’re coding.

1 Like

I’m sorry to hear that. It seems like people have different opinions on this. Maybe it’s a split between those having a secondary screen and those who do not. I’ll try to find a better way next time!

2 Likes

I just finished the Error Handling category and have some questions:

I’m kinda confused about assert().
As far as I understood it, basically every function has a invariant/invariants.

Should I declare the asserts for every function then?
Or should I think about which functions are so important, that I have to be sure they run 100% clean, so they don’t mess around with important information and declare the assert() to only those?
If so, how do I decide whether a function is more important than the other?

Are the examples in the coding lessons where we used assert() trivial? Like, would you seriously use assert in that kind of context, where we were sure our code works for 99%?

1 Like

I don’t use assert often, but i think it s a good idea to use assert after a token transfert or when you are adding our subtracting internal value. Just to make sure there is now flow in your program.
Some function can look trivial but someone can find a way to exploit it and if their is an assert at the end of your function to make sure everything append as attended the state of your contract will be revert at his initial state and you will keep the gas for your contract (anyway someone tried to hack you so let s keep his gas :slight_smile: )

5 Likes

Hey guys! Can someone explain why assert() takes all the gas (or more gas than require() ) in a contract? Thanks a lot

1 Like

Doesn’t an “if” does the same function as a “require”. Why are there 2 ways of checking if the following code should be executed?

1 Like

Hi @pedromndias
Assert and require are taking all the gas but require send back the gas used if the requirement fail. This is just an implementation of the function for a different use case

2 Likes

Hi @pmk

No because require revert the transaction and send you back your ether. If the if failed the transaction will be validate and store in the blockchain

2 Likes

@gabba, @pedromndias, @filip

I’m confused about what’s happening with these gas costs…

I’ve experimented with the deletePerson function in the contract from the videos, to see what the gas effect is in 3 scenarios:

  1. function executed successfully
  2. require() triggered
  3. assert() triggered

I’m not really sure about the differences between the 3 gas figures that are displayed within the transaction details when you click on the arrow next to Debug :

  • gas — this seems to always be the gas limit (default set at 3,000,000 I think);
  • transaction cost — I’ve managed to work out that this is the amount of ETH deducted from the account which executes the function;
  • execution cost — not exactly sure what this is, and how and why it’s different to the transaction cost???

SCENARIO 1

I got the following result when using the owner’s account to delete a person successfully:
transaction cost   24,246
execution cost     25,812
Why are these gas figures different?

SCENARIO 2

I got the following result when using a non-owner’s account to try to delete a person with exactly the same property values as in scenario 1 — this triggers require()
transaction cost   23,873
execution cost     1,193
My understanding is that when require() is triggered, the gas cost is refunded, and I assume this is because the function doesn’t continue executing to the end, due to required() being triggered in the 1st line causing the function to be exited at that point. Is that correct?
Is this why the execution cost of 1,193 is much less than in scenario 1?
However, where can I see this refund or lower execution cost actually reflected in the ETH account balances? The transaction cost of 23,873 (the amount of ETH actually deducted from the caller’s account balance) is almost as high as that of the successful transaction in scenario 1, which didn’t revert. I don’t really understand what’s going on here with these figures…

SCENARIO 3

I got the following result when using the owner’s account to try to delete a person with exactly the same property values as in scenario 1, but with an invariant set so that assert() is deliberately triggered.
transaction cost   3,000,000
execution cost     2,977,320
The answer to one of the quiz questions is:
 assert(false) will consume all of the remaining gas in a function call
Does that mean that whenever assert() is triggered, the gas cost will always be as high as the gas limit set? Is that why the transaction cost is much greater than with the successful function call in scenario 1, because I left the gas limit as the default of 3,000,000?
Why is the execution cost slightly lower than the transaction cost, though?
What exactly do we mean by remaining gas? Is this the difference between the gas limit set and the gas cost of a successfully executed function call? …the difference between the transaction and execution costs? …or something else? :thinking:

2 Likes