头图

作者:Matt Zand and Navil Rodrigues
译者 宋丹阳  
Hyperledger Fabric 的架构在设计上,就包含了对运行企业级区块链应用的,至关重要的基本组件。事实上,随着大型项目开始大规模的安全、实时地管理大量交易,Hyperledger Fabric 的能力得到了充分的理解和赞赏。
正如此,与以太坊等公共区块链平台不同,Hyperledger Fabric 的学习曲线会相对陡峭;但是,当您的应用投入生产环境或是当您负责扩展它的运营时,这些耐心学习将得到回报。
智能合约,或者叫链码,在 Hyperledger Fabric 中发挥着比其他组件更重要的作用。的确,作为一名专业的 Hyperledger Fabric 开发者,你应该逐渐掌握链码从逻辑设计到开发、测试和部署的方方面面。与以太坊不同,在一个链码中,您可以同时运行多个智能合约。实际上,在联盟模型中,每个成员都可以在其节点中拥有自己的智能合约。这包括了在私有通道内与其他成员通信的智能合约,以及连接到 Orderer节点 和系统管理节点的系统智能合约。正是因为链码如此重要,在本文中我们将简要介绍其中的关键部分。
作为开发人员,您需要知道使用 JavaScript 编程语言,是在链码中编码和为 Hyperledger Fabric 开发智能合约的最简单方法(尽管您也可以使用 Java、Python 或 Go)。同时,您可以选择任意的文本编辑器来开发。当您完成基本的设置之后,您应该了解以下用于开发 Fabric 链码的基本概念:
Contract 类
Contract 结构
ChaincodeStub 接口
分布式账本数据表示
链码中的日志
在接下来的部分中,我们将向您简要介绍这些概念,并向您展示如何以及在何处使用它们。
I - 链码中的Contract类
在 Hyperledger Fabric 中,智能合约需要继承Contract类的所有方法,这个类包含在 fabric-contract-api npm 包中。这些不同的方法被调用以响应在链上的交易。下面是一个从合约 API 继承 Contract 类的例子,下面是对其关键方法的简要说明:
图片
构造函数
Contract类中的构造函数有一个name变量作为可选输入参数,用于为您的智能合约命名。如果未提供该参数,则构造函数会使用类名。
isContract 方法
该函数用于识别作为输入传递的对象是否为合约类型。它在成功检查时返回 true。beforeTransaction 方法
该函数会在调用智能合约中的任何交易函数之前被调用。您可以覆盖默认方法并替换成您自己的逻辑。
afterTransaction 方法
该函数在调用特定的交易函数之后调用此函数。您可以覆盖默认方法并替换成您自己的逻辑。unknownTransaction 方法
当智能合约中不存在请求交易函数时,将调用此功能。您可以覆盖默认方法并改用您自己的逻辑。createContext 方法
此函数用于创建您自己的自定义交易对象,在调用事务函数时可以访问该对象以进行额外处理。getName 方法
这是一个简单的 getter 函数,它返回合约名称
II - 链码中的Contract结构
Fabric-contract-api 和 fabric-shim 是在 Hyperledger 结构中编写链码所需的两个重要依赖项。当我们使用 node.js 开发链码时,我们需要在 package.json 文件中添加依赖项,如下所示:
图片
网络中的peer节点,使用启动命令 fabric-chaincode-node start 来启动使用。这条启动链码的指令导出在 index.js 文件中,该文件也是应用的主入口点。
图片
lib 目录可以包含一个或多个从 Contract 类派生的智能合约。此外,我们还可以有一个测试目录,其中将包含测试合同的测试用例。链码文件夹结构如下:
图片
III - 链码中的ChaincodeStub 接口
在 Hyperledger Fabric 中,每个链码都实现了在 Shim 包中定义的链码接口,并定义了两个在交易被请求时调用的重要方法:
图片
如您所见,该接口实现了两个方法:Init 和 Invoke。当链码首次部署在 Docker 容器中时,会调用 Init 来初始化链码的内部数据。但是,Invoke 方法被后续交易用于修改或读取账本;请注意,由于事务操作而修改的状态变量只有在事务提交时才会提交到账本。
这两种方法都接受一个类型为 chaincodeStubInterface 的 stub 参数。在链码中,每个函数都有一个 ctx 对象。该对象包含 chaincodeStubInterface 实现的上下文对象,它提供了与世界状态、私有集合、发出事件、跨链码调用等交互的基本API。
IV - 分布式账本数据
在 Hyperledger Fabric 中,Ledger 是一个不可或缺的组件。通过参与网络的节点的共识来向Ledger中添加或修改数据。它有两个不同但相关的组成——世界状态(World State)和区块链(Blockchain)。
世界状态(World State) —— 是一个保存当前和最新值的数据库。世界状态有助于链码快速获取数据的当前数据,而不用遍历整个交易日志然后再计算得出。账本中记录的数据或状态用键值对表达。有两种可用的数据库选项——Leveldb 和 Couchdb
区块链(Blockchain)—— 当前世界状态发生的所有变化都被记录为交易日志。形成的交易被收集在区块内并附加到区块链,允许任何人查看所存储资产状态的历史记录。区块链数据结构是不可变的;这意味着一旦进行了修改,区块链上的内容就无法变更;如果进行了变更,它将会形成一个新的状态。
与账本数据的简单交互-putState, getState 和 delState
正如前文所述,账本的状态表示为键值对。与它们交互的最简单方法就是使用 chaincodeStub 接口提供的 API。我们将展示最重要的,也是最基础的,用于查询、修改和删除账本状态的 API。
putState – API 需要一个键(字符串)和一个值(字节数组)。用于形成要提交到账本上的数据写入请求;请注意,只有在网络中的对等方验证并成功提交交易后,账本才会受到影响。键不应为空,也不应以空字符开头。
getState – API 需要一个键(字符串)。它将返回该键在账本中对应的值。如果状态数据库中不存在该键,则返回空数组。
delState – API 需要一个键(字符串)。它会形成一个从分类帐状态中删除记录的请求。操作成功后,键及其对应的值从世界状态中被标记为删除。但是,该记录仍将在区块链中可用并且可以重新取回。
V - 链码中的日志
日志是软件开发过程中最重要的部分。它通过分析数据、解决错误和及早发现问题来帮助您做出重要决策。链码日志记录是链码开发人员的最终责任。
任意能够将消息打印到stdout或者stderr的日志工具,都可以被应用于检视相关的Docker容器,Docker容器的日志可以通过以下命令来输出:
图片
总结
在本文中,我们学习了链码在通过 Hyperledger Fabric 构建私有区块链应用程序中的重要性。我们还回顾了链码的所有必须的组件,包括它的Contract类、结构等。
如果您正在准备认证 Hyperledger Fabric 开发人员 (CHFD) 考试,那么本文是一个很好的起点。作为本文的后续内容,您需要探索链码的生命周期,并对帐本数据执行一些从简单到复杂的查询。此外,还可以通过 Node.JS SDK 探索 Hyperledger Fabric V2 中引入的链码外部启动器。
关于 Matt Zand
Matt 是一位连续创业者,也是五家科技初创公司的创始人:RealBig、DC Web Makers、HashFlow、Coding Bootcamps 和 High School Technology Services。他是 O'Reilly Media 的 Hyperledger Fabric 实践智能合约开发一书的主要作者。他在 IBM、SAP、阿里云、Hyperledger、Linux 基金会等网站上为 Hyperledger、Ethereum 和 Corda R3 平台撰写了 100 多篇关于区块链开发的技术文章和教程。在 RealBig,他带领一个区块链专家团队建立了一个虚拟联盟,将 NFT 与 DeFi 相结合,同时通过 ICO 筹集资金。您可以在 Linkedin 上与他联系:https://www.linkedin.com/in/m...
关于 Navil Rodrigues
Navil 是来自 Linux 基金会认证的 Hyperledger Fabric 开发人员 (CHFD)。目前,他在 Mckinley Rice 担任区块链开发人员,负责为以太坊和侧链(如 Binance Smart Chain、Polygon 等)编写和实施智能合约。他还涉足开发和设计 ICO 合约和桥接解决方案以连接不同的链。此外,他还拥有从头到尾构建全栈和去中心化应用程序的经验。您可以在 LinkedIn 上与他联系:https://www.linkedin.com/in/n...

文章来源: Hyperledger超级账本
文章原标题:《Hyperledger Fabric 中智能合约的基本组件概述》
如有侵权请与我们联系删除。


BSN研习社
16 声望11 粉丝