智能合约简介

最近更新时间:2018-12-24 15:22:26

概述

在 Fabric 中,Chaincode(链码)也称为智能合约,是使用高级语言编写的一段代码,主要用于读取和操作账本上的数据。 智能合约是一座连接用户应用和 Fabric 账本的桥梁。用户的应用可直接和智能合约打交道,智能合约可直接和 Fabric 账本进行交互。

一个完整的 Fabric 区块链应用包含用户的应用程序和用户编写的智能合约两部分。用户的应用程序通过区块链网络的 Peer 节点,调用智能合约。用户智能合约通过区块链网络的 Peer 节点,操作账本数据。如下图所示:

在此架构中,智能合约主要负责封装与账本直接交互的过程(包括按照用户指定的逻辑存储与查询账本数据),供用户应用程序调用。用户的应用程序主要负责以下职责:

  • 用户的应用程序根据业务逻辑,负责生成需要存储在区块链网络上的数据。
  • 用户的应用程序根据业务逻辑,从区块链网络上获取到相关数据,进行业务操作。

在 Fabric 中,用户编写的智能合约运行在隔离的沙盒环境中,目前主要以独立的 docker 容器展现,安装在区块链网络中的 Peer 节点上。当智能合约被调用时,Peer 节点通过启动 docker 容器,运行智能合约。当智能合约容器启动后,智能合约会与启动智能合约容器的 Peer 节点建立交互,实现对对应 Peer 节点上账本相关数据的操作。智能合约在运行的过程中,会在对应 Peer 节点账本上创建独立的命名空间(即智能合约的名字),并在此命名空间中完成键值对的操作。不同的智能合约命名空间不一样,互相之间的数据也是独立的,智能合约只能访问到属于自己命名空间的键值对。如果一个智能合约想访问其它智能合约的数据,可以通过在智能合约内部调用其他智能合约的方式来实现。

Fabric 中的 Peer 节点提供了调用智能合约相关服务的接口。用户的应用程序可以通过使用此服务和 Fabric Peer 进行交互。通过与智能合约容器进行交互,完成应用程序和智能合约之间的交互。用户的应用程序可以通过以下两种方式使用 Fabric Peer 提供的服务:

注意事项

编写智能合约的时候,需要注意以下事项:

  • 智能合约对非确定性代码处理。
    在 Fabric 的交易中,交易请求将根据用户的配置,发送到多个组织的多个节点进行背书确认。如果智能合约中包含非确定性代码(例如随机数),将导致每个背书节点的运行结果不一致,无法达成共识。用户在编写智能合约时,建议不要在智能合约中包含随机函数。
  • 智能合约运行无状态性。
    编写智能合约时,建议不要在智能合约内部使用全局变量,建议设计为无状态性。在 Fabric 交易中,交易请求将根据用户的配置,发送到多个组织的多个节点进行背书确认。如果智能合约业务逻辑对全局变量有依赖,可能会导致每个背书节点运行结果不一致,无法达成共识。
  • 智能合约初始化代码。
    编写智能合约时,需要实现 Init 函数,此函数在智能合约实例化和升级的操作中,均会默认被执行一次。如果 Init 函数中的内容只能执行一次,升级的智能合约则不能包含此部分的 Init 代码。例如,在正常使用过程中,已将 Init 函数中设置的需写入账本的初始键值对 KEY1/VALUE1 修改为 KEY1/VALUE1_NEW,但是升级的智能合约默认调用 Init 函数,导致账本中的 KEY1 被更新为 VALUE1。为了避免产生此类似问题,建议将相关的 Init 内容写成独立的函数,供 Invoke 调用,在升级智能合约时,则无需变动 Init 的代码。