pragma solidity ^0.4.19; contract ContentService { struct Content { address contentOwner; string title; uint views; uint pool; uint viewFee; } Content[] public contents; mapping(address => mapping(uint => bool)) existingViews; mapping(address => bool) existingViewers; mapping(address => uint) public balanceOf; event NewContent(uint _contentId, address _contentOwner, string _title, uint _views, uint _pool, uint _viewFee); event IncreasedView(uint _contentId, address _viewerAddress, uint _views); event Transfered(address _from, address _to, uint _value); /* modifiers */ modifier viewerExists() { require(_isViewerExists(msg.sender)); _; } modifier notYetViewed(uint _contentId) { require(!_alreadyViewedContent(_contentId, msg.sender)); _; } function ContentService() public { } function addContent() public { Content memory content = Content({ contentOwner: msg.sender, title: "Return of the Test Title", views: 0, pool: 10 ether, viewFee: 10 ether }); uint contentId = contents.push(content) - 1; NewContent(contentId, content.contentOwner, content.title, content.views, content.pool, content.viewFee); } function getContent(uint _contentId) public view returns ( address contentOwner, string title, uint views, uint pool, uint viewFee ) { return ( contents[_contentId].contentOwner, contents[_contentId].title, contents[_contentId].views, contents[_contentId].pool, contents[_contentId].viewFee ); } function viewContent(uint _contentId) public notYetViewed(_contentId) { _processViewForContent(_contentId); _setViewerForContent(_contentId, msg.sender); _payViewer(_contentId, msg.sender); IncreasedView(_contentId, msg.sender, contents[_contentId].views); } /* privates */ function _payViewer(uint _contentId, address _viewerAddress) private { contents[_contentId].pool -= contents[_contentId].viewFee; balanceOf[contents[_contentId].contentOwner] -= contents[_contentId].viewFee; balanceOf[_viewerAddress] += contents[_contentId].viewFee; Transfered(contents[_contentId].contentOwner, _viewerAddress, contents[_contentId].viewFee); } function _setViewerForContent(uint _contentId, address _viewerAddress) private { existingViews[_viewerAddress][_contentId] = true; _setViewerExists(_viewerAddress); } function _alreadyViewedContent(uint _contentId, address _viewerAddress) private view returns (bool) { return existingViews[_viewerAddress][_contentId]; } function _setViewerExists(address _viewerAddress) private { existingViewers[_viewerAddress] = true; } function _isViewerExists(address _viewerAddress) private view returns (bool) { return existingViewers[_viewerAddress]; } function _processViewForContent(uint _contentId) private { Content memory content = contents[_contentId]; content.views++; contents[_contentId] = content; } }
0.4.19