难点及灵感

众所周知,我们使用WordPress等博客程序时,想实现用户与文章的权限管理,是非常容易的:用户与权限等数据存在数据库中,可以通过PHP代码来判断用户是否有权限访问文章。

虽然WordPress可以很方便的实现付费浏览的功能,但维护一个WordPress站点花费的精力有些大,我想把更多的时间放在技术研究及创作上,这也是为什么我最终又选择使用Hexo搭建博客。

而Hexo生成的所有的内容都是静态页面,能控制页面动态效果的JS对外都是明文的,这就使得文章的权限控制能力非常弱。

直到一天,我看到某博客使用了hexo-blog-encrypt插件,实现通过密码来访问文章内容,简单分析其源码实现后,我顿时眼前一亮,惊呼:我靠,还能这么玩!!?

再加上最近研究了少许的Web3知识,稍微地混合一下科技,就可以实现通过开发Hexo插件来实现付费浏览功能。

思路

其中一个最简单可行的办法就是:通过solidity编写智能合约来存储付费文章的密码,在付费文章页面,通过调用智能合约来获取文章密码,solidity的POC代码如下:

contract Storage {
    mapping( uint => string) private passwords;
    
    mapping( address => uint[] ) public ownIds;
    
    address owner;

    event getPassword(string password);

    constructor() {
        owner = msg.sender;
    }

    modifier onlyOwner() {
        require(owner == msg.sender);
        _;
    }

    function setPassword(uint _id, string calldata _password ) public onlyOwner {
        passwords[_id] = _password;
    }

    function buy(uint _id) public payable{
        require(msg.value >= 0.0001 ether, "infisent funds");
        require(bytes(passwords[_id]).length != 0, "not found password");
        ownIds[msg.sender].push(_id);
    }

    function isBuy(uint _id) public view returns(string memory) {
        uint[] memory buyList = ownIds[msg.sender];
        uint len = buyList.length;
        for( uint i=0; i<len; ++i ) {
            if( buyList[i] == _id ) {
                return passwords[_id];
            }
        }
        return "";
    }

}

当然,这种方式的缺点也很明显,passwords是存储在链上,这种简单的存储很容易通过解析字节码拿到密码。