Fabric v2.0 FabToken介绍

什么是FabToken

       将资产用tokens表示,将使你利用区块链账本去建立一个与物品之间的特殊状态与所有权,并使用一个被多方信任共识机制转移所有权。就像账本是安全的一样,资产也是安全的,并且未经拥有者的同意是无法被转移的。

       Tokens可以代表有形资产,也可以代表无形资产。因为Tokens在未经拥有者同意的前提下是无法被转移的,并且那些转移tokens的交易都会在分布式账本上进行验证,所以使用tokens代表资产可以减少资产在多方转移时的风险和困难。

      FabToken是一个允许你使用Hyperledger Fabric发行,转移,回收tokens的token管理系统。Tokens被存放在通道的账本上,并且可以被通道中的任何一个成员持有。FabToken使用Fabric的MSP去认证token拥有者的身份并管理他们得公私钥。FabToken的交易只有在发起方为拥有有效MSP身份的token拥有者时才是有效的。

      FaToken利用通道提供的验证和信任提供了一个简单的接口token化资产。Tokens使用通道的orderers和peers来进行共识和验证。Tokens也使用通道的策略去管理哪些成员可以拥有和发行tokens。然而,用户不需要使用智能合约去创建或者管理tokens。Token的建立和资产所有权的确立并不需要通道成员的签名和复杂的业务逻辑去批准。Token的拥有者可以使用受信任的peers来创建token交易,而不需要其他组织去对交易背书。

Token的生命周期

     Tokens和Hyperleger Fabric有相似的生命周期。他们可以被发行,转移和回收。 

  • Tokens通过发行来创建。Tokens的发行者定义被tokens代表的资产的类型和数量,同时制定tokens的初始拥有者。
  • Tokens通过转移来消费。Tokens的拥有者可以转移tokens所代表的资产到通道中的另一个成员上。Tokens一旦被转移,它原来的拥有者将无法再使用和获取它。
  • Tokens通过回收来将其从通道中移除。被回收的token不能再被通道中的任何成员拥有和消费。

     FabTokens使用UTXO模型来验证token交易。UTXO交易保证了资产的唯一性,使其只能被拥有者转移,并且无法被多次消费。每一笔交易必须有一组特定输入输出。输出为交易创建的新tokens。这些将被以未消费的状态列在账本上。输入为被另一笔交易创建的未消费的tokens。如果一笔交易是有效的,消费的tokens将被从通道长辈的数据库中移除。

     基于UTXO模式的token生命周期保证了tokens的唯一性,并且只能被消费一次。Token被发行时,它被创建在一个未消费状态,并被发行者指定了一个拥有者。拥有者可以转移和回收Token。当token被转移时,创建者拥有token将作为输入。输出为被交易接收者拥有的新的token。输入的token变为以消费的,并从数据库中移除。这个过程中,输入输出所代表的资产总数是一样的。被回收的token被转移到一个空的拥有者。这使被回收的token不可能在被通道中的成员转移。

     发行token

    Tokens只能被发行者创建。发行者是通过IssuingPolicy授权发行tokens的通道成员。满足策略的用户可以使用issue交易在账本上增加tokens。

    Tokens需要3个参数来创建:

  • Owner 可以通过自己的MSP身份转移和回收token的通道成员
  • Type 表示token代表的资产类型,例如美元,欧元等等
  • Quantity token代表的资产的数量

    例如,每个美元类型的token表示100美元。为了消费50美元或者增加50美元,新的token将被创建,并且代表新的美元数量。

    IssuingPolicy也可以限制发行者可以发行哪种类型的token。在Fabric v2.0 Alpha release中,IssuingPolicy被设置为ANY,意味着所有通道成员可以发行任意类型的token。在之后的版本中用户将可以限制这个策略。

    List

    你可以使用List方法查询你拥有的未消费的token。成功的List指令会返回以下值:

  • TokenID 你拥有的token的id
  • Type 你的token代表的资产类型
  • Quantity 你拥有的资产数量

    Transfer

     你可以转移你拥有的token给通道中其他成员来消费token。转移token需要提供以下值:

  • Token ID 你想要转移的token的id
  • Quantity 要转移的资产数量
  • Recipient 接收者在通道中的MSP身份

    注意,转移交易是针对tokens所代表的基础资产的,而不是转让tokens本身。相反,新的tokens是由传输事务创建的。例如,如果你拥有价值100美元的tokens,你可以使用该tokens花费50美元。传输事务将创建两个新的token作为输出。一个价值50美元的tokens属于你,另一个价值50美元的tokens属于接收者。

    转移到交易接收者的资产数量需要与输入的token所代表的数量相同。如果你不想转移tokens所代表的资产的全部数量,你可以只转移资产的一部分,交易将自动使你成为剩余余额的所有者。使用上面的例子,如果100美元的tokens只花费50美元,那么转账交易将自动创建一个价值50美元的新tokens,并且使你作为所有者。

    要让交易成功,转移者需要具备以下条件:

  • 被转移的token需要属于交易的发起放,并且未被消费
  • 作为交易输入的所有tokens必须是同一种类型

    Redeem

    被回收的tokens无法再被消费。回收tokens意味着将从通道管理的事务网络总移除资产,并保证其不会被再次转移和更改。  如果供应链中的项目达到其最终目的地,或金融资产达到其期限,则表示该资产的tokens可以回收,因为该资产不再需要由通道成员使用。

    拥有者想要回收tokens需要提供以下参数:

  • Token ID :你想要回收的token的id
  • Quantity : 回收token代表的资产数量

    只有token所有者提交回收交易时,才能回收token。无需回收token所代表的全部资产。例如,如果您有一个代表100美元的token,并且想要回收50美元,那么回收交易将创建一个价值50美元的新token,并将另外50美元转移到一个没有所有者的受限账户。因为帐户没有所有者,50美元不能再由任何通道成员转移。

    Token的交易流

     FabToken绕开了Fabric的标准背书流程。针对chaincode的交易需要在足够多的组织的peers上调用,以满足chaincode背书策略。这样可以确保交易的结果与智能合约的逻辑一致,并且该逻辑的结果已由多个组织验证。由于token是资产的唯一表示形式,只能由其所有者转移或回收,因此不需要多个组织来验证初始交易。

    FabToken的客户端使用受信任的peers,我们叫做prover peers,来创建token交易。例如,属于某个组织的peer的用户可以使用该peer查询其token并使用它们。在Fabric 2.0 Alpha中,任何加入了通道并启用了v2_0功能的peer都可以被用作为prover peer。

  • 在发行交易中,prover peer会验证请求的操作是否满足与正在创建的token关联的IssuingPolicy。
  • 在转移,回收和查询交易中,peer检查输入的tokens是否是未消费的,并且属于请求交易的实体。
  • 在转移和回收中,peer检查输入输出的token是否为同一种类型,并且输入tokens代表的资产数量与输出多代表的数量一致。

    一旦客户端通过prover peer生成了token交易,就将该交易发送给了orderer。orderer再将交易发送给记账节点验证并添加到账本。记账节点检查交易是否符合UTXO交易模型,以及基础资产是否被重复使用或过度使用。

    FabToken的使用

    1.创建配置文件

     Token cli使用来自每个组织的配置文件,其中的信息包含了哪些peers是组织信任的,交易将被发向哪个orderer。下面是org1的配置文件。请注意,org1使用自己的peer作为prove peer,并在文件的“prover peer”部分提供peer终端信息。

    configorg1.json

 

{
  "ChannelID":"",
  "MSPInfo":{
    "MSPConfigPath":"",
    "MSPID":"Org1MSP",
    "MSPType":"bccsp"
  },
  "Orderer":{
    "Address":"orderer.example.com:7050",
    "ConnectionTimeout":0,
    "TLSEnabled":true,
    "TLSRootCertFile":"/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem",
    "ServerNameOverride":""
  },
  "CommitterPeer":{
    "Address":"peer0.org1.example.com:7051",
    "ConnectionTimeout":0,
    "TLSEnabled":true,
    "TLSRootCertFile":"/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt",
    "ServerNameOverride":""
  },
  "ProverPeer":{
    "Address":"peer0.org1.example.com:7051",
    "ConnectionTimeout":0,
    "TLSEnabled":true,
    "TLSRootCertFile":"/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt",
    "ServerNameOverride":""
  }
}

 configorg2.json

{
  "ChannelID":"",
  "MSPInfo":{
    "MSPConfigPath":"",
    "MSPID":"Org2MSP",
    "MSPType":"bccsp"
  },
  "Orderer":{
    "Address":"orderer.example.com:7050",
    "ConnectionTimeout":0,
    "TLSEnabled":true,
    "TLSRootCertFile":"/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem",
    "ServerNameOverride":""
  },
  "CommitterPeer":{
    "Address":"peer0.org2.example.com:9051",
    "ConnectionTimeout":0,
    "TLSEnabled":true,
    "TLSRootCertFile":"/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt",
    "ServerNameOverride":""
  },
  "ProverPeer":{
    "Address":"peer0.org2.example.com:9051",
    "ConnectionTimeout":0,
    "TLSEnabled":true,
    "TLSRootCertFile":"/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt",
    "ServerNameOverride":""
  }
}

       现在我们需要保存一个额外的文件,当我们转移token时将使用这个文件。在文本编辑器中创建一个新文件,并将下面的文件另存为shares.json

[
    {
    "recipient":"Org2MSP:/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/users/[email protected]/msp",
    "quantity":"50"
    }
]

    接下来启动Fabric系统。

    Issue tokens

    首先进入cli

    docker exec -it cli bash

    发行一个类型为BYFNcoins,数量为100的token。发行者为org1的admin,接收者为org1的user1

token issue --config /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/configorg1.json --mspPath /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/users/[email protected]/msp --channel mychannel --type BYFNcoins --quantity 100 --recipient Org1MSP:/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/users/[email protected]/msp

   命令运行成功将有下列输出

2019-03-12 00:49:43.864 UTC [token.client] BroadcastReceive -> INFO 001 calling OrdererClient.broadcastReceive
Orderer Status [SUCCESS]
Committed [true]

  可以使用list指令查询被创建的token

# List the tokens belonging to User1 of Org1

token list --config /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/configorg1.json --mspPath /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/users/[email protected]/msp --channel mychannel

    命令运行成功将有下列输出

{"tx_id":"4e2664225d6a67508cfa539108383e682f3d03debb768aa7920851fdeea6f5b7"}
[BYFNcoins,100]

    转移token

    使用上面创建的shares.json作为转移策略,向org2的user1转移50BYFNcoins

# Transfer 50 BYFNcoins to User1 of Org2
# The split of coins tranfered to Org1 and Org2 is in shares.json

token transfer --config /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/configorg1.json --mspPath /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/users/[email protected]/msp --channel mychannel --tokenIDs '[{"tx_id":"4e2664225d6a67508cfa539108383e682f3d03debb768aa7920851fdeea6f5b7"}]' --shares /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/shares.json

   使用list指令可以查询到当前org1的usr1只剩写50BYFNcoins,而org2的user1拥有了50BYFNcoins

  回收token

  使用下面的指令去回收org2,user1的25BYFNcoins

# Redeem tokens belonging to User1 of Org2

token redeem --config /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/configorg2.json --mspPath /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/users/[email protected]/msp --channel mychannel  --tokenIDs '[{"tx_id":"4eaf466884586106f480dd0bb4f675ddaa54d1290ea53e9c24a2c1344fb71d2c","index":1}]' --quantity 25

   再通过list指令查询org2,user1还剩下多少BYFNcoins

   

# List the tokens belonging to User1 of Org2

token list --config /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/configorg2.json --mspPath /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/users/[email protected]/msp --channel mychannel

  如果我们再对org2的user1回收50BYFNcoins则会得到错误,因为他只剩下25BYFNcoins了

# Redeem tokens as Org1 belonging to Org2

token redeem --config /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/configorg2.json --mspPath /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/users/[email protected]/msp --channel mychannel  --tokenIDs '[{"tx_id":"4eaf466884586106f480dd0bb4f675ddaa54d1290ea53e9c24a2c1344fb71d2c"}]' --quantity 50

response:
error from prover: the requestor does not own inputs

  

你可能感兴趣的:(Fabric,FabToken)