0xhardman

0xhardman

twitter
medium
jike
github

DAPP Quick Start Guide

Last night, I was invited by Teacher LXDAO Vdel to talk to the students of the web3 internship program about DAPP development. At first glance, the need for on-chain interaction with wallets is just DAPPs, which isn't too complicated. Moreover, with AI being so powerful now, writing a DAPP isn't a matter of minutes. So I agreed, thinking, isn't this just a web3 hello world?

Later, after finishing my work, I thought I might be suffering from the "curse of knowledge." I recalled my confusion and helplessness during my first hackathon when I created a replica of LXDAO Marry3 called Ring3. Reflecting on my experiences over the years participating in hackathons and projects across different chains, I suddenly felt it was worth discussing. At the same time, it was also a great opportunity to organize my experiences from the past few years and write a blog while preparing the course.

What is DAPP?#

The usual definition is: DAPP, short for Decentralized Application, refers to applications that run on a blockchain. Unlike traditional centralized applications, DAPPs do not rely on centralized servers but rather on the decentralized characteristics of the blockchain. Therefore, DAPPs possess the traits of decentralization, trustlessness, and lack of intermediaries.

The above is a very official introduction, but in reality, if you strictly follow the official server to create a DAPP, making everything decentralized would lead to a very poor user experience, such as difficulty accessing, slow speeds, complex processes, and so on. In fact, even one of the greatest inventions of blockchain—the decentralized exchange Uniswap—is not completely decentralized. Specifically, for example, the token list on Uniswap, if read from the blockchain every time, might take ages; other data queries like prices, slippage, trading volume, TVL, liquidity pools, etc., are retrieved and organized through centralized services that store blockchain data and provide web API/GraphQL interfaces, which are then called by the frontend for user access.

So, what exactly is a decentralized application (DAPP)? In my words, anything that requires on-chain interaction for writing/reading operations can be considered a DAPP, just with varying degrees. DAPPs and our traditional web development are not opposed; they can still be compatible with each other. We can analyze a product's degree of decentralization using a Venn diagram:

DAPP Decentralization Degree Venn Diagram

I believe the entire purple area can be defined as the DAPP area, focusing on several key areas:

  1. The brown area represents the vast majority of DAPPs: Most well-known DAPPs like Uniswap, Pendle, OpenSea, ENS, etc., utilize both decentralized and centralized technologies in their frontend and backend. The frontend typically does not deploy services using technologies like IPFS but may use decentralized CDN technologies to enhance user experience. The backend services are fundamentally based on decentralized blockchain technology, where core services interact directly with the chain but synchronize blockchain data through centralized database servers to form indexes, essentially improving data query speeds and enhancing user experience.
  2. Looking at the "Simple DAPP" area below the brown area, applications in this area usually have relatively simple functions. Specifically, they may only need to read the asset status of a certain address or perform some simple write operations, such as minting NFTs or transferring NFTs. This type of DAPP was particularly popular around 2021 during the NFT boom, where many project teams created flashy web pages to enhance their NFT brand image to sell more NFTs. These DAPPs would determine whether users were eligible to mint, how many NFTs they could mint, and then allow users to call smart contracts to mint, displaying the minted NFTs to users. By the way, LXDAO's Project 0, the Conscience NFT, was also born during that period, but the Conscience NFT stands out in the entire market with its simple web style but complete functionality, objectively introducing the NFT's features without flashy gimmicks, and can be understood as a pure art sales website. At that time, the price was only 0.01 ETH each, and now it's hard to come by

  3. Then, looking at the "Extreme DAPP" area in the brown area. Here, we won't discuss the CDN content distribution network; this service itself is indeed decentralized but still faces the centralization issue of CDN service providers. However, most of the time, we can accept using decentralized applications without an interactive interface. The decentralized frontend discussed here aims to avoid the centralization issues posed by network service providers, such as Tornado.cash, which is essentially an application that uses blockchain technology for money laundering. Whoever maintains it faces legal risks, and no server provider would want their servers to be used to deploy such things. But technology is innocent; the community came up with a brilliant idea to deploy the frontend code of Tornado.cash on IPFS (which will be introduced in the next chapter). Simply put, it's like copying a store into flyers and distributing them to many people to keep, sealing one place while others remain accessible. Of course, the downside is that this website is incredibly slow to access. So, this is not a common solution.
  4. Broadly speaking, the core of DAPPs is a complete set of smart contracts. A DAPP can be constituted solely by smart contracts, but blockchain isn't just for programmers. To attract more users, a basic interactive interface is still necessary.

In summary, whether there is interaction with the chain and whether the core revolves around smart contracts are the most basic standards for judging a DAPP. Centralized frontends and backends can be compatible with DAPPs and play a very important role in enhancing user experience.

Basic Architecture of DAPP#

Based on our understanding of DAPPs, the basic architecture of a DAPP can be simply divided into three parts: frontend, backend, and smart contracts. The frontend and backend are centralized, while the smart contracts are decentralized. Haha, of course, it's not that simple; if it were, there wouldn't be much to write about. Besides the content mentioned above, there are also some important foundational services that support the operation of DAPPs. I have provided detailed explanations, and their relationships are illustrated in the following diagram, which doesn't require much elaboration:

image-3

IPFS#

The Chinese name is InterPlanetary File System, which can be understood as a decentralized file storage system, but without the complex consensus mechanisms of blockchain, it distinguishes/retrieves files by verifying hash values.

Specifically, but simply put, you can understand it as a group of kind-hearted people maintaining a free storage facility on the internet. Uploaded files are distributed and stored across many storage facilities worldwide (meaning some servers have a copy), using file hash values to avoid duplicate storage, while users can also find the corresponding complete data of files through the file hash values.

Of course, nothing is that good; the price of free is that your files may be deleted at any time. However, IPFS also offers some paid storage services to ensure file storage through Filecoin (blockchain).

RPC Service Providers#

In fact, ordinary applications cannot and do not need to interact directly with the Ethereum network. The detailed underlying knowledge of blockchain will not be discussed here; interested friends can look it up themselves.

DAPPs only need to "use" the blockchain, not "maintain" it. "Maintaining" the blockchain requires direct interaction with the chain, which involves participating in blockchain mining/consensus, needing to synchronize massive blockchain data. However, "using" the blockchain does not require concern for such vast data; it is similar to ordinary web services, only needing to open some interfaces.

RPC (Remote Procedure Call) service providers essentially provide an API interface, but with a special format requirement. RPC service providers typically run different types of Ethereum nodes (including full nodes, light nodes, or archive nodes) and expose node functionalities through JSON-RPC interfaces. These interfaces follow Ethereum's JSON-RPC specifications, allowing developers to query blockchain data, send transactions, call smart contracts, etc., via HTTP or WebSocket requests.

Index Service Providers#

You can first look at RPC and then understand index services. This needs to be explained in more detail. When you use RPC to read blockchain data, you cannot query the data you need as freely as you would with a database. Usually, you can only read the current status of a contract or a wallet (like balance) or query detailed information about a single transaction/block or listen for certain events (like whether a new NFT has been minted or whether there are new transactions).

However, as a DApp, you typically need to query all transaction situations of a certain contract from its deployment to the present. Specifically, you might want to check all holders of a certain NFT contract. Without index services, you would need to start from the block where the contract was deployed and record related NFT mint, transfer, burn, and other transactions block by block.

Theoretically, this is not a "necessary" service; if your project is not large, you can completely handle this yourself. However, the demand for such services is similar and universal, which is why index services exist. They check each block, record relevant transactions in a database, and facilitate developers to query using conventional data query statements (usually providing GraphQL API), helping reduce the development burden.

Oracles#

The name Oracle sounds grand, but it is essentially the bridge between blockchain and the real world. Consider a question: how does the blockchain know the current price of ETH? Intuitively, can't we deploy a smart contract and find a trusted role to tell the smart contract the price, which the smart contract can then use for subsequent operations? But the problem arises: who guarantees that this role is trustworthy? We certainly cannot determine the truth of the message based solely on one role's information; the verification of results must also be decentralized, which is where oracles come into play.

The basic principle of oracles is to ensure data reliability through multiple data sources and providers. Taking the ETH price as an example, the oracle network retrieves ETH/USD price data from multiple exchanges like Coinbase, Binance, Kraken, and then calculates a final price using a weighted average algorithm. If the price provided by a certain exchange differs too much from the majority of other exchanges, it will be identified and excluded by the system. Meanwhile, data providers (oracle nodes) need to stake tokens as collateral; if they provide incorrect price data, their tokens will be forfeited, thus creating economic incentives to ensure data accuracy.

The most famous oracle project is Chainlink, which has established a vast oracle network providing real-time price data for thousands of DeFi DAPPs. When you trade on Uniswap or borrow on Aave, these protocols need to know the accurate prices of various tokens to calculate trading ratios or liquidation conditions, and this price data is provided by oracles like Chainlink.

In this section, I will first introduce a more general frontend and backend development toolchain, followed by some toolchains I have encountered on various chains.

General Technology#

I highly recommend that anyone developing DApps prioritize learning JS, as knowing JS allows you to run through the entire process almost by yourself.

Frontend Tech Stack:

Deployment and Tools:

Backend Tech Stack:

Storage Services:

Cost Optimization:

  • Recommended to search "Independent Development Poor Guy Package" for more economical solutions

Ecological Toolchain#

In any case, Ethereum is currently the most mature chain, and the following chapters will take Ethereum as an example to introduce the complete process of DAPP development.

NFT Mint DAPP Demo#

Contract Development and Deployment (Choose one of the following)#

Preparation Before Development#

  1. Create an image: You can consider using your avatar or generating one with AI.
  2. Upload to Pinata IPFS
    1. Register and log in.
    2. Upload the file.
    3. Record the CID like this: bafkreigfpdewysnl5fq2ir57r26fhxpa6bg3qoy3sbkxlajq6dkf4wye3u
    4. You can access the image through the IPFS Gateway, like this: https://ipfs.io/ipfs/bafkreigfpdewysnl5fq2ir57r26fhxpa6bg3qoy3sbkxlajq6dkf4wye3u
    5. Prepare the string ipfs://{CID}, like this: ipfs://bafkreigfpdewysnl5fq2ir57r26fhxpa6bg3qoy3sbkxlajq6dkf4wye3u
  3. Prepare metadata
    1. Refer to the content below to write your own Metadata, with name (name), description (description), and attributes (attributes) written freely (Note: attributes are a fixed array containing trait_type and value).
    2. Copy the content you just created and make it into a JSON file.
    3. Refer to the previous steps to upload to IPFS.
    4. Record the CID and prepare the IPFS URL, like this: ipfs://bafkreid7msiyufvgilrlkt6244psudmaycbbzika2aq57kou3xha5u36pe
{
    "name": "My First Handmade NFT",
    "description": "My First Handmade NFT by @hardman_eth",
    "image": "ipfs://bafkreigfpdewysnl5fq2ir57r26fhxpa6bg3qoy3sbkxlajq6dkf4wye3u",
    "attributes": [
        {
            "trait_type": "IQ",
            "value": "80"
        },
        {
            "trait_type": "Hat",
            "value": "Pot"
        }
    ]
}
  1. Prepare the Etherscan API key
    1. Register and log in at https://etherscan.io/login; the mainnet API key is also valid for the testnet.
    2. Copy the API key and place it in the environment variable .env.
    3. Add the private key you plan to use for deployment (consider generating one with a script or creating one directly; it's not recommended to use online tools due to security issues).
# Private key for deployment
PRIVATE_KEY=your_private_key_here

# Public Sepolia RPC URL, You can change it to your own private RPC
SEPOLIA_RPC_URL=https://ethereum-sepolia-rpc.publicnode.com

# Etherscan API key for contract verification (free from etherscan.io)
ETHERSCAN_API_KEY=your_etherscan_api_key
  1. Get test tokens
    Any write operation on the blockchain requires paying gas fees. Since we are using the testnet, we can obtain some test tokens, also known as "getting water."

https://www.alchemy.com/faucets/ethereum-sepolia

You can also follow me on Twitter, DM me your address, and I'll send you 0.1.

Based on the Foundry Framework#

  1. Install Foundry; I won't go into detail here; you can refer to the official documentation.
  2. Initialize the Foundry project
forge init foundry-nft
  1. Copy the .env file you just prepared into the directory.
  2. Install dependencies (OpenZeppelin)
forge install OpenZeppelin/openzeppelin-contracts
  1. Write the contract; you can directly ask AI to generate it. A prompt could be "Write a simple NFT contract, free minting, limited to 999 pieces, ipfs://bafkreid7msiyufvgilrlkt6244psudmaycbbzika2aq57kou3xha5u36pe." You can also refer to the contract code in the foundry-simple-nft repository.
  2. Write unit tests, refer to foundry-nft/test/SimpleNFT.t.sol.
  3. Prepare the deployment script, refer to foundry-nft/script/DeploySimpleNFT.s.sol.
  4. Deploy the contract and verify it.
# 1. Copy the environment variable file and fill in the private key
cp .env.example .env

# Edit the .env file to fill in your private key
# 2. Deploy to the Sepolia testnet
source .env && forge script script/DeploySimpleNFT.s.sol --rpc-url $SEPOLIA_RPC_URL --broadcast --verify

# Or use the public RPC to deploy directly
forge script script/DeploySimpleNFT.s.sol --rpc-url https://ethereum-sepolia-rpc.publicnode.com --broadcast

# 3. Or execute step by step
# First deploy
source .env && forge script script/DeploySimpleNFT.s.sol --rpc-url $SEPOLIA_RPC_URL --broadcast

# Then verify (requires contract address)
source .env && forge verify-contract <CONTRACT_ADDRESS> src/SimpleNFT.sol:SimpleNFT \
  --etherscan-api-key $ETHERSCAN_API_KEY \
  --chain sepolia

Frontend Development#

https://github.com/0xhardman/handmade-nft-frontend master branch

Integrate Wallet Plugins#

  1. Install RainbowKit, wagmi, viem
npm install @rainbow-me/rainbowkit wagmi [email protected] @tanstack/react-query
  1. Configure the testnet network.
  2. Wrap the provider.
  3. Get a basic understanding of RainbowKit's configuration.

Roughly Understand Common wagmi Hooks#

  1. useReadContract: Read data from a single contract.
  2. useWriteContract: Write data to a contract, such as minting or transferring.
  3. useAccount: Get basic information about the connected account (address, current network).
  4. useSignMessage: Sign a message.
  5. useBalance: Get the gas token balance or ERC20 token balance of the account.
  6. useWaitForTransactionReceipt: Wait for transaction confirmation.
  7. useSwitchChain: Switch the current chain.
  8. useSwitchAccount: Switch accounts.

Get the ABI File#

  1. If the contract is verified, you can download it from the blockchain explorer.
  2. If it's your own deployment, you can find it in the compiled files.
    • For example, in Foundry, you can find it in out/SimpleNFT.out/SimpleNFT.json.

Function Implementation#

  1. Check the network and prompt to switch.
  2. Check wallet balance and prompt the user to top up.
  3. Click the button to call the contract to mint.
  4. Wait for transaction confirmation and prompt success.
  5. Display my NFT page.

Other Concepts That Newbies Might Not Know#

Mint#

It can be understood as the initial purchase. For example, when you buy an artwork directly from the artist, it's called minting. Your money goes directly to the artist to support them, distinguishing it from buying from a second-hand dealer or another buyer, who would profit from the price difference. From a technical perspective, minting refers to creating a new digital asset from a zero address (0x0000...) on the blockchain and assigning it to the user, as opposed to transferring, which moves an asset from one address to another.

What is Gas? Why is there Gas?#

This question is very classic. When I first encountered blockchain, I was also confused about why there were transaction fees for transfers. Moreover, these fees fluctuate; sometimes they are a few dollars, and sometimes they are dozens, which seems even worse than banks!

In fact, Gas is the "transaction fee" of the Ethereum network, but it's not just a simple fee. Imagine Ethereum as a globally shared supercomputer; to get this computer to do something for you (like transferring money or executing a smart contract), you need to pay those who maintain this computer (miners/validators).

Technically, every operation consumes computational resources, and Gas is the unit that measures this resource consumption. A simple transfer might only require 21,000 Gas, but executing a complex smart contract (like trading on Uniswap) could require hundreds of thousands of Gas. Gas prices (Gas Price) change in real-time based on network congestion; when the network is busy, prices are high, and when it's idle, prices are low, similar to surge pricing for taxis.

So why is there Gas? Simply put, it prevents malicious attacks on the network (like infinite loops in code) while incentivizing miners/validators to maintain network security. Without Gas, the entire network would have been paralyzed by various junk transactions long ago.

Why Wait for Block Confirmation?#

Why do I have to wait several seconds or even minutes to see the result after clicking a button? This experience is terrible!

But this is actually an inevitable result of blockchain decentralization. In traditional centralized systems, like Alipay, when you transfer money, you only need to wait for Alipay's server to confirm, and it arrives instantly. But blockchain is different; it doesn't have a central server but is maintained by thousands of nodes worldwide.

Specifically, when you initiate a transaction, it gets broadcasted to the entire network and waits to be packaged into a new block by miners (or validators). Ethereum generates a new block approximately every 12-15 seconds, so your transaction must wait at least one block time for confirmation.

But that's not all; to prevent chain reorganization (simply put, blockchain forks rolling back), it is usually recommended to wait for multiple block confirmations. For example, exchanges typically require 12 block confirmations before considering a transaction final, which is why sometimes you have to wait several minutes.

However, for DAPPs, usually waiting for 1-2 block confirmations is sufficient, which takes about ten seconds to a minute. Although it's slower than centralized systems, it brings the benefits of decentralization, censorship resistance, and global accessibility, which I believe is a worthwhile trade-off.

EVM Ecological DApp Scaffold
Learn Blockchain, Solidity, and Full Stack Web3 Development with JavaScript
Web3 Internship Program
Everything You Need to Know About Converting Mnemonic Phrases to ETH Addresses

Conclusion#

There is actually a lot more I want to say, but focusing on "getting started" means I can't go too deep. Getting into blockchain isn't that simple; half an hour can only give everyone a "brief reading" of this thick book on DApp development. More practical experience and attempts are still necessary!

Feel free to DM me on my Twitter for discussions!

Loading...
Ownership of this post data is guaranteed by blockchain and smart contracts to the creator alone.