A decentralized video-sharing and monetization platform built using blockchain and DeFi principles. Combines media sharing with decentralized finance — giving creators and users full control over content, earnings, and governance.
A new era of media platforms — moving away from centralized control toward decentralized, user-owned ecosystems with transparent monetization.
Revenue distributed directly to creators, curators, or community pools. Zero intermediaries, zero unfair cuts.
Five fully automated on-chain revenue streams — no platform taking unfair cuts.
Transparency means acknowledging the real challenges of decentralized media platforms.
Open source • IPFS storage • DAO governance • BSC
// SPDX-License-Identifier: MIT pragma solidity ^0.8.24; /* DeFi MyTube - Decentralized Video Platform Prototype - IPFS / Arweave video references - Creator monetization: tips, pay-per-view, subscriptions - Watch-to-earn reward tokens - DAO governance with token-weighted voting WARNING: Educational only, not audited */ interface IERC20 { function transfer (address to, uint256 value) external returns (bool); function transferFrom(address from, address to, uint256 value) external returns (bool); function balanceOf (address user) external view returns (uint256); } contract DeFiMyTube { uint256 public constant BPS = 10_000; IERC20 public paymentToken; // stablecoin or native token IERC20 public rewardToken; // watch-to-earn / governance token address public treasury; constructor(IERC20 _pay, IERC20 _reward, address _treasury) { paymentToken = _pay; rewardToken = _reward; treasury = _treasury; } // ── VIDEO DATA ───────────────────────────────── struct Video { address creator; string contentHash; // IPFS / Arweave CID uint256 tipTotal; uint256 price; // 0 = free bool active; } uint256 public videoCounter; mapping(uint256 => Video) public videos; event VideoUploaded (uint256 indexed id, address indexed creator, string hash); event VideoTipped (uint256 indexed id, address indexed user, uint256 amount); event VideoPurchased(uint256 indexed id, address indexed user); event RewardsClaimed(address indexed user, uint256 amount); // ── SUBSCRIPTIONS ────────────────────────────── struct Subscription { uint256 monthlyFee; mapping(address => uint256) expiry; } mapping(address => Subscription) internal subscriptions; event Subscribed(address indexed user, address indexed creator); // ── GOVERNANCE ───────────────────────────────── struct Proposal { string description; uint256 votesFor; uint256 votesAgainst; uint256 deadline; bool executed; } uint256 public proposalCounter; mapping(uint256 => Proposal) public proposals; mapping(uint256 => mapping(address => bool)) public voted; event ProposalCreated(uint256 id, string desc); event Voted(uint256 id, address voter, bool support); // ── REWARDS ──────────────────────────────────── mapping(address => uint256) public pendingRewards; // ── VIDEO FUNCTIONS ──────────────────────────── function uploadVideo(string calldata hash, uint256 price) external { videos[++videoCounter] = Video({ creator: msg.sender, contentHash: hash, tipTotal: 0, price: price, active: true }); emit VideoUploaded(videoCounter, msg.sender, hash); } function tipCreator(uint256 videoId, uint256 amount) external { Video storage v = videos[videoId]; require(v.active, "Inactive"); paymentToken.transferFrom(msg.sender, address(this), amount); uint256 creatorShare = (amount * 9500) / BPS; // 95% to creator paymentToken.transfer(v.creator, creatorShare); paymentToken.transfer(treasury, amount - creatorShare); v.tipTotal += amount; emit VideoTipped(videoId, msg.sender, amount); } function purchaseVideo(uint256 videoId) external { Video storage v = videos[videoId]; require(v.active && v.price > 0, "Invalid"); paymentToken.transferFrom(msg.sender, address(this), v.price); uint256 creatorShare = (v.price * 9000) / BPS; // 90% to creator paymentToken.transfer(v.creator, creatorShare); paymentToken.transfer(treasury, v.price - creatorShare); pendingRewards[msg.sender] += v.price / 10; // reward viewer emit VideoPurchased(videoId, msg.sender); } // ── SUBSCRIPTIONS ────────────────────────────── function setSubscriptionPrice(uint256 monthlyFee) external { subscriptions[msg.sender].monthlyFee = monthlyFee; } function subscribe(address creator) external { uint256 fee = subscriptions[creator].monthlyFee; require(fee > 0, "No subscription set"); paymentToken.transferFrom(msg.sender, address(this), fee); paymentToken.transfer(creator, (fee * 9000) / BPS); paymentToken.transfer(treasury, fee / 10); subscriptions[creator].expiry[msg.sender] = block.timestamp + 30 days; emit Subscribed(msg.sender, creator); } function isSubscribed(address user, address creator) external view returns (bool) { return subscriptions[creator].expiry[user] >= block.timestamp; } // ── REWARD CLAIMING ──────────────────────────── function claimRewards() external { uint256 amt = pendingRewards[msg.sender]; require(amt > 0, "No rewards"); pendingRewards[msg.sender] = 0; rewardToken.transfer(msg.sender, amt); emit RewardsClaimed(msg.sender, amt); } // ── GOVERNANCE DAO ───────────────────────────── function createProposal(string calldata desc, uint256 duration) external { proposals[++proposalCounter] = Proposal({ description: desc, votesFor: 0, votesAgainst: 0, deadline: block.timestamp + duration, executed: false }); emit ProposalCreated(proposalCounter, desc); } function vote(uint256 proposalId, bool support) external { Proposal storage p = proposals[proposalId]; require(block.timestamp < p.deadline, "Voting ended"); require(!voted[proposalId][msg.sender], "Already voted"); uint256 weight = rewardToken.balanceOf(msg.sender); require(weight > 0, "No voting power"); voted[proposalId][msg.sender] = true; if (support) p.votesFor += weight; else p.votesAgainst += weight; emit Voted(proposalId, msg.sender, support); } }
Multi-layer protection for all creator funds, viewer rewards, and DAO governance on-chain.