External Contracts & Calls Discussion

Welcome to the discussion thread about this lecture section. Here you can feel free to discuss the topic at hand and ask questions.

1 Like

First! Sorry, old habits lol.

So I was reading some of the Solidity recommendations on smart contract best practices from the Consensys github, and they recommend avoiding .send() and .transfer() because the 2300 gas stipend is only effective if gas costs are assumed to be constant. They continue:

Recently EIP 1283 (backed out of the Constantinople hard fork at the last minute) and EIP 1884 (expected to arrive in the Istanbul hard fork) have shown this assumption to be invalid.

To avoid things breaking when gas costs change in the future, it’s best to use .call.value(amount)("") instead.

Here’s the link to the page where I was reading it. What is your opinion on the matter?

As someone still learning Solidity, would it be better to continue using .transfer() or .send() until these gas cost changes are confirmed? Or should I try to become more familiar with .call.value(amount)("") since it seems inevitable this will be more applicable in production?

1 Like

Hey, thanks for sharing that. Interesting changes for sure. But I would think that they would adjust the 2300 gas stipend to still be safe in such a hard fork, but perhaps not.

It could be dangerous for some contracts out there. But, you will still be safe using send() or transfer() if you design your contract after the principle of checks-effects-interaction (which we teach). If you do that, even if the 2300 gas stipend would suddenly be enough for another call, you would be safe from re-entrency. But it’s definitely something worth keeping track of :slight_smile:

2 Likes

Agreed, very interesting. Always something new in this space. I’m very excited to see what January brings.:joy:

1 Like

Hi, about push & pull. The other advantage I see on pull is giving flexibility to the user, so if for example its a bet game… he could decide to withdraw when he gets to 1 eth… or withdraw a part and let the other. If its a micropayments systems between 2 smartcontracs this will avoid all the micropayment fees, and will only withdraw in significant chunks of the total amount

1 Like

Re-entry attacks

Even if you set the user balance to zero before sending funds in the withdrawAll function, if an attacker can make many simultaneous calls in parallel would it still be possible to multi-withdraw before the state balance change is seen by parallel calls? Multi-threading can be nasty. This is why locks and atomicity are so important in traditional databases. Is this a concern with smart contracts?

filip, is it possible for someone to make a contract that completely ignores this effects code and just transfer the funds and restart the function?

Ignores this code in the contract?
balances[msg.sender]= 0;

It won’t because at the end all your transaction will be validate in one block.
So let’s say tx 1 to 10 are broadcasted.
Miner 1 takes 1/2/3
Miner 2 takes 4-10
If miner 1 validate the block he will execute your functions and deduces 1 / 2 and 3 if their is no funds for the third transaction it ll be reverted.
Regarding tx 4-10 they will be validated at the next block.

https://github.com/ethereum/wiki/wiki/What-is-Ethereum
Ethereum can be viewed as a single computer that the whole world can use. It notionally has only a single processor (no multi-threading or parallel execution),
Even if you mutli-thread you can still implement locks to only allow one thread at a time to modify a variable

1 Like

Hi @andersbraath1
I m not sure to understand your function , but basically a contract A can’t modify the content of contract B

1 Like