链上声誉与内容推荐:去中心化算法的信任机制
2024年,YouTube的推荐算法被批评为"制造回音室"——算法推荐给你的内容越来越多地是同质化的观点,你看到的世界越来越窄。如果内容推荐算法迁移到链上,由用户的链上声誉和社区共识驱动,会发生什么?这让我想起电影《社交网络》中的一句话:"我们生活在互联网上,但互联网是由算法塑造的。"在去中心化算法中,信任不再由"中心化评分"决定,而是由"链上声誉"决定。
第一幕:推荐算法的"镜头畸变"
传统推荐算法的问题:
- 黑箱:你不知道算法为什么推荐这个内容给你
- 回音室:算法推荐与你已有观点一致的内容
- 数据垄断:平台掌握所有用户数据,用户无法查看或修改
第二幕:链上声誉推荐合约
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "@openzeppelin/contracts/access/Ownable.sol";
contract ReputationEngine is Ownable {
struct UserProfile {
address addr;
uint256 reputationScore;
uint256 contentCount;
uint256 totalVotes;
uint256 accuracyRate;
uint256 lastActive;
bool isRegistered;
uint256[] votedContent;
}
struct Content {
uint256 id;
address creator;
string title;
string category;
bytes32 contentHash;
uint256 score;
uint256 upvotes;
uint256 downvotes;
uint256 timestamp;
bool isVerified;
}
struct Recommendation {
uint256 id;
address user;
uint256[] contentIds;
uint256 timestamp;
uint256 relevanceScore;
}
mapping(address => UserProfile) public users;
mapping(uint256 => Content) public contents;
mapping(uint256 => Recommendation) public recommendations;
mapping(address => mapping(uint256 => bool)) public hasVoted;
mapping(string => uint256[]) public categoryContent;
uint256 public contentCount;
uint256 public recommendationCount;
uint256 public constant REPUTATION_DECAY = 1; // 每24小时衰减1分
uint256 public constant VOTE_WEIGHT_MULTIPLIER = 10;
event UserRegistered(address indexed user);
event ContentSubmitted(uint256 indexed id, address indexed creator, string title);
event ContentVoted(uint256 indexed contentId, address indexed voter, bool support);
event RecommendationGenerated(uint256 indexed id, address indexed user, uint256 contentCount);
function registerUser() external {
require(!users[msg.sender].isRegistered, "Already registered");
users[msg.sender] = UserProfile({
addr: msg.sender,
reputationScore: 100,
contentCount: 0,
totalVotes: 0,
accuracyRate: 0,
lastActive: block.timestamp,
isRegistered: true,
votedContent: new uint256[](0)
});
emit UserRegistered(msg.sender);
}
function submitContent(
string memory _title,
string memory _category,
bytes32 _contentHash
) external returns (uint256) {
UserProfile storage user = users[msg.sender];
require(user.isRegistered, "Not registered");
contentCount++;
contents[contentCount] = Content({
id: contentCount,
creator: msg.sender,
title: _title,
category: _category,
contentHash: _contentHash,
score: user.reputationScore,
upvotes: 0,
downvotes: 0,
timestamp: block.timestamp,
isVerified: false
});
categoryContent[_category].push(contentCount);
user.contentCount++;
user.reputationScore += 10;
emit ContentSubmitted(contentCount, msg.sender, _title);
return contentCount;
}
function vote(uint256 _contentId, bool _support) external {
UserProfile storage voter = users[msg.sender];
Content storage content = contents[_contentId];
require(voter.isRegistered, "Not registered");
require(!hasVoted[msg.sender][_contentId], "Already voted");
require(msg.sender != content.creator, "Cannot vote own content");
hasVoted[msg.sender][_contentId] = true;
uint256 voteWeight = voter.reputationScore / VOTE_WEIGHT_MULTIPLIER + 1;
if (_support) {
content.upvotes += voteWeight;
content.score += voteWeight;
} else {
content.downvotes += voteWeight;
content.score = content.score > voteWeight ? content.score - voteWeight : 0;
}
voter.totalVotes++;
voter.votedContent.push(_contentId);
voter.reputationScore += 1;
emit ContentVoted(_contentId, msg.sender, _support);
}
function generateRecommendation(address _user, uint256 _count) external returns (uint256) {
UserProfile storage profile = users[_user];
require(profile.isRegistered, "Not registered");
// 基于声誉的推荐算法
uint256[] memory allContent = new uint256[](contentCount);
uint256[] memory scoredContent = new uint256[](contentCount);
uint256 allCount;
for (uint256 i = 1; i <= contentCount; i++) {
Content storage c = contents[i];
if (c.creator != _user) {
allContent[allCount] = i;
scoredContent[allCount] = c.score * profile.reputationScore / 100;
allCount++;
}
}
// 选择前_count个
uint256 selectedCount = _count > allCount ? allCount : _count;
uint256[] memory selected = new uint256[](selectedCount);
for (uint256 i = 0; i < selectedCount; i++) {
uint256 maxScore = 0;
uint256 maxIndex = 0;
for (uint256 j = 0; j < allCount; j++) {
if (scoredContent[j] > maxScore && !_isSelected(selected, i, allContent[j])) {
maxScore = scoredContent[j];
maxIndex = j;
}
}
if (maxScore > 0) {
selected[i] = allContent[maxIndex];
}
}
recommendationCount++;
recommendations[recommendationCount] = Recommendation({
id: recommendationCount,
user: _user,
contentIds: selected,
timestamp: block.timestamp,
relevanceScore: maxScore
});
profile.lastActive = block.timestamp;
emit RecommendationGenerated(recommendationCount, _user, selectedCount);
return recommendationCount;
}
function _isSelected(uint256[] memory _selected, uint256 _len, uint256 _value) internal pure returns (bool) {
for (uint256 i = 0; i < _len; i++) {
if (_selected[i] == _value) return true;
}
return false;
}
function getUserProfile(address _user)
external view returns (UserProfile memory)
{
return users[_user];
}
function getContentInfo(uint256 _contentId)
external view returns (Content memory)
{
return contents[_contentId];
}
function getCategoryContent(string memory _category)
external view returns (uint256[] memory)
{
return categoryContent[_category];
}
}
第三幕:Python分析推荐系统
import numpy as np
import pandas as pd
from typing import Dict, List
import matplotlib.pyplot as plt
class RecommendationAnalyzer:
def __init__(self):
self.contents = []
self.users = []
def generate_synthetic_data(self, n_users: int = 50, n_contents: int = 200):
np.random.seed(42)
categories = ['电影', '科技', '艺术', '音乐', '体育', '教育']
for i in range(n_users):
user = {
'id': i + 1,
'reputation': np.random.uniform(0, 500),
'content_count': np.random.randint(0, 20),
'vote_count': np.random.randint(0, 100),
'accuracy': np.random.uniform(0.5, 1.0)
}
self.users.append(user)
for i in range(n_contents):
content = {
'id': i + 1,
'category': np.random.choice(categories),
'score': np.random.uniform(0, 1000),
'upvotes': np.random.randint(0, 100),
'downvotes': np.random.randint(0, 20),
'creator_reputation': np.random.uniform(0, 500)
}
self.contents.append(content)
def analyze_recommendation_quality(self) -> Dict:
df = pd.DataFrame(self.contents)
user_df = pd.DataFrame(self.users)
return {
'total_content': len(self.contents),
'total_users': len(self.users),
'avg_content_score': df['score'].mean(),
'avg_user_reputation': user_df['reputation'].mean(),
'category_distribution': df['category'].value_counts().to_dict(),
'avg_vote_ratio': (df['upvotes'].sum() / (df['upvotes'].sum() + df['downvotes'].sum())) * 100
}
def generate_report(self) -> str:
eff = self.analyze_recommendation_quality()
report = f"""
=== 链上声誉推荐分析 ===
总内容数: {eff['total_content']}
总用户数: {eff['total_users']}
平均内容得分: {eff['avg_content_score']:.1f}
平均用户声誉: {eff['avg_user_reputation']:.1f}
平均投票支持率: {eff['avg_vote_ratio']:.1f}%
分类分布: {eff['category_distribution']}
"""
return report
if __name__ == "__main__":
analyzer = RecommendationAnalyzer()
analyzer.generate_synthetic_data(50, 200)
report = analyzer.generate_report()
print(report)
第四幕:JavaScript推荐引擎
class ReputationEngine {
constructor(providerUrl, contractAddress) {
this.web3 = new Web3(providerUrl);
this.contract = new this.web3.eth.Contract([], contractAddress);
}
async registerUser() {
return await this.contract.methods.registerUser().send({ from: this.userAccount });
}
async submitContent(title, category, contentHash) {
return await this.contract.methods
.submitContent(title, category, contentHash)
.send({ from: this.userAccount });
}
async vote(contentId, support) {
return await this.contract.methods
.vote(contentId, support)
.send({ from: this.userAccount });
}
async generateRecommendation(user, count) {
return await this.contract.methods
.generateRecommendation(user, count)
.send({ from: this.userAccount });
}
async getUserProfile(user) {
return await this.contract.methods.getUserProfile(user).call();
}
}
const engine = new ReputationEngine('https://mainnet.infura.io/v3/YOUR_ID', '0x...');
第五幕:信任的去中心化叙事
链上声誉系统将"信任"从一个中心化平台的评分变成了一个去中心化的、可验证的、不可篡改的"链上记录"。用户的声誉不再由平台决定,而是由他们在链上的行为——投票、创作、验证——累积而成。这种透明的信任机制,比任何中心化推荐算法都更公平、更可信。
在这个万物皆可Token化的时代,技术的迭代往往比镜头切换更快。作为北京城市学院2021级广播电视编导的毕业生,我始终在影像与区块链的交汇处寻找共鸣。感谢阅读,我是王森涛,让我们在视听与去中心化的世界里,继续探索。