本系列文章是针对 https://blog.csdn.net/weixin_43668031/article/details/83962959 内容的实现所编写的。开发经历包括思考过程、重构和推翻重来。
0x0.我如何使用区块链,我对区块链的理解和见解。
我常常把Ethereum以太坊理解为mysql,在mysql主从服务中的bin文件,日志同步文件有着区块链的影子。eth中的状态变量就像mysql的数据,增删改查都是支持的,这设计到eth智能合约的编写过程,eth所带来的历史记录就像mysql的同步日志一样,在慢慢的+1,+1,一个合约就像一个数据库一个应用一样,结构体镜像表结构一样,区块链上的数据就像mysql中的数据条一样,合约里的过程方法和mysql的储存过程一样,在我看来这几乎是一样的。唯一的不同就是在使用方式上,mysql可以做到秒级别的应用数据变更,而eth则是打包大区块来完成同步,这是因为这2者的应用场景完全不同,mysql集群100%用于可信任环境,一个应用内部使用,而eth的使用范围就很广了,允许跨网使用,使用者都是不信任的,所以才有了pow挖矿的必要。
我在这里想实现的是一个视频应用,着重考虑文件存储和文件索引的问题,在传统应用中索引一般是类似mysql的中心服务器,当然文件存储是不会放在检索服务中的,可以是nas类型的本地储存,也可以是ceph类型的分布式储存,或者类似hdfs这种大数据时代下的产物,在cdn分发层面需要相当大的成本,我在这里打算使用ipfs作为数据储存,去中心化,使用成本低廉。
0x1.数据结构的定义。
如果在mysql这种传统的数据库中,这一节就是数据表的定义。我想实现以下几个数据表。
1.用户
2.视频链
3.视频存储
4.评论
5.标签
6.打赏
7.专辑
1.用户表
struct User {
string nickname;
string profile;
string avatar;
uint videoNum;
mapping (uint => uint) videos;
}
mapping(address => User) users;
在区块链中无法分辨用户,识别个体采用地址,因此在此一个地址即为一个用户。
用户对应的是人的个体,需要有个名字。当然需要有一段简介来介绍自己,这段介绍内容可以是纯文字,也可以是一个多媒体的方式介绍自己。用户需要有一个很明显的识别标记,那就是头像。
2.视频链
struct Video {
string title;
string cover;
string videoinfo;
string info;
uint timestamp;
address payable author;
uint commentsNum;
uint gratuityNum;
uint gratuitySum;
uint lableNum;
uint videos;
uint8 authority;
mapping (uint => Videofile) videofiles
mapping (uint => Lable) lables;
mapping (uint => Gratuity) gratuitys;
mapping (uint => Comment) comments;
}
uint public videoNum;
mapping(uint => Video) videos;
这里定义一个authority权限,允许内容上传者控制是否可以让别人读取到该内容。
3.视频存储Videofile结构体
struct Videofile {
string filename;
string info;
uint size;
uint32 width;
uint32 height;
uint32 fps;
uint8 authority;
}
这里定义一个authority权限,允许任何人提交自己的视频文件,但是需要作者的核审。
4.评论
struct Comment {
string content;
uint timestamp;
uint videotimestamp;
address author;
}
5.标签
struct Lable {
string lable;
uint times;
}
标签这个结构涉及到多语言,这一点会严重影响体验,因此在前端展现时需要考虑标签内容的国际化转换。
6.打赏
struct Gratuity {
uint gratuity;
address author;
}
7.专辑
struct Album {
string title;
string cover;
string info;
uint videoNum;
mapping (uint => uint) videos;
address payable author;
}
uint public albumNum;
mapping(uint => Album) albums;
最终效果
https://github.com/bill080307/douyinWithEth/blob/6082ddaa5385f69bd4deb43f31a8c921a802d2de/VideoShare.sol
1-68行,下面的方法还没更新。
0x2.服务角色的定义。
关于代币:
这是所有人最关心的内容,在这个视频应用中会存在2个代币角色,一个是eth链上的,一个是filecoin,在这个应用开发的时候由于filecoin还未测试,所以filecoin的价值还不好估算。eth在公链上部署合约的话,会有2个很严重极端的问题,一个就是eth价格比较高,无法真正做到平民化,第二个就是公链内存池中有太多的交易和操作了,延迟会非常大,因此采用私链方式,并且保证价格非常低廉,预估计,将计划控制10000个视频检索花费在2美元以下,这比某个公有云服务商相同储存量0.8美元/月的价格要便宜太多太多。
检索矿工:使用eth挖矿工具进行挖矿,如显卡。
储存矿工:使用储存介质进行挖矿,如机械硬盘。
全节点:拥有所有eth数据,并提供ipfs节点的节点。
瘦客户端:需要全节点提供api接口给客户端才能使用。
全客户端:包含全节点和瘦客户端的所有功能,并缓存数据到传统数据库中,提供更加丰富的功能,如按标题搜索。
这个视频应用会提供以下示例程序,并包括所有源码,欢迎任何人修改并发布自己的版本,如有缺陷请提交给我。
1.Ethereum节点,linux amd64 版本。
2.Ethereum节点,windows amd64 版本。
3.go-ipfs节点,全平台版本(官网版本)。
4.全节点代理程序,包括nginx配置。
5.瘦客户端,web应用程序。
6.瘦客户端,Android应用程序。
7.基于windows的全客户端,包含windows的eth,windows的go-ipfs,windows传统数据库缓存服务。
8.基于Linux的全客户端,包含Linux的eth,Linux的go-ipfs,mysql的传统数据缓存服务,web应用程序。