アテンション エコノミー (Web 2.0) では、ユーザーは限定コンテンツ (アダルト コンテンツを含むあらゆる種類のコンテンツ) にアクセスするためにサブスクリプション料金を支払うよう「強制」されますが、コンテンツ作成者が新しいコンテンツを作成し続けなかったり、消費した分だけ支払いたいのに長期間サブスクリプションを続けなければならないなどの理由で、支払った分に見合ったメリットが得られる保証はありません。
しかし、Web 3.0 のインテンション エコノミーでは、マイクロペイメントを通じて、ユーザーが長期間ではなく消費した分だけ支払う機会がもたらされます。その結果、コンテンツ クリエイターはより多くの作品を更新し続けるようになり、中央ゲートウェイに依存せずに、非常に低いコストですぐに収入を得ることができます。
Monetizado は、Web3 を通じてあらゆる Web ページや静的コンテンツ (変更を加えるためのバックエンドにアクセスできない場合) を収益化できるオンチェーンのペイパービュー プラットフォームです。
Monetizado は、ニュース サイト、ソーシャル ネットワーク、独占コンテンツ ポータルなどに実装できます。また、Monetizado を使用すると、ユーザーに料金を支払ってもらい、サイトで広告が表示されないようにすることもできます。
Monetizado を使用すると、次のことが可能になります。
次のように、monetized を使用してページを保護し、購読者だけが閲覧できるようにすることができます。
このプラットフォームを構築するために、次のものを使用しました。
私たちのスマート コントラクトは非常に基本的なもので、収益化するコンテンツの名前、金額 (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; } }
マネージメント
// 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; } }
さらに、特に特定のコンテンツにアクセスするために料金を支払いたいユーザー向けに、Web サイト全体でスマート コントラクトを使用できるようにするJavaScript SDKを作成しました。
<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>
<script src="./monetizado.js"></script>
ページの HTML コードの先頭に、属性「rel」と値「monetized」を持つリンク タグを追加し、href で次の構造に従います。
例えば:
<link rel="monetizado" href="rootstock:testnet://0xda3ec0b8bddd2e8bdedede3333fbaf938fcc18c5/0" />
前の例は、コンテンツが作成者 (たとえば 0xda3ec0b8bddd2e8bdedede3333fbaf938fcc18c5) によって保護されており (ID 0 によって)、その組み合わせでロックを解除するには支払いを行う必要があることを意味します。
このプロジェクトはすでに Rootstock テストネットにデプロイされており、リポジトリやデモなど、以下のさまざまなリンクを調べることができます。
特にこのアイデアのために、私たちはコンテンツ作成者とユーザーの両方に大きな影響を与えることなく、Web3 を使用して Web 2.0 プラットフォームを収益化できるようにするという課題を自らに課しました。
そのため、ほとんどのコンテンツ作成者は Web サイトの編集に困難を抱えている可能性が高い (または編集スペースがあまりない外部プラットフォームを使用している) ため、Web サイトにほとんど変更を加えずにコンテンツを収益化できる JavaScript の SDK を作成する必要がありました。
このソリューションでは、収益化されているコンテンツを識別する方法を検討する必要があり、そこで HTML リンク タグを利用してそのコンテンツを指定し、ユーザーがすでに支払いを行ってアクセス権を持っている場合、または支払う必要がある場合に、SDK が rBTC の金額を検出しました。
Rootstock は、分散型ネットワークとしての機能と堅牢性を活かし、BitcoinFi に大きなチャンスをもたらします。このコンテキストでは、マイクロペイメントを実現し、それを創造経済と結び付けます。
この「Monetized」の例は、Web2 プラットフォームで Web3 を使用するシンプルさを示しています。Web2 プラットフォームには、あらゆるタイプのユーザーのための巨大なスペースがあり、これらのテクノロジーを統合する際の摩擦が軽減されます。