如何在Corda上寫一個派发股息的Dapp

  • 前言
  • 架构
    • 1. CreateStock 发行股票
      • Observer 观察员
    • 2. MoveStock 转移股票
    • 3. AnnounceDividend 派发股息
    • 4. GetStockUpdate 股票更新讯息
      • 节点默认不会记录不相关的交易
      • 5. ClaimDividendRecivable  要求股息分派
      • 获得股东的馀额
      • Corda小教训:1 代币 = 1 分 (货币中最小的单位)
    • 6.PayDividend 支付股息
      • 方便的MoveToken内建组合
  • 总结

對應的 Github項目


前言

在CSDN上首次写文章。我经常在世界各地为不同的开发者做有关Corda的培训,发觉他们对新功能代码库 TokenSDK很有兴趣,所以决定写一个相关的样本Dapp作为大家的参考。

这是一个记载了一些我创建此示例CorDapp的过程。基本的Corda的概念我会先跳过,但一些关键内容我会解释一下。

如果您还没有运行示例,可以从这个Github项目中下载并运行。
样本有六个重要的Flow,模拟了股票的发行,转移以至派息时的支付。

架构

这个博客介绍了我创建此示例CorDapp的过程。 尽管我不会介绍所有Corda的基本概念,但我将解释一些关键内容。
样品概述
如果您还没有运行示例,请随时从Github项目中下载并运行建议的示例。

样本有六个重要流。 它们模拟股票的发行,转移以及最终分配方式以及股息的支付方式。

1. CreateStock 发行股票

要发行新的股票,首先要暸解EvolvableToken,因为我接下来创建的StockState 将继承这个class,而它的特性是能够独立的更新代币(Token)的特性,而不影响代币的持有人。
而要创造StockState,我们只需使用Token-SDK内建的CreateEvolvableTokenFlow。 这个StockState包含股票信息,例如股票名称,股票代码,宣布股息等。您可以扩展它以添加更多信息,例如年度报告等等。

Observer 观察员

在实际发行股票时,应通知证监会等监管机构。 在Corda,我们将这些监管机构视为观察员,他们只是记录State的变化,无需签署交易。 做法就像以下这一行代码,提供的observers参数将只记录StockState的创造。

subFlow(new CreateEvolvableTokens(stockState,observers));

在TokenSDK中,大多数内建Flow都带有一个observer参数,开发人员不必自己特意写一个观察员用的flow,非常方便。

2. MoveStock 转移股票

MoveStock这步很直白简单。在TokenSDK中,把Token从一方转移到另一方就像是一行的代码那麽容易。 我们不仅可以将股票转让给其他人,还可以交换其他一些资产,例如金钱。 我们稍后的篇幅再细说。

subFlow(new MoveFungibleTokens(amount, recipient));

3. AnnounceDividend 派发股息

AnnounceDividend 构建的 Transaction

Input : 没有股息的TokenType
Output : 发布了股息的TokenType
不受影響 : 股东StockState

这一个Flow的编写看起来很简单,但它的概念比较复杂,因为牵动往後支付股息的流程,因而设计上的考虑很多。

我公布股息是更改StockState拥有的特性及日期。这里我们可以善用EvolvableToken的特性,利用内建的UpdateEvolvableTokenFlow独立地更新StockState的特性,而不会触发一个简单的动作向成千上万的股东发送讯息,为网络带来大量流量,但这亦意味着股东不会意识到这个AnnounceDividend flow所宣布的股息,正因如此,我设计了接下来的GetStockUpdate flow。

(当然这个设计有很大讨论的空间,但在这个样本CorDapp中我旨在演示TokenSDK的便利。)

4. GetStockUpdate 股票更新讯息

如果只在分散式赈本的层面上,这个flow感觉会有点画蛇添足。但在应用层面上,跟很多实际案例一样,股东的用户端都会向股份公司或证券商发起更新请求以获得最新的资讯。编写这个flow,我们可以使用Corda内置的flow – SendTransactionFlowReceiveTransactionFlow,便可在节点之间交换transaction。

subFlow(new SendTransactionFlow(holderSession, stx));

假如在执行AnnounceDividend flow之后,我们跳过这步直接在股东的节点中运行5. ClaimDividendReceivable flow,会出现包含历史状态(historical state)的错误。 这是因为股东没有最新的StockState状态,因而用已消耗的状态建立交易,违反了Corda设计。这避免了有股东节点在没有收到最新消息的状态下要求股息。

节点默认不会记录不相关的交易

同时间,在这个调用ReceiveTransactionFlow你会发现有StatesToRecord.ALL_VISIBLE这一个参数。

SignedTransaction stx = subFlow(new ReceiveTransactionFlow(session, true, StatesToRecord.ALL_VISIBLE));

Corda本身的设计是节点不会记录自己不是参与者(Participant)的交易。所以即使股东接收到AnnounceDividend的交易,也不会记录因为股东没有参与其中。要强迫股东节点把这种不相关的交易,便需要用到这个StatesToRecord.ALL_VISIBLE

5. ClaimDividendRecivable  要求股息分派

这个flow是模疑除息日所设计的。在这天系统要记录哪些股东符合获得股息,所以我们要做的,是把合资格股东所持有的StockState的资讯记录下
来,而我创建了另一种State类来记录他们,就是DividendState
整个DividendState的概念是最後在支付日(Payday),我们可以用这DividendState来更换其他货币,甚或至更多的股息。

在这个复杂的flow中,我们也可以从要构建一个怎样交易开始想。这个交易将需要从没有创造一个DividendState出来,这个时候我们利用ReferenceState的功能,把股东现在持有的StockState放作交易中的ReferenceState,让这个交易变得更有依据跟参考性。

ClaimDividendRecivable 构建的 Transaction

参考Reference : 股东StockState
Input : DividendState
Output : DividendState

获得股东的馀额

在股份公司方构建这个transaction,需要股东的馀额,这里我创造了一个class ClaimNotification来承载馀额及有需要的资讯,股东发送有必要的资讯到公司系创建transaction。
这种方法在Corda上是很常见的,可以学起来。

(讨论: 这里我让股东成为发起人来要求股息,而不是公司。 可能公司发起这个flow更近似於现实情况。 但这将导致我们得再创造多一次交流,使此样本过于复杂,所以我省略了。)

Corda小教训:1 代币 = 1 分 (货币中最小的单位)

之后我所需要的就是计算股息并创建一个DividendState,我以为这很简单。 然而我花了半天才计算出收益率和股利!
我没有正确处理价格的小数位数。 以美元为例,一个代币等于一美分,而不是一美元。 这是Corda Token概念的基础。
要计算股票的价值,我们需要将股票价格,乘以货币的小数位(fractional digit)作为10的幂。

BigDecimal stockValue = stockPrice.multiply(BigDecimal.valueOf(Math.pow(10.0, currency.getDefaultFractionDigits())))

6.PayDividend 支付股息

PayDividend 构建的 Transaction

Input : DividendState
Input : 股东现金
Output : 股东现金
Input : 公司现金
Output : 公司现金

除息日後的一段时间,便是当支付日(Payday)。这里我们需要一个flow将这个state转换为法定货币(即现金),这就是这个PayDividend目的。
在这个flow中我们要构建的交易中,需要之前创建DividendState作为Input,同时因为要转换现金,所以需要股东及股份公司原本及支付股息後的货币馀额作为input及output。
要把这股东及股份的馀额逐一从vault取出再逐一放进Transaction中,我们还可以使用TokenSDK的内建方法帮助。

方便的MoveToken内建组合

TokenSelection.generateMove()

上面的这行代码,便可生成一对Token移动前跟移动後的State物件。 这背後的原理跟鼓励大家使用的原因,是TokenSelection能用一个高效算法来查询所有有关的Token,开发者省去了要查询全部Token的state再计算总和的工夫。
(为了方便,在这里我暂时创建了一个TempTokenSelectionFactory来创建TokenSelection,现在它在Java constructor跟还需要优化。)

然後重我们可以使用以下这个代码把这对State直接放入Transaction中。

MoveTokensUtilitiesKt.addMoveTokens()

通过使用以上这个组合TokenSelection.generateMove()MoveTokensUtilitiesKt.addMoveTokens(),我们只需要几行代码便能转移Token,在一些需要特别订制的flow,开发者也有合适的工具去轻易应付处理Token的繁琐程序。

总结

创建此Cordapp非常有挑战性,因为我没有太多的财务知识。 但是我可以感觉到TokenSDK如何把交易不同的数位财产的代码编写变得轻松。
感谢阅读完本文,希望您喜欢。


欢迎聯絡或关注Corda社群

  • Slack社群 可以找到我(Wayne),或到#chinese频道交流。
  • 微信公众号

[区块链] 如何在Corda上写一个派发股息的Dapp相关推荐

  1. 如何在ubuntu上写一个类似sl跑火车指令,“跑甜甜圈”

    如何在ubuntu上写一个类似sl跑火车指令,"跑甜甜圈" 首先创建.c文件 #include <stdio.h> #include <math.h> #i ...

  2. 戏人看戏--什么是Web3.0?区块链又是什么?如何写一个web3.0的界面?

    杂谈 有人反馈说大数据现在太可怕了,上午搜的下午在空间的广告里就看到了-- 那么有什么办法可以彻底解决这个问题?Web3.0! 前段时间被炒的沸沸扬扬的比特币也是区块链的产物 正文部分:什么是Web3 ...

  3. Nervos:链外扩容 + Layer 2才是区块链的未来(上)

    5月14日晚,密码极客邀请到了Nervos的联合创始人兼COO吕国宁先生做客"密码极客大咖直播间",为大家详细讲述了Nervos的链外扩容与Layer 2设计.吕国宁先生曾是全球最 ...

  4. 技术图文:如何在CSDN上写自己的技术Blog?

    背景 下周一很多高校就要开学了,由于疫情的影响教育部提出"停课不停学"的口号.我也想着把组队学习应用于本次的远程线上教学中,通过让学生们写技术blog的方式来检查TA们对知识点的掌 ...

  5. 如何在github上fork一个项目来贡献代码以及同步原作者的修改

    如何在github上fork一个项目来贡献代码以及同步原作者的修改 作为一个IT人,通过github进行学习是最快的成长手段.我们可以浏览别人的优秀代码.但只看不动手还是成长得很慢,因此为别人贡献代码 ...

  6. 专题:区块链与数据共享(上)

    专题:区块链与数据共享 Blockchain and Data Sharing 导读: 区块链的概念来源于2008年中本聪发表的论文<比特币:一种点对点的电子现金系统>.在区块链系统中,各 ...

  7. 如何在VSCode上写Mark Down

    如何在VSCode上写Mark Down   近几年Markdown这种轻量级的文本编辑非常火,虽然不能代替我们现在依旧在使用的word,但是许多创作平台已经把Markdown的文件格式纳入平台,这意 ...

  8. 区块链与农业溯源上的利与弊

    区块链与农业溯源上的利与弊 区块链技术,是集分布式存储,点对点传输,共识机制,加密算法,数据区块等概念于一体的新型技术合集.著名<经济学人>杂志称:"区块链让人们在互不信任,并没 ...

  9. 2020 中国开源年会暨阿帕奇中国路演-以太坊区块链黑客松:构造下一个数字世界...

    点击上方"开源社"关注我们 | 编辑:黄欣宜 | 设计:王福政 | 责编:王玥敏 9月11日 -10月 25日 // 线上黑客松  今年,新冠状病毒突袭全球,似乎给全世界按下了&q ...

最新文章

  1. Paddle 网络中的Tensor 数据结构
  2. 回滚到公共回购中的旧Git提交
  3. [Android] SQLite数据库之增删改查基础操作
  4. MFC绘图的几种方法
  5. Google AdSense广告被屏蔽
  6. shell判端mysql数据库是否存在_Shell脚本检测和检查mysql数据库是否存在坏表
  7. CCF201604-3 路径解析(解法二)(100分)(废除!!!)
  8. C# 曲线上的点(一) 获取指定横坐标对应的纵坐标值
  9. linux卸载HBA卡驱动
  10. 云计算概念的基本介绍,云计算的特点主要有哪些?
  11. bcprov-jdk15on 简介、中文文档、中英对照文档 下载
  12. 2019数学建模国赛C题
  13. Sharding-Jdbc分库分表集成Mybatis-Plus+多数据源管理
  14. SpringBoot项目中配置文件敏感信息(数据用户名、密码)的加密
  15. (大佬)睿智的目标检测13——Keras搭建mtcnn人脸检测平台
  16. UVA10115- Automatic Editing
  17. windows桌面图标显示白边的解决方案
  18. 自动化测试生命周期的六个阶段
  19. 1960年代的计算机模型是,BIM全称是什么?BIM是什么以及未来的发展趋势?
  20. 64位计算机比32快多少,64位系统和32位系统哪个速度快

热门文章

  1. 注意力机制 - Transformer
  2. Flask项目实战——7—(Redis数据库存储验证码信息、验证登录界面的表单信息、注册功能实现、登录实现)
  3. oracle 19 rac启动,19c RAC启动报LRM-00109
  4. PASCAL VOC的评估代码voc_eval.py解析
  5. 软件测试--缺陷和缺陷报告
  6. 合宙Air105|摄像头|capture|SPI|Serial 串口|TFTLCD|Micro SD卡|GC032A|USB转TTL|官方demo|学习(2-1):摄像头camera-capture
  7. 对现在的生活不满意?《围城》给你个人,婚姻,爱情的启示
  8. 构建PXE一键装机平台
  9. VUE3组件 (4) 关于 Provide Inject 依赖注入
  10. 一篇NDSS的关于虚拟局域网的论文分析