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

注册【OKEx】交易所,免费送USDT,即刻到账

作者:Share_Boy

来源:CSDN

原文链接: https://blog.csdn.net/z714303584/article/details/78367380

著权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

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的社区。

文章发布只为分享区块链技术内容,版权归原作者所有,观点仅代表作者本人,绝不代表区块链兄弟赞同其观点或证实其描述。

本文由 区块链技术网 作者:区块链 发表,其版权均为 区块链技术网 所有,文章内容系作者个人观点,不代表 区块链技术网 对观点赞同或支持。如需转载,请注明文章来源。

注册【OKEx】交易所,免费送USDT,即刻到账