作者:CNCorda.com Jiachuan

参考:
– 《Unlocking New Opportunities with Accounts on Corda》 Peter Li
– 《Accounts library in Corda》 Harman Puri

Account 是 Corda 4.3 新推出的功能,使用 Account 让 Corda 能够更灵活地应用于更多的场景,并且主要可以解决以下两方面的问题:

  • 由于成本的原因,个人及小微企业无法承担或不愿承担运行一个节点的费用,造成区块链应用的推广困难
  • 对于企业内部的不同部门,如果他们想参与区块链中的交易的话,如果没有 Account,所有部门会使用同一个节点的身份来参与,所有的部门会共享一个账本或者能够查询其他部门的数据

使用 Account 有好处也会有新的问题,那就是隐私的问题,节点的维护者或者管理者是可以访问所有 account 的信息的。在 Github 的 issue discussion 中,有一个 Harman Puri(区块链开发者)和 Roger Willis(R3 Corda CTO)的讨论,Roger 表示:

很不好的是,在节点级别是没有隔离的,但是你可以添加应用级别的控制来基于每个 account 来提供授权。这个功能应该放置到你的 CorDapp 以及相关的 RPC 客户端中。

Corda 将 Account 描述为:

Account 类库允许一个 Corda 节点的维护者可以将 vault 分解成为多个 “逻辑的” sub-vaults。

Corda 提供了一个 Account 的样例程序,可以在 https://github.com/corda/accounts-demo-supplychain 下载。本篇文章会带领大家一起运行以下这个样例程序(基于 Windows10)。

这个样例中演示了一个简单的供应链的业务流程

上图中可以看到 flow 是在不同的参与方(buyer、seller 和 shipping)的 accounts 之间发生的。

准备工作

首先,你需要确保本地环境已经配置好了,如果没有的话,请按照 《配置本地开发环境》配置好本地开发环境。

使用下边的命令将代码下载到本地:

git clone https://github.com/corda/accounts-demo-supplychain.git

按照《配置本地开发环境》中的 “第二步:创建一个 IntelliJ 项目” 那样打开这个项目,这个可能需要一些时间来下载相关的类库。

注意:下载类库的过程中可能会遇到一些类库无法下载的错误,下边是个例子,多尝试几次,或者换个时间再试一试,国内的网络有时不太稳定。

Project resolve errorsC:\Git\Corda\accounts-demo-supplychain\build.gradleroot project 'accounts-demo-supplychain': Unable to resolve additional project configuration.Details: org.gradle.internal.resolve.ArtifactResolveException: Could not download kotlin-stdlib-jdk8.jar (org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.2.71): Skipped due to earlier error 

下载完之后程序会被 build,成功后应该看到下边的结果:

创建并运行节点

在程序的根目录下,通过运行下边的命令创建节点:

.\gradlew.bat clean deployNodes

运行成功后,节点会被创建在根目录下的 build/nodes 下边。会有四个节点:Buyer、Notary、Seller 和 ShippingCo。

通过下边的命令启动节点:

.\build\nodes\runnodes.bat

应该有四个 Corda 终端窗口自动打开了。

注意:如果其中的某个窗口卡在了初始的状态,可以尝试以下的方法:

  • 关掉那个窗口,再重新运行上边的命令
  • 关掉所有窗口,在任务管理器中结束所有 Java 进程,再重新运行上边的命令
  • 重启电脑,再重新运行上边的命令

创建和分享 Accounts

创建 buyer accounts

在 buyer 的终端窗口运行下边的命令 :

flow start CreateNewAccount acctName: BuyerProcurement
flow start CreateNewAccount acctName: BuyerFinance
flow start CreateNewAccount acctName: BuyerWarehouse
flow start ShareAccountTo acctNameShared: BuyerProcurement, shareTo: Seller
flow start ShareAccountTo acctNameShared: BuyerFinance, shareTo: Seller
flow start ShareAccountTo acctNameShared: BuyerWarehouse, shareTo: ShippingCo
flow start ShareAccountTo acctNameShared: BuyerWarehouse, shareTo: Seller

这会在 buyer 的节点下边创建三个 accounts 并且将其分享给相关的节点或者 account。执行完后应该像下边这样的 outputs:

创建 seller accounts

在 seller 的终端窗口运行下边的命令 :

flow start CreateNewAccount acctName: SellerSales
flow start CreateNewAccount acctName: SellerFinance
flow start CreateNewAccount acctName: SellerInventory
flow start ShareAccountTo acctNameShared: SellerSales, shareTo: Buyer
flow start ShareAccountTo acctNameShared: SellerFinance, shareTo: Buyer
flow start ShareAccountTo acctNameShared: SellerInventory, shareTo: ShippingCo

这会在 seller 的节点下边创建三个 accounts 并且将其分享给相关的节点或者 account。执行完后应该像下边这样的 outputs:

查询 accounts 信息

通过以下的命令可以查看到 accounts 信息:

run vaultQuery contractStateType: com.r3.corda.lib.accounts.contracts.states.AccountInfo

Buyer 节点能查到以下 accounts:

  • BuyerProcurement
  • BuyerFinance
  • BuyerWarehouse
  • SellerSales
  • SellerFinance

Seller 节点能查到以下 accounts:

  • BuyerProcurement
  • BuyerFinance
  • BuyerWarehouse
  • SellerSales
  • SellerFinance
  • SellerInventory

ShoppingCo 节点能查到以下 accounts:

  • BuyerWarehouse
  • SellerInventory

执行业务 flows

步骤1:Seller 的 sales account 向 buyer 的 procurement account 发送一个 $500 的发票

在 seller 的终端窗口运行下边的命令 :

flow start SendInvoice whoAmI: SellerSales, whereTo: BuyerProcurement, amount: 500 

执行完成后应该像下边这样的输出:

这时候可以到 buyer 的节点查看一下消息是否成功接收到,运行下边的命令:

flow start ViewInboxByAccount acctname: BuyerProcurement

执行完成后应该像下边的输出:

这里我们也可以测试一下 BuyerFinance account 是不是能看到这条消息,运行以下命令:

flow start ViewInboxByAccount acctname: BuyerFinance

可以看到 BuyerFinance 的 account 是没有这条消息的。

步骤2:Buyer 的 procurement account 向 buyer finance account 发送一个内部的消息

在 buyer 的终端窗口运行下边的命令 :

flow start InternalMessage fromWho: BuyerProcurement, whereTo: BuyerFinance, message: Send 500 to SellerFinance

通过以下的命令查看是否成功收到了消息:

flow start ViewInboxByAccount acctname: BuyerFinance

步骤3:Buyer 的 finance account 向 seller 的 finance account 发送一个付款

在 buyer 的终端窗口运行下边的命令 :

flow start SendPayment whoAmI: BuyerFinance, whereTo: SellerFinance, amount: 500

可以在 seller 的终端窗口中用下边的命令查询是否收到消息

flow start ViewInboxByAccount acctname: SellerFinance

步骤4:Seller 的 Finance account 给 seller 的 inventory account 发送消息告诉他们发送货物

在 seller 的终端窗口运行下边的命令 :

flow start InternalMessage fromWho: SellerFinance, whereTo: SellerInventory, message: send Cargo to Buyer

在 seller 的终端窗口验证是否接收到了消息:

flow start ViewInboxByAccount acctname: SellerInventory

步骤5:Seller 的 inventory account 为 shipping company 发送一个 shipping 的工作订单

在 seller 的终端窗口运行下边的命令:

flow start SendShippingRequest whoAmI: SellerInventory, whereTo: BuyerWarehouse, shipper: ShippingCo, Cargo: 10 boxes of Books

可以在 ShippingCo 终端窗口运行下边的命令查看是否收到消息

run vaultQuery contractStateType: com.accounts_SupplyChain.states.ShippingRequestState

步骤6:Shipping company 将货物发给 buyer 的 warehouse account

在 ShippingCo 的终端窗口运行下边的命令 :

flow start SendCargo pickupFrom: SellerInventory, shipTo: BuyerWarehouse, cargo: Books

可以在 buyer 的终端窗口中使用下边的命令查看是否收到了货物

flow start ViewInboxByAccount acctname: BuyerWarehouse

总结

这个例子程序中实现了以下的交互方式:

  • 节点间的 Account 和 Account 交互
  • 节点内的 Account 和 Account 交互
  • Account 和其他节点的交互

发表评论