paint-brush
Как создать сетевой протокол оплаты за просмотр на Rootstockк@nescampos
376 чтения
376 чтения

Как создать сетевой протокол оплаты за просмотр на Rootstock

к Néstor Campos9m2024/11/30
Read on Terminal Reader

Слишком долго; Читать

Monetizado — это on-chain-протокол оплаты за просмотр. Он позволяет монетизировать любую веб-страницу и статический контент через Web3.0. Его можно использовать для защиты страниц, чтобы их могли видеть только подписчики.
featured image - Как создать сетевой протокол оплаты за просмотр на Rootstock
Néstor Campos HackerNoon profile picture

В экономике внимания (Web 2.0) пользователей «подталкивают» платить за подписку, чтобы получить доступ к эксклюзивному контенту (всем видам контента, включая контент для взрослых), но ничто не гарантирует, что вы получите те преимущества, за которые платите, либо потому, что создатель контента не продолжает создавать что-то новое, либо вам приходится оформлять подписку на длительные периоды, когда вы хотите платить только за то, что потребляете.


Однако Web 3.0, экономика намерений, дает пользователям возможность платить только за то, что они потребляют, а не за длительные периоды, посредством микроплатежей. В свою очередь, это стимулирует создателей контента оставаться в курсе новых творений, получая свой доход немедленно, с очень низкими затратами, не завися от централизованных шлюзов.

Monetizado, сетевой протокол оплаты за просмотр

Monetizado — это он-чейн-платформа с оплатой за просмотр, которая позволяет монетизировать любую веб-страницу и статический контент (если у вас нет доступа к бэкэнду для внесения изменений) через Web3.


Вы можете внедрить Monetizado на новостных сайтах, в социальных сетях, на порталах с эксклюзивным контентом и т. д. Вы также можете использовать его, чтобы мотивировать пользователей платить и не видеть рекламу на ваших сайтах.

Функции

Monetizado позволяет вам:

  • Укажите защищенный контент с определенной суммой, которую пользователи должны заплатить за доступ.
  • Просмотрите созданный вами защищенный контент.
  • Вашим подписчикам/пользователям: платите за просмотр вашего контента.
  • Проверьте, имеет ли пользователь доступ к вашему контенту.
  • При необходимости измените стоимость доступа к контенту.
  • Снимите защиту с контента (если вы хотите сделать его доступным для всех на некоторое время).
  • Выведите деньги, собранные за ваш контент.

Вариант использования

Вы можете использовать monetized для защиты страниц, чтобы их могли видеть только подписчики, например:

  • Новостные порталы.
  • Видео.
  • Аудио.
  • Файлы
  • Блоги.
  • Социальные сети.
  • И многое другое.

Стек разработки

Для создания этой платформы мы использовали:


  • Solidity для смарт-контракта
  • Ремикс, для развертывания смарт-контракта
  • Тестовая сеть Rootstock , как сеть для проекта
  • Javascript для создания SDK и интеграции с веб-сайтами.


Наш смарт-контракт довольно прост и позволяет вам указать название контента, который будет монетизироваться, сумму (в rBTC) и несколько функций для включения/отключения контента, а также оплаты и получения платежей и т. д.


MonetizadoLibrary.sol

 // SPDX-License-Identifier: MIT pragma solidity ^0.8.0; library MonetizadoLibrary { struct ProtectedContent { string name; uint256 accessCost; bool isProtected; uint256 sequenceId; address creator; uint256 amountAvailable; uint256 amountCollected; mapping(address => Subscriber) subscribers; } struct Subscriber { bool paid; uint256 amount; } }


Monetizadov1.sol

 // SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "./MonetizadoLibrary.sol"; contract Monetizadov1 { // Struct with info about the protected content (for paying to access) struct ProtectedContentInfo { string name; uint256 accessCost; bool isProtected; uint256 sequenceId; address creator; uint256 amountAvailable; uint256 amountCollected; } mapping(address => bool) private creators; mapping(address => bool) public hosting; mapping(address => MonetizadoLibrary.ProtectedContent[]) private paginasProtegidas; event GrantedAccess(address usuario, address creator, uint256 sequenceId); address private _owner; uint256 private _platformFeePercentage; uint256 private _platformBalance; modifier onlyOwner() { require(msg.sender == _owner, "Only the owner can call this function"); _; } constructor() { _owner = msg.sender; _platformFeePercentage = 0; _platformBalance = 0; } function addProtectedContent(string memory name, uint256 accessCost) public returns (uint256) { uint256 cantidadPaginasCreador = paginasProtegidas[msg.sender].length; MonetizadoLibrary.ProtectedContent[] storage paginas = paginasProtegidas[msg.sender]; MonetizadoLibrary.ProtectedContent storage pagina = paginas.push(); pagina.name = name; pagina.accessCost = accessCost; pagina.isProtected = true; pagina.sequenceId = cantidadPaginasCreador; pagina.creator = msg.sender; pagina.amountCollected = 0; pagina.amountAvailable = 0; creators[msg.sender] = true; return cantidadPaginasCreador; } function getProtectedContentsForCurrentUser() public view returns (ProtectedContentInfo[] memory) { uint256 cantidadPaginasPorCreador = paginasProtegidas[msg.sender].length; ProtectedContentInfo[] memory paginas = new ProtectedContentInfo[](cantidadPaginasPorCreador); for (uint256 i = 0; i < cantidadPaginasPorCreador; i++) { MonetizadoLibrary.ProtectedContent storage pagina = paginasProtegidas[msg.sender][i]; paginas[i] = ProtectedContentInfo(pagina.name, pagina.accessCost, pagina.isProtected, pagina.sequenceId, pagina.creator, pagina.amountAvailable, pagina.amountCollected); } return paginas; } function getProtectedContentByAddressAndId(address creator, uint256 sequenceId) public view returns (ProtectedContentInfo memory) { MonetizadoLibrary.ProtectedContent storage pagina = paginasProtegidas[creator][sequenceId]; ProtectedContentInfo memory paginas = ProtectedContentInfo(pagina.name, pagina.accessCost, pagina.isProtected, pagina.sequenceId, pagina.creator, pagina.amountAvailable, pagina.amountCollected); return paginas; } function payAccess(address creator, uint256 sequenceId) external payable { MonetizadoLibrary.ProtectedContent storage pagina = paginasProtegidas[creator][sequenceId]; require(msg.value == pagina.accessCost, "Incorrect payment amount"); require(pagina.isProtected == true, "The page is not protected and you do not need to pay access"); MonetizadoLibrary.Subscriber storage subscriber = pagina.subscribers[msg.sender]; subscriber.paid = true; subscriber.amount = msg.value; pagina.amountCollected += msg.value; pagina.amountAvailable += msg.value; emit GrantedAccess(msg.sender, creator, sequenceId); } function currentUserHasAccess(address creator, uint256 sequenceId) public view returns(bool) { MonetizadoLibrary.ProtectedContent storage pagina = paginasProtegidas[creator][sequenceId]; return pagina.subscribers[msg.sender].paid; } function changeAccessCost(uint256 sequenceId, uint256 newCost) external { MonetizadoLibrary.ProtectedContent storage pagina = paginasProtegidas[msg.sender][sequenceId]; pagina.accessCost = newCost; } function unprotectContent(uint256 sequenceId) external { MonetizadoLibrary.ProtectedContent storage pagina = paginasProtegidas[msg.sender][sequenceId]; pagina.isProtected = false; } function protectContent(uint256 sequenceId) external { MonetizadoLibrary.ProtectedContent storage pagina = paginasProtegidas[msg.sender][sequenceId]; pagina.isProtected = true; } function changePlatformFee(uint256 feePlatform) external onlyOwner { require(feePlatform <= 100, "The fee should be between 0.01 to 1% (1 - 100 in a 10000 scale)"); _platformFeePercentage = feePlatform; } function withdrawMoneyFromContent(uint256 sequenceId,uint256 amount) external { MonetizadoLibrary.ProtectedContent storage pagina = paginasProtegidas[msg.sender][sequenceId]; require(pagina.amountAvailable >= amount, "Insufficient balance"); uint256 amountForPlatform = amount * _platformFeePercentage / 10000; _platformBalance += amountForPlatform; payable(_owner).transfer(amountForPlatform); payable(msg.sender).transfer(amount - amountForPlatform); pagina.amountAvailable -= amount; } function getPlatformFee() public view returns(uint256) { return _platformFeePercentage; } function getPlatformBalance() public view returns(uint256) { return _platformBalance; } function withdrawMoneyPlatform(uint256 amount) external onlyOwner { require(_platformBalance >= amount, "Insufficient balance"); payable(msg.sender).transfer(amount); _platformBalance -= amount; } }


Кроме того, мы создали Javascript SDK , который позволяет использовать смарт-контракт на всех веб-сайтах, особенно для пользователей, желающих платить за доступ к определенному контенту.

Как использовать

  1. На странице, которую вы хотите монетизировать, импортируйте Web3.JS и Ethers.JS. Вы можете сделать это из CDN, например:
 <script src="https://cdn.jsdelivr.net/npm/web3@latest/dist/web3.min.js"></script> <script src="https://cdn.ethers.io/lib/ethers-5.2.umd.min.js" type="application/javascript"></script>


  1. Загрузите и импортируйте monetizadov1.js
 <script src="./monetizado.js"></script>
  1. Создайте защищенный контент с помощью смарт-контракта или в Менеджер .


  2. Добавьте тег ссылки в заголовок HTML-кода вашей страницы с атрибутом «rel» со значением «monetized», а в href он должен иметь следующую структуру:


  • сеть: это сеть, в которой защищен контент.


  • creator_address: Это адрес (0x..) создателя контента. Это может быть ваш адрес, если вы создатель.


  • sequence_id: Это идентификатор, по которому контракт был расторгнут, когда вы указали новый защищенный контент (начинается с 0 и далее, является числовым).


Например:

 <link rel="monetizado" href="rootstock:testnet://0xda3ec0b8bddd2e8bdedede3333fbaf938fcc18c5/0" />


Предыдущий пример означает, что контент защищен (по идентификатору 0) создателем (например, 0xda3ec0b8bddd2e8bdedede3333fbaf938fcc18c5), и эта комбинация является платой, которую необходимо внести для его разблокировки.


  1. Используйте свойство window.monetizado ( инструкции здесь ).


Пошаговое руководство по проекту

Этот проект уже развернут в тестовой сети Rootstock, и вы можете изучить различные ссылки ниже, включая репозитории и демо:

  1. Инструкции по смарт-контракту: https://github.com/Monetizado/Contracts
  2. Javascript SDK: https://github.com/Monetizado/monetizadojs
  3. Monetizado Proxy SDK (для монетизации полных страниц с использованием промежуточной страницы для оплаты и проверки): https://github.com/Monetizado/proxyjs
  4. Monetizado Manager (для управления вашим контентом, сбора денег и многого другого без взаимодействия со смарт-контрактом): https://monetizado.github.io/manager/
  5. Демонстрация с Rootstock: <https://monetizado.github.io/demosmonetizado/demo_rootstock.html ](https://monetizado.github.io/demosmonetizado/demo_rootstock.html)
  6. Видео демо:


Проблемы и решения

Специально для этой идеи мы поставили перед собой задачу монетизировать платформы Web 2.0 с помощью Web3, не оказывая существенного влияния ни на создателя контента, ни на пользователя.


Поэтому нам пришлось создать SDK на Javascript, который позволил бы монетизировать контент, внеся лишь незначительные изменения на сайт, поскольку весьма вероятно, что у большинства создателей контента возникнут трудности с редактированием своих сайтов (или они используют внешние платформы, на которых у них не так много места для редактирования).


При таком решении нам нужно было понять, как определить контент, который монетизируется, и мы воспользовались тегом HTML-ссылки, чтобы указать этот контент, а SDK определил бы сумму в rBTC, если бы пользователь уже заплатил и имел доступ или должен был бы заплатить.

Заключение

Rootstock представляет собой огромную возможность в BitcoinFi, используя его возможности и надежность как децентрализованной сети. В этом контексте, чтобы делать микроплатежи и подключать его к экономике создания.


Этот пример, Monetized, демонстрирует простоту использования Web3 на платформах Web2, где есть огромное пространство для всех типов пользователей, что снижает трудности при интеграции этих технологий.