Web3 Dapps Vs Web2 Webapps

key implementation differences

Alberto Molina
Coinmonks
Published in
8 min readJun 2, 2022

--

Web3 seems to be gaining more and more traction and many web2 developers and jumping on the train. As you probably know, the main difference between web3 and web2 is that web3 is powered by decentralized, public blockchains as opposed to the centralized, private servers used in web2.

When I started to learn about web3 myself I noticed some key differences in the way web applications had to be designed and implemented, some of them might be obvious but others not so much.

The new web3 implementation paradigm is not just a challenge to newbies, it is also the main reason why web3 is so interesting and attractive (at least to me) which is why I decided to put together a list of “things to keep in mind when designing your firsts web3 Dapps” that I believe can be useful for beginners looking forward to joining the web3 industry.

  • Application architecture
  • Application lifecycle
  • Application maintenance
  • Data visibility
  • Application execution
  • Execution costs
  • Long executions (loops)
  • User authentication
  • Logging
  • Admin rights
  • Systems upgrades
  • Accessing off-chain data
  • Task scheduling
  • Security threats

Application architecture

Web3 Dapps architectures are different than Web2 web apps architectures because you need to add your smart contracts (blockchain) in the design. In some cases, the blockchain can even completely replace your backend if it makes sense for you to store all the data in it.

There are several Web3 overall architectural options, I already described some of them in this blog:

Web3 Dapps architectures. The very first thing that any developer… | by Alberto Molina | Jun, 2022 | Medium

Applications lifecycle

The major difference between smart contracts deployed on a blockchain and traditional backend services is that once they are deployed they cannot be modified in any way, you will not be able to fix bugs or add new functionality…

There are obviously some ways to “bypass” this limitation but you will have to keep it in mind from the very beginning of your design process.

You can use proxy patterns (transparent, UUPS, beacon…) that will allow you to decouple your data from your logic (in different smart contracts) so that you can deploy new logic contracts without losing your current contracts state (data). You can, instead of a proxy pattern, choose to simply migrate your contracts state to the newer contracts whenever you deploy them.

Both strategies can be interesting depending on your use case, but the important thing is to always think about it at the very beginning of your project.

You can check the following links for more information:

Upgradeable Dapp architecture. Smart contracts are, by definition… | by Alberto Molina | CoinsBench

Upgrading smart contracts — OpenZeppelin Docs

Application Maintenance

In web2 if you need to do some maintenance work on your backend application or server, you can simply stop it for a while, your users will see a very nice message on their browser “Down for maintenance” and that is.

Smart contracts on the other hand cannot be stopped. Just like I described in the previous section (Application lifecycle) smart contracts are immutable, public, and unstoppable (you can only destroy them using the “self-destruct” command, but that will completely remove your smart contract from the blockchain).

If you think that at some point you might need to “stop” your smart contract and then “start” it again, you will have to handle that with code. The “Pausable” pattern is a very simple and effective way to do that, it is meant to pause your contract in case of emergency so that nobody except you can interact with it, then unpause it whenever the work is done. You can check the OpenZeppelin open-source library here :

Security — OpenZeppelin Docs

Data visibility

Blockchain data is public and available to anyone off-chain. It is true that you can set some state variables as internal or private but this will only restrict the visibility to other smart contracts, off-chain programs will always be able to read any slot in your contract storage.

It is thus extremely important to never store confidential information on the blockchain which is why a backend can sometimes be required in a web3 Dapp architecture.

Application execution

Smart contracts are decentralized, they run on every node of the blockchain network, in order to add a transaction to the blockchain you will need a miner to validate it and add it to a block.

This means that transactions to your smart contracts will be available to one or multiple miners, they will be able to see the transaction content and check the smart contract execution output before actually adding the transaction to the blockchain.

This can lead to smart contract vulnerabilities like :

  • Front running”: a miner copies another user’s transaction and adds it to the blockchain before adding the user’s one. If your smart contract was supposed to award a prize to the first person to submit that particular content, your user will be quite disappointed.

Front-Running Attacks on Blockchain | by Saad.Najafi | CodeChain | Medium

  • Replay attacks” : someone sends a transaction to your smart contract with the same content as a previous transaction (the content can be a signed message from one of your users for example). This can lead to some code being re-executed which could be an issue.

What Is a Replay Attack? | Binance Academy

  • Timestamp manipulation” : miners can manipulate the timestamp of the block they are mining in order to trick your smart contract.

Timestamp Dependence — Ethereum Smart Contract Best Practices (consensys.github.io)

  • Insecure Randomness”: smart contracts must be deterministic which makes on-chain randomness impossible, the only way to get a random value is to rely on off-chain data provided by oracles for example.

Random Number Generator for Blockchain Games | Chainlink

Execution costs

Transactions cost money (paid by the transaction sender). The price of a transaction depends on the code it executes. Indeed your smart contract's code compiles into EVM opcodes that have a fixed price (the more computationally intensive the opcode is the more expensive it gets). Whenever a transaction runs, the opcodes prices add up to return the final transaction price.

In Ethereum we talk about Gas (unit that defines the opcodes prices) and Gas Price (the amount of money the user is willing to pay per unit of Gas).

The point is that you should implement your code so that it consumes as little Gas as possible.

Long executions (loops)

Looping through arrays is a very common practice in web2 Webapps. You can also loop through arrays in smart contracts, the problem is that a transaction is supposed to fit within a block, and blocks have a maximum size (calculated in Gas). If you start looping through a long array (or your function executes too many opcodes for whatever reason) you might end up consuming more than the allowed maximum amount of Gas, in which case the transaction will revert.

You can very easily end up causing a DoS attack to your own smart contract, let’s suppose that you loop through an array that originally did not contain many values but you let users add new elements to it. A malicious actor could add many elements to your array until looping through it becomes literally impossible…

Always check if your functionality can become too expensive to execute in term of Gas. A good rule of thumb is: try not to loop through arrays, use “mappings” instead which are hash tables that can store any type of data.

User authentication

You do not need to authenticate users in the blockchain, wallets sign messages using private/public key cryptography and account addresses are obtained from the public key, meaning that no one can ever send a transaction to the blockchain pretending to be someone else.

Logging

Blockchain does not allow your code to actually log anything. Instead of logging, ethereum let’s you use “events” which are kind of single lines of information containing the event name followed by all the data you defined in the event.

The idea is to define an event for every operation you would like to monitor (that you would normally log in a web2 web app). The event can contain for example the previous states of the modified variables and the new ones. Some of those values can even be indexable to make your search faster. Once the operation is executed the event gets triggered and recorded on the blockchain. The event is now accessible to anyone monitoring the blockchain. It is important to note that events are not accessible to other smart contracts despite been stored on the blockchain themselves.

A Guide to Events and Logs in Ethereum Smart Contracts | ConsenSys

Admin rights

Admin rights are assigned to accounts and accounts can be either “externally owned” (EOA: meaning that someone owns the private key) or can be contracts (no private key at all). Even if you grant admin rights to a contract, you will probably end up controlling that contract with an externally owned account too.

The problem here is that EOA can be compromised, and the private key can be stolen or lost which is something that does not happen so often to admin accounts in backend systems.

A good idea is to always grant admin rights to multiple EOAs and require more than just 1 admin validation to execute critical code.

System upgrades

In web2 you can choose whether or not to upgrade the OS running your backend. You can postpone certain upgrades that are incompatible with your applications until you have time to upgrade them.

The problem in web3 is that we are all sharing the same computer and the same OS. If a hard fork is approved and deployed, your smart contracts might not work anymore, you should always keep up with the latest deployments and follow the potentially breaking changes in system upgrades.

Accessing off-chain data

If you need your Dapp to access data that does not exist in the blockchain (exchange rates, weather information, etc…) you will have to scratch your head a little bit.

In web2 you can simply make your application invoke some API from an external provider (you can virtually access any data in the world doing that) in web3 the problem is that smart contracts can only retrieve data stored in another’s smart contract’s storage!

The only way for your smart contracts to access “outside world” information is by sending it to the blockchain. You can choose to either do it yourself, which can actually be a lot of work or use an existing and reliable Oracle.

Oracles provide outside world data to the blockchain and make it available to all other smart contracts (normally for a fee), you can check Chainlink, UMA, or any other and see if they already provide the data you need, otherwise, you will have to look for a plan B…

Task Scheduling

Smart contract tasks cannot be scheduled, they only run when invoked by an external account or by another smart contract.

If you need your backend to run some scheduled jobs without any end-user interaction you will have to do it using a traditional backend, blockchains are not meant for that.

Security Threats

Some security threats are different in web3 and web2. To begin with, the fact that you will be deploying smart contracts on a blockchain will exponentially increase the number of attack vectors your Dapp may have, you can check the following two blogs I wrote about common vulnerabilities and safeguards :

Smart Contracts common vulnerabilities (solidity) | by Alberto Molina | May, 2022 | CoinsBench

Smart Contracts Safeguards. Smart Contracts are an easy target for… | by Alberto Molina | May, 2022 | CoinsBench

It is also important to point out that blockchains, despite introducing several new attack vectors, are not vulnerable to some other forms of attacks that are very common nowadays like SQL injection attacks (no SQL in a blockchain smart contract)or CSRF (no cookies are delivered to the blockchain).

--

--