Home / Cases / Web2 to Web3 Development Guide

A complete guide to Web2 projects to Web3 decentralized development

📅 Last updated: May 2025 ⏱ Reading time: about 20 minutes 👤 By NovaLinkR technical team

Web2 to Web3 transformationNot a simple technological replacement, but a fundamental shift from a centralized architecture to a decentralized paradigm. This guide will provide a clear and gradual migration path for teams with mature Web2 products – from wallet authentication, smart contract integration, data decentralized storage to tokenomics design, covering every key technical decision point in the transformation process.

The essential difference between Web2 and Web3

Schematic diagram of the evolution of Web2 to Web3 architecture

To successfully complete the Web2 to Web3 migration, it is necessary to first deeply understand the fundamental differences between the two in terms of architectural philosophy, data ownership, and trust model.

Core paradigm comparison

Dimensions Web2 (Centralized) Web3 (Decentralized)
Data ownershipThe platform owns user dataUsers are in control of their data
Identity authenticationEmail/mobile phone number + passwordCrypto wallet signature verification
Backend logicCentralized server executionSmart contracts are executed on-chain
Data storageAWS/MySQL/MongoDBIPFS/Arweave/on-chain storage
Payment systemBanking/Alipay/StripeCryptocurrency on-chain transfers
Trust modelTrust Platform (Intermediary)Trust code (permissionless)
Governance methodsThe board of directors of the company makes decisionsDAO community voting governance
ComposabilityAPI Integration (Restricted)Smart contracts are permissionless combinations

Architectural thinking shifts

🔄 From Request-Response to Event-Driven

Web3 applications synchronize state by listening to on-chain events (Events), replacing the traditional API polling model. The frontend subscribes to contract events through WebSockets to achieve real-time data updates.

🔐 From "Trust Server" to "Verify Everything"

The core principle of Web3 is "Don't Trust, Verify". All key logic is executed by smart contracts, and the results can be independently verified by anyone without trusting a centralized server.

📊 From "platform locking" to "composability"

Web3 protocols are open Lego bricks, and any project can combine existing protocols (such as Uniswap, Aave) without permission to build more complex application layers.

💰 From "advertising monetization" to "token economy"

Web3 projects incentivize user participation, contribution, and governance through tokens, achieving a fair distribution of value among network participants, replacing the traditional advertising-data monetization model.

Why migrate to Web3

Web2 projects choose to transform to Web3 not blindly follow the trend, but are driven by clear business value and technical advantages:

Business drivers

🌍 There is no threshold for globalization

Anyone with a wallet can access the service without permission, without a bank account, without identity verification (KYC optional), covering the world's 2 billion unbanked people.

🤝 User trust and transparency

The business logic is open and transparent, the flow of funds is traceable, and the rules cannot be unilaterally modified, fundamentally solving the platform trust crisis.

🚀 Token Funding and Community Incentives

By issuing governance tokens, NFT loyalty cards, etc., it raises funds and builds a loyal community at a low cost worldwide.

🔗 Ecological synergy

After accessing the DeFi ecosystem, you can easily integrate financial services such as lending, trading, and insurance, without the need to connect to third-party payment channels one by one.

Types of Web2 products suitable for transformation

Product Type:Web3 directionTypical case
Social platformsDecentralized identity + content ownership + token incentivesLens Protocol, Farcaster
E-commerce/marketplaceNFT digital goods + on-chain reputation + crypto paymentsShopify NFT, Boson Protocol
gaming platformChain game assets + Play-to-Earn + NFT propsAxie Infinity, Immutable X
Content platformCreator economy + NFT subscription + decentralized storageMirror, Paragraph
SaaS toolsDecentralized computing + token payments + open APIAkash Network, Filecoin
Financial servicesDeFi protocol + on-chain lending + automated market makingAave, Compound

Progressive migration strategy

A one-time full rewrite is neither realistic nor necessary. It is recommended to adopt a "progressive decentralization" strategy to migrate core modules on-chain in stages while maintaining user experience continuity.

Four-stage migration route

01

Phase 1: Wallet integration and dual-track authentication (2-4 weeks)

Added a wallet login option to the existing system and retained the traditional email login. Users can bind their wallet addresses to existing accounts for a smooth transition. This stage is risk-free and can be rolled back at any time.

02

Phase 2: Core assets on the chain (4-8 weeks)

Tokenize core digital assets (points, membership rights, digital goods) within the platform. Deploy ERC-20/ERC-721 contracts to record asset ownership on-chain and maintain business logic off-chain.

03

Phase 3: Decentralization of business logic (6-12 weeks)

Migrate core business rules to smart contracts: deal matching, royalty distribution, incentive distribution, etc. Off-chain services are gradually scaled back to indexing and caching roles.

04

Phase 4: Full Decentralization and DAO Governance (8-16 weeks)

Data storage migrated to IPFS/Arweave, introduced DAO governance mechanism, and transferred platform control to the community. The front-end can be deployed to IPFS to achieve censorship resistance.

💡 Key principles: There should be a stable version that can be run independently after each phase. Even if the migration is paused at any stage, the system can serve users normally.

Architectural transformation design

The Web2 to Web3 architectural transformation requires redesigning every layer of the system. Here's a typical hybrid architecture solution that balances decentralization with user experience:

DApp Frontend
React/Next.js DAppWallet Connection (wagmi)Contract Interaction (ethers.js)IPFS gateway
Hybrid Backend
API GatewayOn-chain event indexingIPFS Pin ServiceCaching servicesNotification push
Blockchain Layer (On-Chain Logic)
Business contractsToken contractGovernance contractsAccess controlOracle integration
Decentralized Storage
IPFS / ArweaveThe Graph subgraphCeramic NetworkPostgreSQL (index)

Key architectural decisions

What logic is on the chain?
Logic involving asset transfer, authority control, and rule arbitration must be on the chain. High-frequency reads, complex calculations, and private data remain off-chain. Judgment criteria: "Does the user need to verify the fairness of this operation?" "
How to handle on-chain/off-chain data synchronization?
Adopt the Event Sourcing mode: The on-chain contract triggers the event → the indexing service listens for and synchronizes to the off-chain database→ The frontend reads the off-chain cache through APIs to achieve low-latency queries.
How to ensure upgradeability?
Deploy contracts using UUPS or Transparent Proxy mode to allow logical upgrades while maintaining the stored state. Coordinate Timelock + Multi-Signature Governance to approve and upgrade operations.
How to deal with blockchain performance limitations?
Adopt Layer2 solution (Arbitrum/Optimism/Base) to reduce gas costs, use Merkle Tree proofs for batch operations, and use off-chain signatures + on-chain settlement for non-critical operations.

Wallet authentication replaces traditional login

Wallet connection is the gateway to Web3 applications, replacing the traditional email/password login system. Secure and decentralized identity verification through SIWE (Sign-In with Ethereum) standard.

Comparison of certification processes

StepsWeb2 (Traditional Login)Web3 (Wallet Authentication)
1. InitiationThe user enters the email + passwordThe user clicks on "Connect Wallet"
2. VerificationThe server matches the password hashThe server generates a random nonce message
3. ConfirmationIf it matches, a JWT will be issuedUser wallet signature message
4. IssuanceThe server verifies the signature recovery address and issues the JWT
SecurityPasswords can be compromised/phishedThe private key does not leave the device and cannot be stolen

SIWE Certification Implementation (Backend)

// Node.js + Express 实现 SIWE 认证
import { SiweMessage } from 'siwe';
import jwt from 'jsonwebtoken';

// 1. 生成 Nonce(防重放攻击)
app.get('/api/auth/nonce', (req, res) => {
  const nonce = generateNonce(); // 随机32字节
  req.session.nonce = nonce;
  res.json({ nonce });
});

// 2. 验证签名并签发 Token
app.post('/api/auth/verify', async (req, res) => {
  const { message, signature } = req.body;

  try {
    const siweMessage = new SiweMessage(message);
    const result = await siweMessage.verify({ signature });

    // 验证 Nonce 匹配(防重放)
    if (result.data.nonce !== req.session.nonce) {
      return res.status(401).json({ error: 'Invalid nonce' });
    }

    // 验证通过,签发 JWT
    const token = jwt.sign(
      { address: result.data.address, chainId: result.data.chainId },
      process.env.JWT_SECRET,
      { expiresIn: '7d' }
    );

    // 查找或创建用户(与已有Web2账户关联)
    let user = await User.findOne({ walletAddress: result.data.address });
    if (!user) {
      user = await User.create({ walletAddress: result.data.address });
    }

    res.json({ token, user });
  } catch (error) {
    res.status(401).json({ error: 'Signature verification failed' });
  }
});

Front-end wallet connection (wagmi + RainbowKit)

// React 前端钱包连接
import { ConnectButton } from '@rainbow-me/rainbowkit';
import { useAccount, useSignMessage } from 'wagmi';
import { SiweMessage } from 'siwe';

function LoginButton() {
  const { address, isConnected } = useAccount();
  const { signMessageAsync } = useSignMessage();

  const handleLogin = async () => {
    // 1. 获取 Nonce
    const { nonce } = await fetch('/api/auth/nonce').then(r => r.json());

    // 2. 构造 SIWE 消息
    const message = new SiweMessage({
      domain: window.location.host,
      address,
      statement: 'Sign in to NovaLink Platform',
      uri: window.location.origin,
      version: '1',
      chainId: 1,
      nonce,
    });

    // 3. 请求用户签名
    const signature = await signMessageAsync({
      message: message.prepareMessage(),
    });

    // 4. 提交验证
    const { token } = await fetch('/api/auth/verify', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ message: message.prepareMessage(), signature }),
    }).then(r => r.json());

    localStorage.setItem('token', token);
  };

  return isConnected
    ? <button onClick={handleLogin}>Sign In with Wallet</button>
    : <ConnectButton />;
}

Dual-track parallel scheme

💡 Smooth transition recommendations: The traditional login entrance will be retained at the beginning of the migration, allowing users to bind their wallets to existing accounts. The database design allows a user to hold email + walletAddress at the same time, and both methods can log in to the same account.

Smart contract business layer

Migrating Web2's core business logic to smart contracts is a critical step in decentralization. The contract code is open, transparent, and tamper-proof, providing users with verifiable fairness guarantees.

Business logic migration example: Membership subscription system

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;

import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
import "@openzeppelin/contracts/access/Ownable.sol";

/// @title 去中心化会员订阅合约
/// @notice 将传统SaaS订阅模型转化为链上NFT会员卡
contract MembershipNFT is ERC721, Ownable {
    struct Membership {
        uint256 tier;        // 0=Basic, 1=Pro, 2=Enterprise
        uint256 expiry;      // 过期时间戳
        uint256 mintedAt;    // 铸造时间
    }

    mapping(uint256 => Membership) public memberships;
    mapping(uint256 => uint256) public tierPrices; // tier => price in wei
    uint256 private _nextTokenId;

    event MembershipMinted(address indexed user, uint256 tokenId, uint256 tier, uint256 expiry);
    event MembershipRenewed(uint256 tokenId, uint256 newExpiry);

    constructor() ERC721("NovaLink Membership", "NLM") {
        tierPrices[0] = 0.01 ether;   // Basic: ~$30/月
        tierPrices[1] = 0.05 ether;   // Pro: ~50/月
        tierPrices[2] = 0.2 ether;    // Enterprise: ~$600/月
    }

    /// @notice 购买会员(铸造NFT会员卡)
    function subscribe(uint256 tier, uint256 months) external payable {
        require(tier <= 2, "Invalid tier");
        require(months > 0 && months <= 12, "1-12 months");
        require(msg.value >= tierPrices[tier] * months, "Insufficient payment");

        uint256 tokenId = _nextTokenId++;
        uint256 expiry = block.timestamp + (months * 30 days);

        _mint(msg.sender, tokenId);
        memberships[tokenId] = Membership(tier, expiry, block.timestamp);

        emit MembershipMinted(msg.sender, tokenId, tier, expiry);
    }

    /// @notice 续费(延长过期时间)
    function renew(uint256 tokenId, uint256 months) external payable {
        require(ownerOf(tokenId) == msg.sender, "Not owner");
        require(months > 0 && months <= 12, "1-12 months");

        Membership storage m = memberships[tokenId];
        require(msg.value >= tierPrices[m.tier] * months, "Insufficient payment");

        uint256 base = m.expiry > block.timestamp ? m.expiry : block.timestamp;
        m.expiry = base + (months * 30 days);

        emit MembershipRenewed(tokenId, m.expiry);
    }

    /// @notice 检查会员是否有效
    function isActive(uint256 tokenId) public view returns (bool) {
        return memberships[tokenId].expiry > block.timestamp;
    }

    /// @notice 检查地址是否拥有有效会员
    function hasActiveMembership(address user) external view returns (bool) {
        uint256 balance = balanceOf(user);
        for (uint256 i = 0; i < balance; i++) {
            // 简化示例,实际应使用 ERC721Enumerable
            // 遍历用户持有的所有会员NFT
        }
        return false;
    }

    function withdraw() external onlyOwner {
        payable(owner()).transfer(address(this).balance);
    }
}

Web2 vs Web3 business logic comparison

Business functionWeb2 implementationWeb3 implementation
User paymentStripe/PayPal APIThe contract payable function receives ETH/USDC
Membership statusDatabase field queriesContract view function validation
Subscription expiresScheduled task checksOn-chain timestamp comparison
Refund mechanismCustomer service manual processingContracts are automatically refunded on a pro-rata basis
Data transparencyThe user is not visibleAnyone can verify it on-chain
Membership transferUsually not supportedNFTs are freely transferred/sold

Decentralized storage of data

Web3's data storage no longer relies on a single cloud service provider, but is distributed in a decentralized network to achieve censorship resistance, permanent storage, and user data autonomy.

Storage Scheme Selection

SchemeFeatures:Applicable data typesCost
IPFS + FilecoinContent addressing, decentralization, and incentive layersStatic files, media assets, NFT metadataMedium
ArweavePay once for permanent storageImportant documents, legal documents, historical dataDisposable
Ceramic NetworkVariable data flow and user autonomyUser profile, social data, settingslow
On-chain storageMaximum security, never lostCore state variables, balances, permissionsExtremely high
The GraphOn-chain data indexing and queryingTransaction history, event logs, aggregated statisticsBy query volume

IPFS file upload and retrieval

// 使用 Pinata SDK 上传文件到 IPFS
import PinataSDK from '@pinata/sdk';

const pinata = new PinataSDK({
  pinataApiKey: process.env.PINATA_API_KEY,
  pinataSecretApiKey: process.env.PINATA_SECRET_KEY,
});

// 上传用户文件到 IPFS
async function uploadToIPFS(fileBuffer, fileName) {
  const readableStream = Readable.from(fileBuffer);
  readableStream.path = fileName;

  const result = await pinata.pinFileToIPFS(readableStream, {
    pinataMetadata: { name: fileName },
    pinataOptions: { cidVersion: 1 },
  });

  return {
    cid: result.IpfsHash,
    url: `ipfs://${result.IpfsHash}`,
    gateway: `https://gateway.pinata.cloud/ipfs/${result.IpfsHash}`,
  };
}

// 上传 JSON 元数据到 IPFS
async function uploadMetadata(metadata) {
  const result = await pinata.pinJSONToIPFS(metadata, {
    pinataMetadata: { name: `metadata-${Date.now()}` },
  });
  return `ipfs://${result.IpfsHash}`;
}

Ceramic Network user data flow

// 使用 Ceramic + ComposeDB 管理用户可变数据
import { ComposeClient } from '@composedb/client';
import { DID } from 'dids';

// 定义数据模型(GraphQL Schema)
const profileSchema = `
  type UserProfile @createModel(accountRelation: SINGLE, description: "User Profile") {
    displayName: String! @string(maxLength: 100)
    bio: String @string(maxLength: 500)
    avatar: String @string(maxLength: 200)  # IPFS CID
    socialLinks: [String] @list(maxLength: 10)
    updatedAt: DateTime!
  }
`;

// 用户更新自己的 Profile(无需服务器介入)
async function updateProfile(ceramic, profileData) {
  const compose = new ComposeClient({ ceramic, definition });

  await compose.executeQuery(`
    mutation {
      createUserProfile(input: {
        content: {
          displayName: "${profileData.name}"
          bio: "${profileData.bio}"
          avatar: "${profileData.avatarCID}"
          updatedAt: "${new Date().toISOString()}"
        }
      }) {
        document { id }
      }
    }
  `);
}

Data migration strategy

  • Thermal data(Frequent reads and writes): Remains in the off-chain database + Redis cache, synchronizing the on-chain state through events
  • Cold data(History Archive): Bulk migration to Arweave persistent storage
  • User data(Profile/Settings): Migrated to Ceramic, where users control autonomously through DIDs
  • Media files(Image/Video): Migrating to IPFS, CID writes to on-chain contracts

Front-end DApp retrofit

The biggest difference between Web3 front-end and traditional web front-end is that it needs to interact with wallets, read and write smart contracts, and listen to on-chain events. Here are the key transformation points for upgrading existing React applications to DApps:

Technology stack upgrades

Functional modulesWeb2 technologyWeb3 alternatives
User authenticationFirebase Auth / Auth0wagmi + SIWE
Status managementRedux / Zustandwagmi hooks + React Query
API callsAxios / fetchethers.js Contract.call()
Real-time updatesWebSocket / SSEContract Event Listener
File uploadAWS S3 SDKIPFS / Pinata SDK
Payment integrationStripe Elementswagmi useSendTransaction

Contract interaction encapsulation

// 封装合约交互 Hook(React + wagmi v2)
import { useReadContract, useWriteContract, useWaitForTransactionReceipt } from 'wagmi';
import { parseEther } from 'viem';
import { MEMBERSHIP_ABI, MEMBERSHIP_ADDRESS } from '../contracts/membership';

// 读取会员状态
export function useMembershipStatus(tokenId) {
  const { data: isActive } = useReadContract({
    address: MEMBERSHIP_ADDRESS,
    abi: MEMBERSHIP_ABI,
    functionName: 'isActive',
    args: [tokenId],
    watch: true, // 自动轮询更新
  });

  const { data: membership } = useReadContract({
    address: MEMBERSHIP_ADDRESS,
    abi: MEMBERSHIP_ABI,
    functionName: 'memberships',
    args: [tokenId],
  });

  return { isActive, membership };
}

// 购买会员(写入操作)
export function useSubscribe() {
  const { writeContract, data: hash, isPending } = useWriteContract();

  const { isLoading: isConfirming, isSuccess } = useWaitForTransactionReceipt({ hash });

  const subscribe = (tier, months, price) => {
    writeContract({
      address: MEMBERSHIP_ADDRESS,
      abi: MEMBERSHIP_ABI,
      functionName: 'subscribe',
      args: [tier, months],
      value: parseEther(price),
    });
  };

  return { subscribe, isPending, isConfirming, isSuccess, hash };
}

Event listening is synchronized with status

// 监听链上事件实时更新UI
import { useWatchContractEvent } from 'wagmi';
import { useQueryClient } from '@tanstack/react-query';

function MembershipDashboard() {
  const queryClient = useQueryClient();

  // 监听新会员铸造事件
  useWatchContractEvent({
    address: MEMBERSHIP_ADDRESS,
    abi: MEMBERSHIP_ABI,
    eventName: 'MembershipMinted',
    onLogs(logs) {
      logs.forEach(log => {
        const { user, tokenId, tier, expiry } = log.args;
        // 更新本地缓存
        queryClient.invalidateQueries(['membership', tokenId]);
        // 显示通知
        toast.success(`会员 #${tokenId} 已激活!`);
      });
    },
  });

  // 监听续费事件
  useWatchContractEvent({
    address: MEMBERSHIP_ADDRESS,
    abi: MEMBERSHIP_ABI,
    eventName: 'MembershipRenewed',
    onLogs(logs) {
      logs.forEach(log => {
        queryClient.invalidateQueries(['membership', log.args.tokenId]);
      });
    },
  });

  return (<div>{/* Dashboard UI */}</div>);
}

Tokenomics integration

The token economy is the core growth engine of Web3 projects, upgrading the points/membership system of traditional platforms to a token system with real value circulation.

Token economic model design

🪙 Utility Token

Unlock functions in the platform, pay for services, and pay for gas. For example, platform fee discounts, advanced feature usage rights, and API call quotas.

🏛️ Governance Token

Give holders the power to participate in platform decisions: protocol upgrade voting, rate adjustments, new feature proposals. The amount of coins held determines the voting weight.

🎁 Reward Token

Reward users for their contributions: content creation, referral invitations, liquidity provision. Instead of traditional points, they can be freely traded on DEXs.

🖼️ NFT certificates

Represents membership, achievement badges, and limited benefits. Indivisible and unique certificates that can be traded on the secondary market.

Token distribution and release contract

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;

import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import "@openzeppelin/contracts/access/Ownable.sol";

/// @title 平台治理代币 + 线性释放
contract PlatformToken is ERC20, Ownable {
    uint256 public constant MAX_SUPPLY = 1_000_000_000 * 1e18; // 10亿总量

    // 代币分配
    uint256 public constant COMMUNITY_ALLOCATION = 400_000_000 * 1e18; // 40% 社区
    uint256 public constant TEAM_ALLOCATION = 200_000_000 * 1e18;      // 20% 团队
    uint256 public constant INVESTORS_ALLOCATION = 150_000_000 * 1e18;  // 15% 投资者
    uint256 public constant ECOSYSTEM_ALLOCATION = 250_000_000 * 1e18;  // 25% 生态

    // 线性释放
    struct VestingSchedule {
        uint256 total;
        uint256 released;
        uint256 startTime;
        uint256 duration;
        uint256 cliff;  // 锁定期
    }

    mapping(address => VestingSchedule) public vestingSchedules;

    constructor() ERC20("NovaLink Token", "NLT") {
        // 社区份额直接铸造到DAO金库
        _mint(msg.sender, COMMUNITY_ALLOCATION);
    }

    /// @notice 创建线性释放计划
    function createVesting(
        address beneficiary,
        uint256 amount,
        uint256 cliff,
        uint256 duration
    ) external onlyOwner {
        require(vestingSchedules[beneficiary].total == 0, "Already exists");
        vestingSchedules[beneficiary] = VestingSchedule({
            total: amount,
            released: 0,
            startTime: block.timestamp,
            duration: duration,
            cliff: cliff
        });
        _mint(address(this), amount); // 锁定到合约
    }

    /// @notice 领取已释放的代币
    function claimVested() external {
        VestingSchedule storage schedule = vestingSchedules[msg.sender];
        require(schedule.total > 0, "No vesting");
        require(block.timestamp >= schedule.startTime + schedule.cliff, "Cliff");

        uint256 vested = _vestedAmount(schedule);
        uint256 claimable = vested - schedule.released;
        require(claimable > 0, "Nothing to claim");

        schedule.released += claimable;
        _transfer(address(this), msg.sender, claimable);
    }

    function _vestedAmount(VestingSchedule memory s) internal view returns (uint256) {
        if (block.timestamp >= s.startTime + s.duration) return s.total;
        return (s.total * (block.timestamp - s.startTime)) / s.duration;
    }
}

Web2 Credits → Web3 token migration solution

  • Snapshot migration: Take a snapshot of the existing points database and generate a Merkle Tree, where users can claim equivalent tokens with proof
  • Progressive exchange: Set the redemption window period, and users will actively exchange points 1:1 for on-chain tokens
  • Dual-track operation: During the transition period, points and tokens will be parallel, and off-chain points will be automatically synchronized as on-chain balances
  • Incentivize migration: Early migrating users receive additional incentives (such as a 10% bonus) to encourage the transition to be completed as soon as possible

DAO governance module

DAOs (Decentralized Autonomous Organizations) hand over the decision-making power of the platform from centralized teams to the community of token holders, enabling true decentralized governance.

Governance process

01

Proposal creation

Users holding a certain amount of tokens (e.g., 0.1% of the total supply) can submit governance proposals, including protocol upgrades, fee adjustments, fund allocations, etc.

02

Discussion period (3-7 days)

The community discusses the pros and cons of proposals on forums and Discord, and proposers can modify the content based on feedback.

03

On-chain voting (5-7 days)

Token holders vote through on-chain contracts, one coin, one vote, or quadratic votes. If the quorum is reached, the proposal will be passed.

04

Timelock execution (2 days delay)

Proposals that pass enter a timelock, giving the community a final exit window. Automate on-chain operations after expiration.

Governance contract core logic

// 基于 OpenZeppelin Governor 的治理合约
import "@openzeppelin/contracts/governance/Governor.sol";
import "@openzeppelin/contracts/governance/extensions/GovernorSettings.sol";
import "@openzeppelin/contracts/governance/extensions/GovernorCountingSimple.sol";
import "@openzeppelin/contracts/governance/extensions/GovernorVotes.sol";
import "@openzeppelin/contracts/governance/extensions/GovernorTimelockControl.sol";

contract PlatformGovernor is
    Governor,
    GovernorSettings,
    GovernorCountingSimple,
    GovernorVotes,
    GovernorTimelockControl
{
    constructor(
        IVotes token,
        TimelockController timelock
    )
        Governor("NovaLink Governor")
        GovernorSettings(
            7200,     // 投票延迟:1天(按区块数)
            50400,    // 投票持续:7天
            100000e18 // 最低提案门槛:10万代币
        )
        GovernorVotes(token)
        GovernorTimelockControl(timelock)
    {}

    // 法定人数:总供应量的 4%
    function quorum(uint256) public pure override returns (uint256) {
        return 40_000_000e18;
    }
}

Test and deploy

The testing and deployment process of Web3 projects is significantly different from traditional web applications. Once deployed, smart contracts are not modifiable (unless using proxy mode), so they must be adequately tested.

Test pyramid

Test typeToolsCoverage contentTarget coverage
Unit TestingHardhat + Chaiboundary conditions for each contract function100%
Integration testingHardhat ForkInteraction between contracts, real on-chain state90%+
FuzzingFoundry FuzzUnknown vulnerabilities are found in random inputsContinuous operation
Formal verificationCertora / HalmosMathematical proof of contract correctnessCritical path
Testnet validationSepolia / MumbaiReal network environment end-to-endComplete process

Hardhat deploys scripts

// scripts/deploy.js - 完整部署流程
const { ethers, upgrades } = require("hardhat");

async function main() {
  const [deployer] = await ethers.getSigners();
  console.log("Deploying with:", deployer.address);

  // 1. 部署代币合约
  const Token = await ethers.getContractFactory("PlatformToken");
  const token = await Token.deploy();
  await token.waitForDeployment();
  console.log("Token deployed:", await token.getAddress());

  // 2. 部署 Timelock(2天延迟)
  const Timelock = await ethers.getContractFactory("TimelockController");
  const timelock = await Timelock.deploy(
    172800, // 2 days
    [], // proposers (Governor合约地址后补)
    ["0x0000000000000000000000000000000000000000"], // executors: anyone
    deployer.address
  );
  await timelock.waitForDeployment();

  // 3. 部署治理合约
  const Governor = await ethers.getContractFactory("PlatformGovernor");
  const governor = await Governor.deploy(
    await token.getAddress(),
    await timelock.getAddress()
  );
  await governor.waitForDeployment();

  // 4. 部署会员合约(可升级代理)
  const Membership = await ethers.getContractFactory("MembershipNFT");
  const membership = await upgrades.deployProxy(Membership, [], {
    initializer: 'initialize',
    kind: 'uups',
  });
  await membership.waitForDeployment();

  // 5. 配置权限
  const PROPOSER_ROLE = await timelock.PROPOSER_ROLE();
  await timelock.grantRole(PROPOSER_ROLE, await governor.getAddress());

  console.log("Deployment complete!");
  console.log({ token, timelock, governor, membership });
}

main().catch(console.error);

CI/CD integration

  • PR submission: Automatically run Hardhat tests + Slither static analysis + gas reports
  • Merge to main: Automatically deploy to the testnet (Sepolia) + front-end preview environment
  • Release Tag: Deploy the mainnet after manual approval, and write the contract address to the front-end environment variable
  • After deployment: Automatically verify the contract source code to Etherscan + update the subgraph configuration

Security audit and compliance

Web3 security audit process

Web3 projects directly manage user funds, and security breaches can lead to irreversible asset losses. A comprehensive security audit is a necessary step before going live.

Common security risks

🔁 Reentrancy attack

The attacker re-enters the contract in an external call, repeatedly withdrawing funds. Protection: Use ReentrancyGuard or CEI mode.

⚡ Flash loan attack

Utilize unsecured loans to manipulate prices within a single transaction. Protection: Use TWAP oracle, multi-block verification.

🔑 Privilege management vulnerability

Admin key compromise or excessive concentration of privileges. Protection: Multi-signature wallet + Timelock + least privilege principle.

📝 Signature replay

Valid signatures are reused to perform multiple operations. Protection: Bind nonce + chainId + expiration time.

Audit process

  1. Internal Code Review: Cross-review by teams to ensure logical correctness
  2. Automated scanning: Slither + Mythril discovers known vulnerability patterns
  3. Fuzz testing: Foundry Fuzz runs continuously > 1 million random inputs
  4. Third-party audit: CertiK / Trail of Bits / OpenZeppelin professional audit
  5. Bug Bounty: Launched a bug bounty program after launch, and continued to be tested by the community
  6. Monitoring and Alerting: Deploy on-chain monitoring (Forta Network) to provide real-time early warning of abnormal operations

Compliance considerations

⚠️ Legal compliance reminders: Token issuance involves securities regulations in various countries, requiring professional legal counsel to assess whether a token constitutes a security. Recommendations: (1) clarify the utility function of the token rather than the investment attributes; (2) to comply with regulatory requirements in your jurisdiction; (3) Implement necessary AML/KYC measures.

Practical case analysis

Here are three real-world examples of different types of Web2 products successfully transforming into Web3, showcasing different migration strategies and technology options:

Case 1: Social Platform → Decentralized Social Networking

DimensionsPre-Transformation (Web2)Post-Transformation (Web3)
User systemMobile Number Registration + OAuthWallet Login + Lens Profile NFT
Content storageMongoDB + CDNArweave Persistent Storage + IPFS Cache
Focus on relationshipsDatabase Join queryOn-chain Follow NFT
Content monetizationAdvertising DivisionNFT minting + token tipping + paid subscription
Content moderationUnified review of the platformCommunity governance voting + reputation system
Migration cycle6 months (progressive)

Case 2: E-commerce platform → decentralized marketplace

DimensionsPre-Transformation (Web2)Post-Transformation (Web3)
Payment systemStripe + PayPalUSDC/ETH on-chain payment + smart contract escrow
Reputation systemIn-platform scoringOn-chain SBT reputation certificate (non-transferable)
Dispute arbitrationCustomer service manual processingKleros Decentralized Arbitration Tribunal
Loyalty programPoints MallERC-20 Loyalty Token (Tradable)
Supply chain traceabilityInternal ERP recordsOn-chain full-link traceability
Migration cycle9 months (core module installment chaining)

Case 3: SaaS platform → decentralized protocol

DimensionsPre-Transformation (Web2)Post-Transformation (Web3)
Subscription paysMonthly/yearly credit cardsToken staking to obtain service credits
API accessAPI Key + Rate LimitToken payment per-call + permissionless access
Product decisionsThe product manager made a decisionDAO governance votes determine the roadmap
Income distributionThe company's profits are retainedProtocol revenue is distributed in proportion to token holdings
OpennessClosed ecologyOpen source license + permissionless fork
Migration cycle12 months (including DAO governance transition)

Development process and cycle

Based on the practical experience of the NovaLinkR team in multiple Web2-to-Web3 projects, the typical migration development process is as follows:

01

Status Assessment and Architecture Planning (2-3 weeks)

Audit the existing system architecture, identify chainable modules, and develop a phased migration plan. Output: Technical assessment report, migration architecture diagram, milestone plan.

02

Smart contract development and audit (4-8 weeks)

Write business contracts, token contracts, and governance contracts. Complete unit testing (100% coverage), fuzz testing, and third-party security audits.

03

Back-end service retrofit (3-6 weeks)

Build on-chain event indexing services, integrate IPFS storage, realize off-chain signature verification, and transform user authentication systems.

04

Front-end DApp upgrade (3-5 weeks)

Integrate wallet connection, implement contract interaction UI, listen to on-chain events, and IPFS file upload components. Maintain UX consistency.

05

Testnet validation and stress testing (2-3 weeks)

System-wide joint commissioning test, gas optimization, boundary condition verification, performance stress test. Early user beta testing.

06

Mainnet Deployment and Data Migration (1-2 weeks)

Contract deployment mainnet, stock data migration, user account mapping, and monitoring alarm configuration. Gradually open the user migration portal.

Project budget reference

Project scaleMigration scopeCycleBudget Range
LightweightWallet login + single contract + token issuance6-8 weeks$30,000 - $60,000
Medium sizeCore business on-chain + DApp front-end + event index12-16 weeks$80,000 - 50,000
Large projectsFully decentralized + DAO governance + multi-chain deployment20-30 weeks00,000 - $500,000
💡 Need professional Web2 to Web3 migration services?

The NovaLinkR team has extensive experience in delivering decentralized systems, providing one-stop transformation solutions from architecture evaluation to contract development, front-end DApps to DAO governance.Contact us todayGet free technical advice and migration assessments.