编写你的第一个hyperledger fabric network程序

Posted Share_Boy

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了编写你的第一个hyperledger fabric network程序相关的知识,希望对你有一定的参考价值。

Writing Your First Application
编写你的第一个程序。 本文档的目标是使阅读本文档的人能基于HyperLedger Fabric Network编写自己的第一个程序。 在这个程序里,我们提供最基本的功能: 用户能在账本中查询一条数据或者用户更新账本中的一条数据。
我们的程序是使用javascript编写,运行在NODEJS平台上。 此文档将会指导你通过三步去编写你的第一个程序。 第一步:
  运行一个HyperLedger Fabric BlockChain Network。
  我们需要一些基础组件去查询和更新账本。 一个通道节点(peer node), 排序节点(Ordering node)和认证授权中心(Certificate Authority )--作为我们的网络支撑。
  我们还需要一个CLI容器来执行管理命令。 一个单独的脚本将会下载和运行这个测试网络。
第二步:
  学习我们的程序将要使用的智能合约的参数。
  我们的智能合约允许我们使用多种不同的方法去操作账本(Ledger)。 例如: 我们可以读取数据的整体或者是一部分(we can
                   read data holistically or on a more granular level.)。
第三步:
  部署程序去查询和更新数据。
  我们提供两种简单的程序 ---- 一个查询账本,另一个更新账本。 我们的程序将会使用超级账本的SDK API 去影响 HyperLedger.
  
  在完成本教程之后,你应该对如何使用HyperLedger Fabric Network提供的NODEJS的API去编写自己的程序有一个基本的理解。
  
首先,让我们运行我们的HyperLedger。 Getting a Test Network
获取一个测试网络。   确保你已经安装了所有必须的依赖软件。
  首先决定你要克隆Fabric-samples到哪一个目录,然后运行克隆脚本,随后进入fabric的子目录。
  
  git clone https://github.com/hyperledger/fabric-samples.git
  cd fabric-samples/fabcar
  
  这个子目录(fabcar)包含脚本和程序代码可以运行简单的fabric程序。 运行ls命令你将会看到如下内容:
  chaincode invoke.js network package.json query.js startFabric.sh
  现在我们运行startFabric.sh脚本去运行网络。
  
  ./startFabric.sh
  
  注意: 这个脚本将会下载HyperLedger Fabric Docker 镜像,所以它将会运行一会儿。
  
  为了简洁起见, 我们不会深挖这个命令运行时发生了什么, 这里给出了一个大概内容。
    启动一个通道节点(peer node), 排序节点(Ordering node)和认证授权中心(Certificate Authority )和一个CLI 容器。
    创建一个通道并且将启动的节点加入通道。
    在启动的节点上安装智能合约并且安装启动chainCode。
    调用initLedger添加10条数据到账本中。
    
  注意: 这些操作通常有管理员来完成。 本脚本使用CLI执行脚本完成操作。同时SDK也能很好的支持这些操作。
  
  执行docker ps 命令去显示startFabric.sh脚本运行的进程。 你可以通过Building Your First Network来学习更多细节和关于这些机器的操作。
  在这里我们把注意力放在程序这里。下面的图片简单展示了程序是如何访问HyperLedger Fabric Netowrk。
  
  好吧, 现在你有了一个简单的网络环境和一些能与这个环境交互的代码,让我们将这两部分组合到一起吧。 How Applications Interact with the Network 
如何使用程序访问Fabric   程序使用APIs去访问智能合约(chaincode)。这些智能合约在网络的主机上以名字和版本作为唯一标识。例如: 我们的智能合约的标题是: dev-peer0.org.example.com-fabcar-1.0 ----名称的部分是fabcar, 版本的部分是1.0,运行的peer的名称是dev-peer0.org.example.com.
  
  API可以通过软件开发工具包(SDK)来访问。这次练习中我们将使用Hyper-ledger Fabric Node SDK来开发。当然你也可以使用JAVA SDK或者CLI来进行练习。
  
Querying the Ledger
查询账本   查询是从账本中读取数据。你可以查询数据的单个值或者多个值。如果账本写入的时候使用的是像JSON一样的富文本 ---- 执行复杂的搜索。
  
  
  
  
  正如我们之前说的,我们的网络中有一个运行Chaincode容器和一个账本,其中有10条不同的数据。 我们还需要一些简单的JAVASCRIPT脚本 --
  -- 在fabcar目录下可以去查询账本下的块的信息。
  
  在我们了解程序如何运行之前,我们需要为我们的程序安装依赖的SDK模块,在你的fabcar目录下,运行如下命令:npm install。
  
  注意: 你将从fabcar目录发出所有后续的命令。
  
  现在我们可以运行我们的JAVASCRIPT程序了。 首先,让我们运行query.js程序列出账本中的所有区块的信息。 一个函数将会查询出所有的区块,
  queryAllCars, 预加载到我们的程序中, 我们可以简单的运行这个脚本: node query.js
  
  它将会返回如下内容:
   Query result count = 1
   Response is ["Key":"CAR0", "Record":"colour":"blue","make":"Toyota","model":"Prius
   ˓→ ","owner":"Tomoko",
   "Key":"CAR1", "Record":"colour":"red","make":"Ford","model":"Mustang","owner":
   ˓→ "Brad",
   "Key":"CAR2", "Record":"colour":"green","make":"Hyundai","model":"Tucson","owner":
   ˓→ "Jin Soo",
   "Key":"CAR3", "Record":"colour":"yellow","make":"Volkswagen","model":"Passat","owner
   ˓→ ":"Max",
   "Key":"CAR4", "Record":"colour":"black","make":"Tesla","model":"S","owner":"Adriana
   ˓→ ",
   "Key":"CAR5", "Record":"colour":"purple","make":"Peugeot","model":"205","owner":
   ˓→ "Michel", 
   "Key":"CAR6", "Record":"colour":"white","make":"Chery","model":"S22L","owner":"Aarav",
   
   "Key":"CAR7", "Record":"colour":"violet","make":"Fiat","model":"Punto","owner":"Pari
   ˓→ ",
   "Key":"CAR8", "Record":"colour":"indigo","make":"Tata","model":"Nano","owner":
   ˓→ "Valeria",
   "Key":"CAR9", "Record":"colour":"brown","make":"Holden","model":"Barina","owner":
   ˓→ "Shotaro"]
   
   
   这里有10条数据。 一辆属于adriana黑色(black)的特斯拉(Tesla)Mode S,一辆红色(red)的福特(ford)野马(mustang)是Brad 和其他的。
   账本是基于键值(key/value)来实现,而且我们实现键(key)的CAR0 到CAR9。 这一点将会变的非常重要。
   
   让我们看看程序是如何实现的吧。 使用编辑器打开程序query.js。
   
   程序的初始化章节定义了主要的变量例如: (智能合约)chaincode ID, 通道名称(channel name)和 访问端口。
   
   var options =
      wallet_path : path.join(__dirname, './network/creds'),
      user_id: 'PeerAdmin',
      channel_id: 'mychannel',
      chaincode_id: 'fabcar',
      network_url: 'grpc://localhost:7051',
   
   
   这一部分使我们构造查询的语句:
   
   // queryCar - requires 1 argument, ex: args: ['CAR4'],
   // queryAllCars - requires no arguments , ex: args: [''],
   const request =
   chaincodeId: options.chaincode_id,
   txId: transaction_id,
   fcn: 'queryAllCars',
   args: ['']
   
   我们将chaincode_id定义为fabcar,允许我们到达这个智能合约。 然后调用智能合约中定义的queryAllCars函数。
   当我们运行 node query.js命令的时候,这个函数被调用来查询账本。然而这并不是我们唯一能调用的函数。
   
   我们来看下其他的代码。进入chaincode子目录然后打开fabcar.go文件, 你将会看到被声明为 -- initLedger,
   queryAllCars, createCar 和 changeCarOwner等函数。 让我们在queryAllCars中去了解如何操作账本。
   func (s
    * SmartContract) queryAllCars(APIstub shim.ChaincodeStubInterface) sc.Response
    ˓→
    startKey := "CAR0"
    endKey := "CAR999"
    resultsIterator, err := APIstub.GetStateByRange(startKey, endKey) 这个函数使用了shim的接口函数GetStateByRange通过两个区间函数startKey和endKey来返回之间的账本数据。
   我们分别定义了CAR0到CAR999的键。因此, 如果键被正确使用的话,我们可以存储1000辆车,而且queryAllCars会列出每一辆车。
   
   下面的图片展示了程序如何智能合约(chaincode)的不同的函数。



在上图中我们可以看到我们的queryAllCars, 还有一个createCar。createCar函数允许我们更新账本。createCar最终将一个新的块添加到区块链中。
   但是首先我们先做另一个查询。
   
   回到我们的query.js程序,编辑query.js的构造请求去查询一个特殊的车辆。  我们将会修改queryAllCars为queryCar,并且指定一个Key作为参数(这里我们
   使用CAR4)。我们编辑query.js成下面这样。
   const request =
       chaincodeId: options.chaincode_id,
       txId: transaction_id,
       fcn: 'queryCar',
       args: ['CAR4']
   保存程序并返回fabcar目录下。然后再次运行程序:
   node query.js
   你应该看到如下的数据:
   "colour":"black","make":"Tesla","model":"S","owner":"Adriana"
   
   现在我们已经从查询所有到查询指定的一条。 使用queryCar函数,我们可以查询任意Key获取其映射的数据。
   
   非常好, 现在你应该能使用智能合约(chaincode)的基础函数用来查询并且可以传递查询参数了。
   
Updating the Ledger
更新账本。
   
   现在我们已经做过了账本查询并且修改了一点点代码, 我们已经做好了更新账本的准本。
   我们可以对账本做很多更新,但是前提是我们得有数据来更新。所以首先我们来创建一辆车(一条数据)。
   
   账本更新从一个事务的生成开始。 就像查询一样, 一个请求需要一个唯一的channelID, 调用函数和智能合约才能被创建,并且需要将这些数据传递。
   然后程序将调用channel.SendTransactionProposal API 将事务发送给peer获得建议(endorsement)。
   
   
   
   Fabric 返回一个请求响应,应用程序使用它来创建和提交一个事务请求。这个请求通过调用channel.sendTransaction API 发送到 排序服务
   (The Ordering Service)。排序服务(The Ordering Service)将此事务绑定到一个块中, 然后将该块发送给所有对等的节点上去认证
   (我们的例子中仅有一个节点)。
    
    
    
   最终程序会调用eh.setPeerAddr去链接节点的事件监听端口并且调用eh.registerTxEvent去注册时间关联到事务的ID。这个API允许程序去获取
   交易的流程(成功(successfully), committed(已提交)或者未成功(unsuccessful))。把他想象成为一个通知机制。
   
   
   注意: 我们不会深入的了解事务的生命周期。你可以查阅事务流程(Transaction Flow)文档来了解如何提交事务给账本的底层细节。
   
   
   我们最初的调用是建立一项新的资产(也就是一辆车)。我们有一个单独的程序 - invoke.js -我们将使用这些事务。就像查询(query.js)一样,
   我们使用编辑工具打开invoke.js 并找到构造调用API的代码:
   // createCar - requires 5 args, ex: args: ['CAR11', 'Honda', 'Accord', 'Black', 'Tom
    ˓→ '],
    // changeCarOwner - requires 2 args , ex: args: ['CAR10', 'Barry'],
    // send proposal to endorser
    var request =
    targets: targets,
    chaincodeId: options.chaincode_id,
    fcn: '',
    args: [''],
    chainId: options.channel_id,
    txId: tx_id
   
    
   你将会看到我们调用两个函数 createCar和changeCarOwner. 让我们创建一辆红色的Chevy Volt,并且将他的拥有者设置为 Nick. 我们的账本的唯一标识的最顶端
   是CAR9, 所以我们将用CAR10. 更改代码块像下面这样:
   var request =
    targets: targets,
    chaincodeId: options.chaincode_id,
    fcn: 'createCar',
    args: ['CAR10', 'Chevy', 'Volt', 'Red', 'Nick'],
    chainId: options.channel_id,
    txId: tx_id
    
    
   保存并运行它:
    node invoke.js
   
   你的控制台终将会输出响应和事务ID。当我们看到这条信息的时候:
    The transaction has been committed on peer localhost:7053
    
   节点会发出事件通知,我们通过eh.registerTxEvent去接受通知。所以现在如果我们重复去运行query.js的话我们是可以查询到CAR10的。
   我们应该会看到如下结果:
    Response is "colour":"Red","make":"Chevy","model":"Volt","owner":"Nick"
   
   最后让我们调用我们最后一个函数: changeCarOwner。 Nick是非常慷慨大方的,它准备将他的车送个一个叫Barry的朋友。所以我们简单
   的修改一下我们的invoke.js
    var request =
     targets: targets
     chaincodeId: options.chaincode_id,
     fcn: 'changeCarOwner',
     args: ['CAR10', 'Barry'],
     chainId: options.channel_id,
     txId: tx_id
   再次运行程序 - node invoke.js - 然后再运行query.js。 我们将看到CAR10, 我们看到的是修改后的:
    Response is "colour":"Red","make":"Chevy","model":"Volt","owner":"Barry"
Additional Resources  
附加资源
   Hyperledger Fabric Node SDK repo 中有更多的优秀的资源和实例代码。当然你也可以咨询Hyperledger FAbric的社区。



    
    
    
    
    
    
    
    
    
















以上是关于编写你的第一个hyperledger fabric network程序的主要内容,如果未能解决你的问题,请参考以下文章

用Java为Hyperledger Fabric(超级账本)编写区块链智能合约链代码

Hyperledger Fabric 1.4 快速环境搭建

Hyperledger Fabric 开发环境搭建&构建Fabric

Hyperledger Fabric 智能合约实战 整体步骤

搭建基于hyperledger fabric的联盟社区 --Fabric证书解析

Hyperledger Fabric链码之二