一、区块链演进
区块链本身只是一种数据的记录格式, 与传统的记录格式不同的是, 区块链是将产生的数据按照一定的时间间隔, 分成一个个的数据块记录, 然后再根据数据块的先后关系串联起来, 也就是所谓的区块链了.
区块链目前经过了三个阶段的发展和演进, 暂且分别叫做1.0、2.0、3.0, 他们的代表架构分别如下:
1、区块链1.0: 其典型应用是比特币应用, 并适合于公有链中. 在整个架构中, 分为核心节点和前端工具
2、区块链2.0: 其典型代表是以太坊, 也适合于公有链, 但其引入了智能合约的概念, 并在此基础上提供了更为开放的平台, 进行合约的开发
3、区块链3.0: 超越了对数字货币或者金融的应用范畴, 而将区块链技术作为一种泛解决方案, 可以在其他领域应用, 比如行政管理、文化艺术、企业供应链、医疗健康、物联网、产权登记等,可以认为区块链 可编程社会的结构, 其更适用于企业级的应用, 或联盟链、私有链
二、区块链关键技术栈
区块链其实是现有技术的组合, 其基础的系统结构如下:
可以认为所有的区块链软件都是由以上结构组成, 将这些区块链软件部署到不同的服务器上就形成了对等节点, 有许多对等节点组合起来就构成了对等网络, 而许多这种大大小小的网络即形成了DAO(去中心化的自治组织), 也可以说区块链是一个由分布式网络中的节点维护的不可篡改的账本. 大概可以描述为如下过程:
下面再来简单看下区块链系统结构中个技术栈的含义:
1、区块链账本: 特有的数据记录格式 , 区块 链, 也即数据块 串联标识
2、共识机制: 一套规则 , 让分布式对等网络中的每个节点的数据达成一致
3、密码算法: 确保区块数据完整性、不可篡改 , 创建账户地址、签名交易事务等
4、智能合约: 部署在区块链账本中的脚本 , 驱动区块链系统进行数据的各种操作
5、网络路由: 网络触角 , 用于在去中心化、分布式网络中的节点发现 , 数据同步 下面我们来详细介绍其中几个关键技术
三、密码算法
首先想想区块链中为什么需要密码算法? 这个问题其实可以从两方面来考虑
1) 区块链承载的业务价值: 我们知道区块链账本一般运用于货币、股票、信任、数字资产、版权、私人信息等场合, 对于这些业务场景, 是和隐私信息密切相关的, 所以加密机制的应用就不言而喻了
2) 业务特性: 发布到区块链上的业务, 一般都有隐私保护需求、数据防篡改、极高的安全性、数据准确性等特点, 为了满足这些要求, 都要运用密码学作为其基础保障
再来想想区块链中可以使用哪些密码学算法? 区块链中主要用到的密码学算法有哈希算法、公开密钥算法、编码/解码算法等, 下面具体介绍
1、哈希算法
哈希算法算是比较常用的算法了, 其在区块链等应用场景包括比特币中计算钱包地址、区块头、交易事务的哈希值,梅克尔哈希树,共识算法 , 挖矿使用哈希值进行难度匹配等. 其算法原理概括起来就是任意长度的字符串输入可以得到固定长度的字符串输出. 一张图概括如下:
其算法有如下特点:
1) 抗冲突: 不同的输入不能产生相同的输出. 抗冲突并不是说不会有冲突, 只不过找到有冲突的两个输入的代价很大, 不可承受. 这就好像暴力破解一个有效期为20年的密码, 整个破解过程长达30年, 虽然最后密码被破解了, 但是由于密码 有效期过了, 所以也就失去了意义.
2) 信息隐藏: 知道了输出不可能逆向推导出输入. 例如敌人截获了公开信道(比如无线电波), 获取了传送的哈希信息, 敌人也不可能根据这段信息还原出明文.
3) 可隐匿性: 没有便捷的方法去产生满足特殊要求的哈希值. 这个特性主要是为了对付伪造和仿制,
4) 算力敏感: 哈希算法的计算过程是有效率的, 其依赖于计算资源, 而这些资源的限制可能会成为瓶颈.
目前常用的哈希算法包括:
MD5: 1992年发布 , 输出128位散列值 , 2004年被破解 , 无法防止碰撞
SHA1: 1995年发布 , 输出160位散列值 , 在许多安全协议中广为使用,包括TLS和SSL , 2017年被攻破
SHA2: 2001年发布 , 主要有SHA224、SHA256、SHA384和SHA512
SHA3: 2012年将Keccak选中 , 作为一个与之前算法不同的 , 可替换的加密散列算法 , 不是取代SHA2
RIPEMD-160: 1996年发布 , 160位加密哈希函数 , 旨在替代128位MD4、MD5和RIPEMD-128 我们以比特币为例子, 看看哈希算法是如何在其中得到广泛应用的
上图所示的是一个比特币的区块, 他是由区块头和交易数据组成的, 区块头一共占用80个字节, 包括区块版本号、前一区块hash、梅克尔根hash、时间戳、难度值、随机数等. 其区块头的数据结构定义如下
每一个区块都有一个区块头, 其区块头的hash指针是通过SHA256( SHA256(version prev_hash merkle_root timestamp bits nonce ) )两次哈希运算计算出来的, 而挖矿的过程就是不算的计算这个值, 使得其小于bits值, 计算挖矿成功. 可以看出只有version、prev_hash、merkle_root、bits的值是不变的, 而要不断的对nonce进行变化取暴力计算, 因此这个过程没有任何捷径, 且比较耗费性能
同时每一个区块都是具有一棵梅克尔树结构的, 其中存储着不同的交易数据, 同时可以发现, 梅克尔树中的每一个节点都是一个哈希值, 其哈希值是SHA256( SHA256( Hash12 Hash34 ) )两次哈希运算所得, 因此也可以称之为哈希树, 而比特币中的梅克尔树是通过交易事务的哈希值两两哈希计算而成, 所以这样梅克尔树称为二叉梅克尔树. 比特币是分布式的网络结构, 当一个节点需要同步自己的区块链账本数据时, 并没有一个明确的服务器来下载, 而是通过与其他的节点进行通信实现的. 在下载区块数据的时候, 难免会有部分数据会损坏, 对于这些一条条的交易事务, 如何去校验有没有问题呢?这个时候, 梅克尔树就能发挥作用了, 由于哈希算法的特点, 只要参与计算的数据发生 一点点的变更, 计算出的哈希值就会改变. 假设A通过B来同步区块数据, 同步完成后,发现计算出的梅克尔根与B不一致,也就是有数据发生了损坏,此时先比较Hash12和Hash34哪个不一致, 假如是Hash12不一致, 则再比较Hash1和Hash2哪个不一 致, 如果是Hash2不一致, 则只要重新下载交易事务2就行了. 重新下载后, 再计算出Hash12并与Hash34共同计算出新的梅克尔根比较, 如果一 致, 则说明数据完整. 我们发现, 通过梅克尔树, 可以很快找到出问题的数据块, 而且本来一大块的区块数据可以被切分成小块处理.
2、公开密钥算法
公钥和私钥是现代密码学分支非对称性加密里面的名词, 对于一段需要保护的信息, 通常使用公钥加密, 用私钥解密, 这种加密方法也称为公开密钥算法. 其应用场景主要包括比特币中构造钱包地址、交易信息签名、价值转移保卫、零知识证明、数字证书等.
其算法有如下特点:
1) 安全性: 加解密密钥分开 , 无需提前共享通用密钥
2) 保密性高: 基于大数质因子分解、离散对数、椭圆曲线等
3) 性能瓶颈: 对于大篇幅的原始数据加密的性能不会很高
区块链中常用的公开密钥算法包括
RSA: 1977年发布 , 既能用于加密 , 也能用于数字签名. 其安全性基于大数的因子分解,但并没有从理论上证明破译的难度与大数分解难度等价,无法从理论上把握其保密性能如何. 其特点主要是 1) 产生密钥很麻烦,受限于质数产生的技术, 2) 分组长度太大,运算代价高,速度慢. RSA的算法过程大致如下
ECC: 椭圆曲线加密 , 利用了y²=x³ ax b(mod p)的椭圆曲线,即定义在有限域上的椭圆曲线 , 其主要的安全性在于利用了椭圆曲线离散对数问题的困难性, 其常用的算法是SECP256K1.
3、编码/解码算法
其主要应用场景是比特币中构造钱包地址, 一般包括如下算法:
4、示例
以上算法, 我们用比特币的地址生成为例来介绍下他们的具体应用场景:
比特币的地址生成可以包括三个阶段, 生成公钥哈希、 校验值、地址生成. 结合比特币源码进行分析,
1) 先生成随机数作为私钥, 比特币通过GetStrongRandBytes生成32字节的随机数, 其过程是先通过RandAddSeedPerfmon函数使用OpenSSL’s RNG 生成随机数, 并进行 SHA512 哈希运算; 然后调用GetOSRand方法, 通过 OS RNG 生成随机数,并进行 SHA512 哈希运算; 如果 HW(硬件随机数发生器) 可用, 通过 HW 生成随机数, 并进行 SHA512 哈希运算; 最后合并并更新状态, 把buf数组中的内容拷贝到输出参数中,并清空数组中的内容.
2) 生成公钥, 通过椭圆曲线算法SECP256K1来生成私钥对应的公钥, 并验证其有效性
3) 获取公钥哈希, GetID方法调用Hash160函数, 该函数用公钥的数据经过 SHA256、RIPEMD160 两次哈希运算后生成一个CKeyID对象, 将其作为公钥哈希
4) 生成校验值, 将一个地址版本号连接到公钥哈希(比特币主网版本号为 0x00), 然后对其进行两次SHA256运算, 将计算得到的结果取前面4字节作为公钥哈希的校验值
4) 生成钱包地址, 将0x00版本号与公钥哈希以及校验值连接起来, 然后进行 BASE58编码转换, 最终得到了比特币地址
四、共识算法
什么是共识? 为什么需要共识? 如何达成共识?
理解共识之前, 先要理解分布式系统, 区块链系统本质就是一个分布式应用软件, 分布式系统一般需要具备以下能力:
1) 正确性: 分布式系统作为一个逻辑整体,不应该返回错误的结果
2) 抵抗单点故障: 只要系统里的大部分机器工作正常,整个分布式系统就能有效运行
3) 扩展性: 系统的性能是可以横向扩展的
4) 异步性: 每个节点可以按照自己的时序独立工作,没有全序的时间顺序
而分布式系统的一致性, 是指数据要完整、要同步. 也就是如何在多个独立的分布式节点之间达成共识. 要注意的是, 这里说的是要达成一致, 而没有说保证一定要结果正确, 比如所有的节点都达成失败状态也是一种一致, 说白了就是要成为一致行动人. 但是要满足分布式系统的要求并达成一致性不是那么容易, 从以下两个定理就可以看出:
1) FLP定理: 在网络可靠、存在节点失效的最小化异步模型系统中,不存在一个可以解决一致性问题的确定性算法
2) CAP定理: 分布式计算系统不可能同时确保一致性、可用性和分区容错性
对于分布式系统来说, 分区容错是必然的, 而实际上, 很多时候我们对一致性的要求也并没有那么迫切, 在一定的约束下, 可以实现所谓的最终一致性, 也就是说在某个时刻系统达到了一致的状态. 这个节点现在断网了, 没问题, 等恢复后跟上, 通过其他节点来同步自己的数据; 那个节点宕机了, 也没问题, 恢复后跟上. 只要整个网络中绝大部分的节点都是正常工作的, 整个系统总能在未来的某一个时刻达成数据状态的一致.
1、拜占庭将军问题
在分布式系统中有个典型的问题叫拜占庭将军问题, 拜占庭的军队是由分散的小分队组成, 各小分队由一个将军指挥, 将军们通过传令兵来策划一系列进攻行动, 他们必须有超过半数的小分队同时发起进攻才能成功. 而有些将军是叛徒, 会有意地妨碍进攻计划, 这个问题的目标是使忠诚的将军达成一致的计划. 已经证明, 如果背叛的将军超过了将军总数的 1/3, 达成上述目标是不可能的. 以一个三个军队攻占拜占庭为例, 即三个节点达成共识的问题.
1) 如果三个都是忠诚的将军, 他们之前都会发出相同的指令, 每个军队收到半数以上(2)的相同指令就会发起进攻, 在这种条件下很容易达成一致, 最终完成进攻
2) 如果有一个叛军时, 即 1/3 的叛军, 此时叛军C会发出撤退的命令扰乱进攻任务, 但是由于军队A、B都收到了半数以上的进攻指令, 所以A、B军队仍会发起进攻, 最终还是能达成一致, 完成进攻
3) 如果有两个叛军时, 即 超过1/3 的叛军, 此时叛军B、C都会发出撤退的命令扰乱进攻任务, A会收到2个撤退命令, 最终会放弃进攻, 这样无法攻克拜占庭
针对于拜占庭问题的延伸, 可以用容错的概念来表述, 可以分为4中类型
1) 拜占庭容错(BFT): 节点不按程序执行 , 返回错误结果
2) 崩溃容错(CFT): 节点按程序执行 , 能返回正确结果 , 不保证返回时间
3) 遗漏容错: 节点按程序执行 , 能返回正确结果 , 不保证返回时间 , 但结果可以持久化 , 故障恢复后返回
4) 崩溃停止容错: 节点按程序执行 , 能返回正确结果 , 不保证返回时间 , 但结果可以持久化 , 故障恢复后返回 , 且恢复前会停止响应
为了解决上述问题, 在分布式系统中我们可以引入激励机制(增加利益驱使), 随机性(随机选举制, 并提高背叛成本)等机制来解决一致性问题, 实现最终一致性, 从而达成共识. 依据如上机制, 有如下共识算法:
2、Paxos
其用来解决非拜占庭将军问题, 在分布式系统中的节点存在故障, 但是不存在恶意节点. 当超过一半节点正常时, 就能达成共识. 算法模型中有四种角色划分, 这些角色可以是不同的服务节点也可以是同一个服务节点兼任, 通过提案的方式进行组织, 提案发出后, 就要争取大多数的投票支持, 当超过一半支持的时候, 发送一半结果给所有人进行确认, 也就是上面说的Paxos能保证在超过一半的正常节点存在时, 系统达成共识.
根据不同的场景可以分为:
1) 单个提案者 多个接收者: 只有一个提案, 要么通过, 要么拒绝, 很容易达成共识, 不过也容易形成单点故障
2) 多个提案者 单个接收者: 只有一个接收者, 选择其中一个提案即可, 也容易达成共识, , 同样的也容易形成单点故障
3) 多个提案者 多个接收者: 这种情况避免了单点故障, 在实际中往往会分两个方案来解决, 第一种是向 1) 场景靠近, 通过设置一些竞争规则或者按照一个时间序列的排列选择, 在某一时间段内只允许一个提案通过, 第二种是向 2) 场景靠近, 当节点收到多份提案后, 根据提案序号排列或者根据提案时间等规则选出一份提案, 也就是仍然保持只接收一份
Paxos算法还可以概括为两个阶段
1) 准备阶段: 解决对哪个提案进行投票的问题
2) 提交阶段: 解决确认最终值的问题
3、Raft
Paxos被认为是一种比较晦涩难懂的算法, 在实现起来也比较复杂, 而Raft在可靠性不输于Paxos的情况下, 尽可能简单易懂, 因此更适合做工程实现, Raft是一种强Leader的共识协议.
举个例子, 假设在一个班级中有很多学生, 一个班级相当于一个服务器集群, 每个学生对应一个服务器, 都保存着一份作业数据副本, 所有学生都听从老师的命令完成作业, 因此作业数据副本都必须保证一致性. 通常一个班级学生中会有一个班长, 即服务器集群中的leader, 班长是通过选举产生, 谁得的票数多(简单多数)谁就当选班长。班长有任期概念, 每学期都要重新选班长, 任期是一直向上增长的: 1, 2, 3, ..., n, n 1, ... 老师下达的命令都要经过班长传达给全部学生(此时命令处于uncommitted状态), 学生接收到班长的命令后向班长进行反馈, 表示已接收到指令, 当超过半数的学生反馈后, 班长会告诉老师确认命令已接收, 此时命令处于committed状态, 班长发通知告知同学该命令状态已提交(即命令已执行).
这个过程中会遇到一些异常情况的处理, 比如:
1) 班长选举平票: 此时选举失败, 老师会让大家休息一会, 且每人休息时长不同, 休息的学生只有选举权, 没有被选举权, 第一个醒来的学生可以发起自己的选举, 这样总会有一个学生当选.
2) 老师命令到达前 , 班长挂了(图例标识1): 重新选举, 之前的命令会自动过时失效 , 之后被重新发送
3) 班长收到命令 , 还没传达就挂了(图例标识2): 跟上面第2条类似
4) 命令已传达 , 但学生还没执行或执行完还没反馈 , 班长就挂了(图例标识3): 重新选举 , 继续等待学生执行完 , 对于老师重发的命令会自动去重过滤
5) 学生执行命令过程中 , 班长的心跳没了(图例标识3、4、5): 选举当前任期 1 的班长 , 新班长接替老班长 , 老班长恢复心跳后变成普通学生
4、PBFT
PBFT是用来解决拜占庭将军问题的,比原始的BFT算法更高效, 复杂度由指数降低到多项式级别. 目前有很多平台都在使用该算法, 例如央行数字票据交易平台、腾讯区块链等. 算法中维护了三种状态, 包括节点数据副本三种状态 pre-prepare、prepared、committed, 消息的三种状态pre-prepare、prepare、commit. 以运动员跑步为例, 一般起跑口令为, “各就各位, 预备, 跑”, 这个口令对应了三种状态, 可以描述如下:
当裁判说出“各就各位”时, 就相当于发出了pre-prepare消息, 选手接受了命令就会脚踩进助跑器, 而这一动作被其他选手看到, 就会认为该选手进入了prepared 状态; “预备”就相当于prepare消息, 选手接受了就是双手撑起, 身子呈弓形, 而这一动作被其他选手看到, 就会认为该选手进入了committed状态.
以4人比赛跑步为例, 假设学校举行了代号为“N: 1xxx“的4人百米赛跑比赛, 这个“N: 1xxx“就相当于一个提案. 为了节省钱, 比赛并没有请裁判, 而是在4个选手中随机挑出一个做裁判, 假设裁判是公正的,
1) 当裁判喊出“各就各位”, 其他三人相当于接收到pre-prepare消息, 即会进入准备状态, 同时也将prepare状态广播出去
2) 假设此时有一名同学是拜占庭节点, 没有进行响应, 当其他选手接收到对应的prepare广播消息, 如果确认多于f个人(f为拜占庭节点, 此时f=1,所以至少是2个人)的状态和自己应有的状态相同, 则认为大家进入prepared状态, 选手会将自己收到的pre-prepare和发送的prepare信息记录下来.
3) 裁判看到至少2个人进入prepare状态, 就会接着喊出“预备, 跑“, 其他同学接收到口令(commit)消息后, 就会进入待跑状态, 拜占庭节点除外, 而这一个动作又相当于互相广播了一个 commit消息, 如果确认多于f个人(f为拜占庭节点, 此时f=1,所以至少是2个人)的状态和自己应有的状态相同, 则认为大家进入committed状态.
4) 当大家都确认进入Committed状态后, 就可以起跑了.
5) 假设裁判是不公正的, 则会被换掉, 重新选择一名选手当裁判. 这时候, 由于所有选手都记录了自己的状态和接受/发送的信息, 那些换掉前已经是committed状态的选手, 开始广播commit消息, 如果确认多于f个人(f为拜占庭节点, 此时f=1,所以至少是2个人)的状态和自己应有的状态相同, 则认为大家进入committed状态. 而对于换掉前是prepared 和pre-prepare状态的选手,则完全作废以前的命令和状态,重新开始.
PBFT算法有如下特点:
1) 排序: proposal有序号N , 且每一个节点按顺序接收proposal
2) 提案节点为拜占庭节点: 出现提案超时 , 挑选新leader
3) 法定多数: 一个节点一票 , 少数服从多数
4) 安全: 共识各节点由业务的参与方组成 ,安全性与稳定性由业务方保证
5) 效率: 共识的时延大约在2~5秒,基本达到商用实时处理的要求
5、PoW、PoS、DPoS
工作量证明(Proof of Work,PoW)机制随着比特币的流行而广为人知. 其大概流程为:
1) 向所有的节点广播新的交易
2) 每个节点把收到的交易放进块中
3) 在每一轮中, 一个被随机选中的节点广播它所保有的块
4) 其他节点在验证块中的所有的交易正确无误后接受该区块
5) 其他节点将该区块的哈希值放入下一个它们创建的区块中, 表示它们承认这个区块的正确性
股权权益证明(Proof of Stack,PoS)现在已经有了很多变种. 最基本的就是选择生成新的区块的机会应和股权的大小成比例, 股权可以是投入的资金, 也可以是预先投入的其他资源. 其大概流程为:
1) 加入PoS机制的都是持币人, 成为验证者(validator)
2) PoS算法在这些验证者里挑一个给予权利生成新的区块. 挑选顺序依据持币的多少
3) 如果在一定时间内, 没有生成区块, PoS则挑选下一个验证者, 给予生成新区块的权利
4) 以此类推, 以区块链中最长的链为准
委托权益人证明机制(Delegated Proof of Stake,DPoS)机制是PoS算法的改进. 他有个选取见证人的机制来解决中心化问题, 大概流程为:
1) 加入DPoS机制的都是持币人, 持币人可以选取委托权益人, 即见证人
2) 从选出的见证人种按持币量顺序挑选一个去对区块签名, 生成区块
3) 见证人的数量由权益所有者确定, 至少需要确保11个见证人, 必须尽量长时间在线, 以便做出响应; 见证人代表权益所有人签署和广播新的区块链; 见证人如果无法签署区块链, 就将失去资格, 也将失去这一部分 的收入; 见证人无法签署无效的交易, 因为交易需要所有见证人都确认.
三种模式的对比
6、应用场景
目前不同的共识算法应用在了不同的场景中, 大致可以分为如下:
1) PoW: 公有链、比特币、莱特币、以太坊前3个阶段Frontier、Homestead、Metropolis
2) PoS: 公有链、点点币、NXT、以太坊第4个阶段Serenity
3) DPoS: 公有链、BitShare
4) Paxos: 联盟链、私有链、Google Chubby、ZooKeeper
5) PBFT: 联盟链、私有链、超级账本、TBaaS
6) Raft: 联盟链、私有链、ETCD
四、智能合约
什么是智能合约? 如何执行合约?
智能合约一种计算机协议(程序) ,一旦制定和部署就能实现自我执行和自我验证,而且不再需要人为的干预. 其有如下特点
- 高效的实时更新: 无需第三方或中心化代理服务参与 ,能够在任何时候响应用户的请求
- 准确执行: 所有条款和执行过程是提前制定好的,并在计算机的绝对控制下进行
- 较低的人为干预风险: 部署之后,合约的所有内容无法修改,任何一方都不能干预合约的执行
- 去中心化权威: 合约的监督和仲裁都由计算机来完成 , 即共识机制
- 较低的运行成本: 大大减少合约履行、裁决和强制执行所产生的人力成本
智能合约可以支持多语言编程, 如go、rust、c 、solidity等等, 以腾讯云TBaas的长安链为例, 在管理平台上可以快速安装智能合约, 然后上链
以certificateMaker.go合约代码为例
代码语言:javascript复制package main
import (
"encoding/json"
"log"
"strconv"
"chainmaker.org/chainmaker/chainmaker-contract-sdk-docker-go/pb/protogo"
"chainmaker.org/chainmaker/chainmaker-contract-sdk-docker-go/shim"
)
type FactContract struct {}
// 存证对象
type Fact struct {
FileHash string `json:"FileHash"`
FileName string `json:"FileName"`
Time int32 `json:"time"`
}
// 新建存证对象
func NewFact(FileHash string, FileName string, time int32) *Fact {
fact := &Fact{
FileHash: FileHash,
FileName: FileName,
Time: time,
}
return fact
}
// 用于合约的部署和升级
// @param stub: 合约接口
// @return: 合约返回结果,包括 Success 和 Error
func (f *FactContract) InitContract(stub shim.CMStubInterface) protogo.Response {
return shim.Success([]byte("Init Success"))
}
// 用于合约的调用
// @param stub: 合约接口
// @return: 合约返回结果,包括 Success 和 Error
func (f *FactContract) InvokeContract(stub shim.CMStubInterface) protogo.Response {
// 获取参数
method := string(stub.GetArgs()["method"])
switch method {
case "save":
return f.save(stub)
case "findByFileHash":
return f.findByFileHash(stub)
default:
return shim.Error("invalid method")
}
}
func (f *FactContract) save(stub shim.CMStubInterface) protogo.Response {
...
// 返回结果
return shim.Success([]byte(fact.FileName fact.FileHash))
}
func (f *FactContract) findByFileHash(stub shim.CMStubInterface) protogo.Response {
...
// 返回结果
return shim.Success(result)
}
func main() {
err := shim.Start(new(FactContract))
if err != nil {
log.Fatal(err)
}
}
1、首先需要有一个合约对象的结构体FactContract, 作为合约主体
2、使用InitContract函数对合约进行部署和升级
3、使用InvokeContract可以调用对应的处理方法, 通常包括上链、查询等链上操作
4、合约编写完成后对其进行编译打包, 生成.7z压缩文件, 然后就可以在TBaas平台安装合约, 具体详见智能合约开发
5、安装完成后即可看到合约详情, 并可以添加一些初始化参数和合约调用方法(对应InvokeContract中方法方法)
六、思考
企业级的区块链应用需要满足哪些要求?
1、参与者必须是已认证的或者可识别的
2、网络需要获得许可
3、高交易吞吐量性能
4、交易确认低延迟
5、与商业交易有关的交易和数据的隐私和机密性
……
要满足以上这些要求, 可以参考Hyperledger Fabric区块链超级账本技术, 这里篇幅原因暂不做详细说明