难点及灵感

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

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

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

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

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

思路

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
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是存储在链上,这种简单的存储很容易通过解析字节码拿到密码。