EOS 10 - DAPP 业务逻辑合约开发:发微文、评论

pendingauth · 2019年07月10日 · 17 次阅读

本文转载自币乎,作者松果,原文链接:https://bihu.com/article/1969842282

这篇文章继续进行weiwendappss智能合约核心业务逻辑开发,包括发布微文、评论、点赞、关注。

适当的数据冗余

使用multi_index表的智能合约,类似于传统应用的后端+数据库,但又有一些不同;

目前multi_index表的查询灵活性还很差,远比不上传统数据库,这意味着无法在合约中使用类似于SQL的连接查询这样的功能,multi_index表甚至没有提供count,为了便于查询,multi_index表应该适当设计一些数据冗余。

微文DAPP的数据表设计中,有如下一些冗余字段:

  • 用户表(usertable):balance、follow_num、fans_num、post_num、like_num;

  • 微文表(posttable):balance、like_num、comment_num;

  • 评论表(commenttable):balance、like_num;

微文DAPP核心业务逻辑相关的Action执行时,对应需要修改的冗余字段如下:

1、发微文(post)

  • usertable.post_num

2、评论(commment)

  • posttable.comment_num

3、微文点赞(like)

  • usertable.like_num

  • usertable.balance

  • posttable.like_num

  • posttable.balance

4、评论点赞(like)

  • usertable.like_num

  • usertable.balance

  • commenttable.like_num

  • commenttable.balance

5、关注/取关(follow/unfollow)

  • usertable.follow_num

  • usertable.fans_num

另外,也可以使用之前文章介绍的Demux来增强DAPP的数据库能力,使用Demux就需要搭建后端服务器了,本质上是把multi_index表难以支持的查询操作转移到了后端;

而微文DAPP是要部署在IPFS上的,IPFS上部署的是DAPP的前端代码,没有后端服务器,所以还是采用数据冗余的办法提高查询效率。

发微文

微文包含一段文字和(可选的)附件,发布一条微文使用weiwendappss::post Action,代码如下:

ACTION post(name author, const std::string& content, uint32_t attachtype, const std::string& attachment) {
  require_auth(author);

  check_user(author);
  if(attachtype != 0){
    check(attachment != "", "attachment can not be empty");
  }

  post_t posts(_self, _self.value);
  posts.emplace(author, [&](auto& post){
    post.id = posts.available_primary_key();
    post.author = author;
    post.content = content;
    post.attachtype = attachtype;
    post.attachment = attachment;
    post.time = time_point_sec(current_time_point()); 
    post.balance = asset(0, TOKEN_SYMBOL);
    post.like_num = 0;
    post.comment_num = 0;
  });

  auto itr = users.find(author.value);
  users.modify(itr, same_payer, [&](auto& user){
    user.post_num++;
  });
}

代码的主要逻辑是进行一些条件检查后,把微文数据添加到posttable表,然后把usertable表的post_num字段加1,这里的post_num字段就是为了便于查询而设计的冗余字段。

在修改usertable表时,直接使用了users对象,但Action中并没有初始化它,这是因为users被提取为了weiwendappss合约类的成员变量,并已经在构造函数中初始化了;

weiwendappss构造函数的定义方式修改了,从:

using contract::contract;

改为了:

weiwendappss(name self, name first_receiver, datastream<const char *> ds) : 
  contract(self, first_receiver, ds), users(self, self.value) {}

这种定义方式,在构造weiwendappss时就初始化了users表对象。

评论

用户可以评论已发布的微文,也可以对评论进行回复,评论和回复评论都使用weiwendappss::comment Action,代码如下:

ACTION comment(name author, const std::string& content, uint64_t post_id,
  bool has_parent, uint64_t pid, name reply_to) {

  require_auth(author);

  check_user(author);

  post_t posts(_self, _self.value);
  auto itr = posts.find(post_id);
  check(itr != posts.end(), "post does not exist");

  comment_t comments(_self, _self.value);
  if(has_parent){
    check(comments.find(pid) != comments.end(), "parent comment does not exist");
  }

  comments.emplace(author, [&](auto& comment){
    comment.id = comments.available_primary_key();
    comment.post_id = post_id;
    comment.author = author;    
    comment.time = time_point_sec(current_time_point()); 
    comment.balance = asset(0, TOKEN_SYMBOL);
    comment.like_num = 0;
    comment.has_parent = has_parent;
    comment.pid = pid;
    comment.reply_to = reply_to;
  });

  posts.modify(itr, same_payer, [&](auto& post){
    post.comment_num++;
  });
}

代码逻辑和发微文类似,更多细节可以到项目源码中查看。

Tips

项目代码在Github同步更新:https://github.com/songguo6/weiwen-dapp,下一篇文章介绍点赞(核心功能)和关注的实现过程。

更多内容

EOS开发系列目录

暂无回复。
需要 登录 后方可回复, 如果你还没有账号请点击这里 注册