王森涛
发布于 2026-08-03 / 0 阅读
0
0

链上治理与内容共创:从Web2评论到DAO提案

链上治理与内容共创:从Web2评论到DAO提案

2026年,内容创作的"范式"正在从"Web2评论"转向"DAO提案"。从"YouTube的评论区"到"DAO的治理论坛",从"点赞"到"投票",从"创作者决定"到"社区共创"——链上治理正在"重塑"内容创作的"权力"结构。这是"内容"的"民主化"革命——不是"创作者"决定"一切",而是"社区"共同"决定"。

第一幕:从"Web2评论"到"链上治理"

第一场:Web2的"评论"——"表面"的"参与"

Web2的"内容"参与方式:

  1. 评论:用户"评论"内容——"表达"意见、"分享"观点、"讨论"话题。
  2. 点赞:用户"点赞"内容——"表达"喜欢、"支持"创作者。
  3. 分享:用户"分享"内容——"传播"内容、"扩大"影响。
  4. 投票:平台"投票"——"YouTube"的"投票"功能、"Twitter"的"投票"功能。

第二场:Web2评论的"局限性"

Web2评论的"局限性":

  1. 表面参与:评论、点赞、分享——"表面"的"参与"——"没有"真正的"决策权"。
  2. 中心化控制:平台"控制"内容——"算法"决定"推荐"、"审查"决定"删除"。
  3. 价值流失:用户"贡献"价值——"内容"、"讨论"、"流量"——但"平台"获得"收益"。

第三场:从"评论"到"提案"——"DAO"的"治理"模式

DAO的"治理"模式:

  1. 提案(Proposal):社区成员"提出"提案——"内容"方向、"资金"分配、"规则"修改。
  2. 投票(Voting):Token持有者"投票"——"赞成"、"反对"、"弃权"。
  3. 执行(Execution):通过的提案"自动"执行——"智能合约"执行"决策"。

DAO governance

第二幕:内容DAO的"治理"架构

第一场:从"创作者DAO"到"内容DAO"——"类型"的"区分"

内容DAO的"类型":

  1. 创作者DAO:一个"创作者"的"DAO"——"粉丝"参与"治理"——"合作"、"收入"、"方向"。
  2. 内容DAO:一个"内容"的"DAO"——"社区"共同"创作"和"治理"——"Wiki"、"开源"、"媒体"。
  3. 平台DAO:一个"平台"的"DAO"——"用户"参与"治理"——"规则"、"算法"、"收入"。

第二场:从"提案"到"执行"——"治理"的"流程"

内容DAO的"治理"流程:

  1. 讨论阶段:社区成员在"论坛"讨论"提案"——"Discourse"、"Discord"、"Telegram"。
  2. 提案阶段:提案"正式"提交——"Tally"、"Snapshot"、"Governor"。
  3. 投票阶段:Token持有者"投票"——"代币"投票、"二次方"投票、"声誉"投票。
  4. 执行阶段:通过的提案"执行"——"智能合约"、"多签"、"时间锁"。

第三场:从"Web2评论"到"Web3提案"——"参与"的"升级"

Web2评论到Web3提案的"升级":

  1. 从"评论"到"提案":从"表达"意见到"提出"方案。
  2. 从"点赞"到"投票":从"表达"支持到"决策"。
  3. 从"分享"到"执行":从"传播"内容到"执行"决策。
  4. 从"平台"到"DAO":从"中心化"平台到"去中心化"组织。
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;

import "@openzeppelin/contracts/access/AccessControl.sol";
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "@openzeppelin/contracts/utils/ReentrancyGuard.sol";

contract ContentDAO is AccessControl, ReentrancyGuard {
    bytes32 public constant CREATOR_ROLE = keccak256("CREATOR_ROLE");
    bytes32 public constant CURATOR_ROLE = keccak256("CURATOR_ROLE");

    enum ProposalType {
        CONTENT_DIRECTION, FUND_ALLOCATION, RULE_CHANGE, MEMBER_ADMISSION, COLLABORATION
    }

    enum ProposalStatus {
        PENDING, ACTIVE, APPROVED, REJECTED, EXECUTED, CANCELLED
    }

    enum ContentCategory {
        ARTICLE, VIDEO, MUSIC, NFT, PODCAST, EVENT, RESEARCH
    }

    struct Proposal {
        uint256 proposalId;
        address proposer;
        string title;
        string description;
        string ipfsCID;
        ProposalType propType;
        ProposalStatus status;
        uint256 forVotes;
        uint256 againstVotes;
        uint256 startTime;
        uint256 endTime;
        uint256 quorum;
        bool executed;
    }

    struct ContentProject {
        uint256 projectId;
        string title;
        string description;
        address creator;
        ContentCategory category;
        uint256 fundingGoal;
        uint256 totalFunded;
        uint256[] proposalIds;
        bool isActive;
    }

    struct Vote {
        address voter;
        uint256 proposalId;
        bool support;
        uint256 votingPower;
        uint256 timestamp;
    }

    IERC20 public governanceToken;
    uint256 public votingDelay = 1 days;
    uint256 public votingPeriod = 7 days;
    uint256 public quorumPercentage = 10;
    uint256 public proposalCount;
    uint256 public projectCount;

    mapping(uint256 => Proposal) public proposals;
    mapping(uint256 => ContentProject) public projects;
    mapping(uint256 => mapping(address => Vote)) public votes;
    mapping(address => uint256) public reputationScore;
    mapping(address => uint256) public contributionCount;

    event ProposalCreated(uint256 indexed proposalId, address indexed proposer, string title);
    event VoteCast(uint256 indexed proposalId, address indexed voter, bool support, uint256 power);
    event ProposalExecuted(uint256 indexed proposalId);
    event ProjectCreated(uint256 indexed projectId, string title, address creator);

    constructor(address _governanceToken) {
        governanceToken = IERC20(_governanceToken);
        _grantRole(DEFAULT_ADMIN_ROLE, msg.sender);
        _grantRole(CREATOR_ROLE, msg.sender);
    }

    function createProposal(
        string memory _title,
        string memory _description,
        string memory _ipfsCID,
        ProposalType _propType
    ) external returns (uint256) {
        require(bytes(_title).length > 0, "Title required");
        proposalCount++;

        proposals[proposalCount] = Proposal({
            proposalId: proposalCount,
            proposer: msg.sender,
            title: _title,
            description: _description,
            ipfsCID: _ipfsCID,
            propType: _propType,
            status: ProposalStatus.ACTIVE,
            forVotes: 0,
            againstVotes: 0,
            startTime: block.timestamp + votingDelay,
            endTime: block.timestamp + votingDelay + votingPeriod,
            quorum: 0,
            executed: false
        });

        emit ProposalCreated(proposalCount, msg.sender, _title);
        return proposalCount;
    }

    function castVote(uint256 _proposalId, bool _support) external nonReentrant {
        Proposal storage proposal = proposals[_proposalId];
        require(proposal.status == ProposalStatus.ACTIVE, "Proposal not active");
        require(block.timestamp >= proposal.startTime, "Voting not started");
        require(block.timestamp <= proposal.endTime, "Voting ended");
        require(votes[_proposalId][msg.sender].timestamp == 0, "Already voted");

        uint256 votingPower = governanceToken.balanceOf(msg.sender);
        require(votingPower > 0, "No voting power");

        votes[_proposalId][msg.sender] = Vote({
            voter: msg.sender,
            proposalId: _proposalId,
            support: _support,
            votingPower: votingPower,
            timestamp: block.timestamp
        });

        if (_support) {
            proposal.forVotes += votingPower;
        } else {
            proposal.againstVotes += votingPower;
        }

        emit VoteCast(_proposalId, msg.sender, _support, votingPower);
    }

    function executeProposal(uint256 _proposalId) external onlyRole(CURATOR_ROLE) {
        Proposal storage proposal = proposals[_proposalId];
        require(proposal.status == ProposalStatus.ACTIVE, "Not active");
        require(block.timestamp > proposal.endTime, "Voting still active");
        require(!proposal.executed, "Already executed");

        uint256 totalVotes = proposal.forVotes + proposal.againstVotes;
        uint256 totalSupply = governanceToken.totalSupply();
        require(totalVotes * 100 >= totalSupply * quorumPercentage, "Quorum not met");

        if (proposal.forVotes > proposal.againstVotes) {
            proposal.status = ProposalStatus.APPROVED;
            proposal.executed = true;
            emit ProposalExecuted(_proposalId);
        } else {
            proposal.status = ProposalStatus.REJECTED;
        }
    }

    function createContentProject(
        string memory _title,
        string memory _description,
        ContentCategory _category,
        uint256 _fundingGoal
    ) external onlyRole(CREATOR_ROLE) returns (uint256) {
        projectCount++;
        projects[projectCount] = ContentProject({
            projectId: projectCount,
            title: _title,
            description: _description,
            creator: msg.sender,
            category: _category,
            fundingGoal: _fundingGoal,
            totalFunded: 0,
            proposalIds: new uint256[](0),
            isActive: true
        });

        emit ProjectCreated(projectCount, _title, msg.sender);
        return projectCount;
    }

    function contributeToProject(uint256 _projectId) external payable nonReentrant {
        ContentProject storage project = projects[_projectId];
        require(project.isActive, "Project not active");
        project.totalFunded += msg.value;
    }

    function getProposalVotes(uint256 _proposalId) external view returns (uint256 forVotes, uint256 againstVotes) {
        Proposal storage proposal = proposals[_proposalId];
        return (proposal.forVotes, proposal.againstVotes);
    }
}

第三幕:内容共创的"案例"

第一场:从"Mirror"到"内容DAO"——"去中心化"的"内容平台"

Mirror是一个"去中心化"的内容平台:

  1. 写作:创作者"发布"文章——"链上"存储、"NFT"铸造、"Token"激励。
  2. 众筹:创作者"发起"众筹——"社区"支持、"Token"分配、"收入"共享。
  3. 治理:社区"投票"决定——"内容"方向、"资金"分配、"平台"规则。

第二场:从"Bankless"到"DAO媒体"——"去中心化"的"媒体"

Bankless是一个"DAO"驱动的"媒体"品牌:

  1. 内容社区:Bankless的"社区"成员"参与"内容的"创作"和"策展"。
  2. Token激励:BANK Token"激励"社区"贡献"——"写作"、"编辑"、"策展"。
  3. 治理参与:Token持有者"投票"决定"内容"方向——"焦点"主题、"嘉宾"邀请。

第三场:从"内容DAO"到"创作者经济"——"去中心化"的"创作者经济"

内容DAO在"创作者经济"中的"角色":

  1. 创作者与粉丝:创作者"发布"提案,粉丝"投票"决定——"内容"方向、"合作"项目。
  2. 创作者与赞助商:赞助商"赞助"提案——"Token"、"NFT"、"资金"。
  3. 创作者与平台:平台"治理"由DAO"决定"——"规则"、"算法"、"收入"分配。
import json
from typing import Dict, List, Optional
from dataclasses import dataclass
from datetime import datetime, timedelta
from web3 import Web3
import hashlib

@dataclass
class Proposal:
    proposal_id: int
    title: str
    description: str
    proposer: str
    proposal_type: str
    status: str
    for_votes: int
    against_votes: int
    created_at: datetime
    voting_end: datetime
    quorum: int

class ContentDAOClient:
    def __init__(self, rpc_url: str, dao_address: str):
        self.w3 = Web3(Web3.HTTPProvider(rpc_url))
        self.dao_address = dao_address
        self.proposals: Dict[int, Proposal] = {}
        self.votes: Dict[int, Dict[str, Dict]] = {}
        self.reputation: Dict[str, int] = {}

    def create_proposal(
        self,
        title: str,
        description: str,
        proposal_type: str,
        proposer: str
    ) -> Proposal:
        proposal_id = len(self.proposals) + 1
        proposal = Proposal(
            proposal_id=proposal_id,
            title=title,
            description=description,
            proposer=proposer,
            proposal_type=proposal_type,
            status='active',
            for_votes=0,
            against_votes=0,
            created_at=datetime.now(),
            voting_end=datetime.now() + timedelta(days=7),
            quorum=0
        )
        self.proposals[proposal_id] = proposal
        return proposal

    def cast_vote(self, proposal_id: int, voter: str, support: bool, voting_power: int) -> Dict:
        if proposal_id not in self.proposals:
            raise ValueError("Proposal not found")

        proposal = self.proposals[proposal_id]
        if proposal.status != 'active':
            raise ValueError("Proposal not active")
        if datetime.now() > proposal.voting_end:
            raise ValueError("Voting ended")

        if proposal_id not in self.votes:
            self.votes[proposal_id] = {}
        if voter in self.votes[proposal_id]:
            raise ValueError("Already voted")

        self.votes[proposal_id][voter] = {
            'support': support,
            'voting_power': voting_power,
            'timestamp': datetime.now().isoformat()
        }

        if support:
            proposal.for_votes += voting_power
        else:
            proposal.against_votes += voting_power

        return {
            'proposal_id': proposal_id,
            'voter': voter,
            'support': support,
            'voting_power': voting_power
        }

    def execute_proposal(self, proposal_id: int) -> Dict:
        proposal = self.proposals[proposal_id]
        if proposal.status != 'active':
            return {'success': False, 'error': 'Not active'}

        total_votes = proposal.for_votes + proposal.against_votes
        if total_votes < proposal.quorum:
            return {'success': False, 'error': 'Quorum not met'}

        if proposal.for_votes > proposal.against_votes:
            proposal.status = 'approved'
            return {'success': True, 'result': 'approved'}
        else:
            proposal.status = 'rejected'
            return {'success': True, 'result': 'rejected'}

    def create_content_project(
        self,
        title: str,
        description: str,
        category: str,
        creator: str,
        funding_goal: int
    ) -> Dict:
        project_id = hashlib.sha256(f"{title}{creator}{datetime.now()}".encode()).hexdigest()[:8]
        project = {
            'project_id': project_id,
            'title': title,
            'description': description,
            'creator': creator,
            'category': category,
            'funding_goal': funding_goal,
            'total_funded': 0,
            'proposals': [],
            'is_active': True,
            'created_at': datetime.now().isoformat()
        }
        return project

    def get_collaboration_score(self, address: str) -> Dict:
        score = self.reputation.get(address, 0)
        proposal_count = sum(1 for p in self.proposals.values() if p.proposer == address)
        vote_count = sum(1 for v in self.votes.values() if address in v)

        return {
            'address': address,
            'reputation_score': score,
            'proposals_created': proposal_count,
            'votes_cast': vote_count,
            'collaboration_level': 'high' if score > 80 else 'medium' if score > 40 else 'low'
        }

    def suggest_content_direction(self, community_votes: Dict[str, int]) -> Dict:
        total = sum(community_votes.values())
        if total == 0:
            return {'direction': 'unknown', 'confidence': 0}

        directions = {
            'educational': 0,
            'entertainment': 0,
            'news': 0,
            'research': 0,
            'collaboration': 0
        }

        for topic, votes in community_votes.items():
            if topic in directions:
                directions[topic] = votes / total * 100

        best_direction = max(directions, key=directions.get)
        return {
            'direction': best_direction,
            'confidence': directions[best_direction],
            'all_directions': directions
        }

dao = ContentDAOClient('https://eth-mainnet.g.alchemy.com/v2/YOUR_KEY', '0xDAO')
proposal = dao.create_proposal(
    "Create a documentary series about DeFi",
    "Proposal to fund a 5-part documentary series exploring DeFi protocols",
    "content_direction",
    "0xCreator"
)
print(f"Proposal #{proposal.proposal_id}: {proposal.title}")

Content DAO

第四幕:从"Web2评论"到"Web3提案"——"参与"的"未来"

第一场:从"评论"到"策展"——"内容"的"策展"经济

内容策展的"经济"模型:

  1. 策展人(Curator):用户"策展"内容——"推荐"、"评分"、"筛选"。
  2. 策展Token:策展人"获得"策展Token——"激励"策展"行为"。
  3. 策展DAO:策展人"组成"DAO——"共同"决定"内容"的质量和"方向"。

第二场:从"内容DAO"到"跨DAO协作"——"内容"的"跨组织"协作

跨DAO协作的"模式":

  1. 内容DAO与DeFi DAO:内容DAO"创作"DeFi"内容",DeFi DAO"赞助"内容"创作"。
  2. 内容DAO与NFT DAO:内容DAO"创作"NFT"内容",NFT DAO"发行"NFT"收藏"。
  3. 内容DAO与媒体DAO:内容DAO"创作"内容,媒体DAO"分发"内容。

第三场:从"Web2评论"到"Web3治理"——"参与"的"民主化"

内容参与"民主化"的"未来":

  1. 从"评论"到"决策":用户从"评论"内容到"决定"内容。
  2. 从"被动"到"主动":用户从"被动"消费到"主动"参与。
  3. 从"消费者"到"参与者":用户从"内容"消费者到"内容"参与者。
const { ethers } = require('ethers');
const axios = require('axios');

class ContentDAOGovernance {
  constructor(providerUrl, daoAddress, governanceTokenAddress) {
    this.provider = new ethers.providers.JsonRpcProvider(providerUrl);
    this.daoAddress = daoAddress;
    this.governanceTokenAddress = governanceTokenAddress;
    this.proposals = new Map();
    this.votes = new Map();
    this.reputation = new Map();
  }

  async createProposal(title, description, proposalType, proposer) {
    const proposalId = this.proposals.size + 1;
    const proposal = {
      id: proposalId,
      title,
      description,
      proposer,
      type: proposalType,
      status: 'active',
      forVotes: ethers.BigNumber.from(0),
      againstVotes: ethers.BigNumber.from(0),
      createdAt: Math.floor(Date.now() / 1000),
      votingEnds: Math.floor(Date.now() / 1000) + 7 * 86400,
      executed: false,
      quorum: ethers.BigNumber.from(1000)
    };

    this.proposals.set(proposalId, proposal);
    return proposal;
  }

  async castVote(proposalId, voter, support, votingPower) {
    const proposal = this.proposals.get(proposalId);
    if (!proposal) throw new Error('Proposal not found');
    if (proposal.status !== 'active') throw new Error('Proposal not active');

    const voteKey = `${proposalId}-${voter}`;
    if (this.votes.has(voteKey)) throw new Error('Already voted');

    const vote = {
      voter,
      proposalId,
      support,
      votingPower: ethers.BigNumber.from(votingPower),
      timestamp: Math.floor(Date.now() / 1000)
    };

    this.votes.set(voteKey, vote);

    if (support) {
      proposal.forVotes = proposal.forVotes.add(votingPower);
    } else {
      proposal.againstVotes = proposal.againstVotes.add(votingPower);
    }

    return vote;
  }

  async executeProposal(proposalId) {
    const proposal = this.proposals.get(proposalId);
    if (!proposal) throw new Error('Proposal not found');
    if (proposal.executed) throw new Error('Already executed');

    const totalVotes = proposal.forVotes.add(proposal.againstVotes);
    if (totalVotes.lt(proposal.quorum)) {
      throw new Error('Quorum not met');
    }

    proposal.executed = true;
    proposal.status = proposal.forVotes.gt(proposal.againstVotes) ? 'approved' : 'rejected';

    return {
      proposalId,
      status: proposal.status,
      forVotes: proposal.forVotes.toString(),
      againstVotes: proposal.againstVotes.toString()
    };
  }

  async createContentProject(title, description, category, creator, fundingGoal) {
    const projectId = ethers.utils.keccak256(
      ethers.utils.toUtf8Bytes(`${title}${creator}${Date.now()}`)
    ).slice(0, 10);

    const project = {
      projectId,
      title,
      description,
      creator,
      category,
      fundingGoal: ethers.utils.parseEther(fundingGoal.toString()),
      totalFunded: ethers.BigNumber.from(0),
      proposals: [],
      isActive: true,
      createdAt: Math.floor(Date.now() / 1000)
    };

    return project;
  }

  async contributeToProject(project, amount) {
    project.totalFunded = project.totalFunded.add(ethers.utils.parseEther(amount.toString()));
    return project;
  }

  async getCommunitySentiment(proposalId) {
    const proposal = this.proposals.get(proposalId);
    if (!proposal) return { sentiment: 'unknown', confidence: 0 };

    const totalVotes = proposal.forVotes.add(proposal.againstVotes);
    if (totalVotes.isZero()) return { sentiment: 'no_votes', confidence: 0 };

    const forPercentage = proposal.forVotes.mul(100).div(totalVotes).toNumber();
    return {
      sentiment: forPercentage > 66 ? 'strong_approval' : forPercentage > 50 ? 'approval' : 'rejection',
      confidence: Math.abs(forPercentage - 50) * 2,
      forPercentage
    };
  }

  async calculateReputation(address) {
    let score = this.reputation.get(address) || 0;
    const userProposals = Array.from(this.proposals.values())
      .filter(p => p.proposer === address);
    const userVotes = Array.from(this.votes.values())
      .filter(v => v.voter === address);

    score += userProposals.length * 10;
    score += userVotes.length * 5;

    this.reputation.set(address, score);
    return {
      address,
      score,
      proposalsCreated: userProposals.length,
      votesCast: userVotes.length,
      level: score > 80 ? 'trusted' : score > 40 ? 'active' : 'newcomer'
    };
  }
}

const governance = new ContentDAOGovernance(
  'https://eth-mainnet.g.alchemy.com/v2/YOUR_KEY',
  '0xDAO',
  '0xToken'
);
governance.createProposal(
  'Fund a documentary about DeFi protocols',
  '5-part documentary series exploring Aave, Compound, Uniswap',
  'content_direction',
  '0xCreator'
).then(p => console.log('Proposal:', p.id));

Web3 governance

终场:从"评论"到"提案"——"内容"的"民主化"

从Web2的"评论"到Web3的"提案",从"点赞"到"投票",从"创作者决定"到"社区共创"——链上治理正在"重塑"内容创作的"权力"结构。这不是"技术"的"进步",而是"社会"的"变革"——内容创作的"民主化"。

在这个万物皆可Token化的时代,技术的迭代往往比镜头切换更快。作为北京城市学院2021级广播电视编导的毕业生,我始终在影像与区块链的交汇处寻找共鸣。感谢阅读,我是王森涛,让我们在视听与去中心化的世界里,继续探索。


评论