人类的历史,即分久必合,合久必分。
2017 年,比特币因行情疯长火热一时。2018 年伊始,其使用的底层技术区块链又迎来狂欢:从国内创投人到硅谷投资者,从 BAT 到互联网企业众生,都纷纷加入这场技术的斗艳中。
在去中心化技术给这个时代带来新革命的同时,区块链也在更多的行业施展拳脚,利用去中心化计算机系统来创建安全、可验证和永久的交易记录,从而解决不透明或非可信问题。从本质上讲,它创建了一个安全的、分布式的信息和交易记录数据库。
对于交易不透明等问题,广告行业存在的欺诈流量、隐私泄露等现象正在倒逼区块链技术发展,以借其构造新的广告环境。
例如,区块链建构的个人数据档案、交易认证、透明性标准等技术实现方案,在广告「按需使用时代」提供了更好的契合点。FreeWheel 作为媒体广告管理、投放及预测方,同样也需要应对相应痛点。因而在与第三方评测机构和主流的 DSP 集成时,其尝试搭建了一套联盟链系统以达成账本的一致性。
本文中,我们将集中讲解 FreeWheel 区块链应用的缘起、架构及运作模式。
拨开云雾见天日:为何使用区块链技术解决问题?
区块链是加密货币的核心技术基础,具有不可篡改、透明等特性,而在广告行业内涉及多方集成,容易产生数据不一致等问题,所以 FreeWheel 尝试引入区块链技术到业务场景中。
但需要澄清的是,FreeWheel 做区块链并不是想做一个新的代币系统,而是希望用区块链解决当前广告行业当中常见的痛点。
在广告行业中,任何参与者都会频繁地与第三方进行集成。比如,在评测投向效果场景中,会和 Nielsen、Comscore 等市场调研公司集成,以评价广告的投放效果。另外,通过实时竞价(OpenRTB)协议,SSP 也需要与 DSP 集成,帮助媒体公司卖掉剩余流量,最大程度上实现流量变现。
集成过程中,对于广告有效投放次数和调用服务收费的评定,会由于各自记账模式和方法的不同而导致双方报价完全不匹配。此外,按天或按月出账单具有较高的延时性,较难验证或达成一致的结果。因此,
FreeWheel 引入区块链技术的最主要目的,是以期让整个交易流程透明化,使整个交易记录被所有参与者共享——当整个交易数据记载在区块链里,各方参与者拥有所有账本记录,结算即变得简单。
在采用区块链技术解决方案前,FreeWheel 在技术选型进行了诸多尝试。已有的分布式数据库无法规避恶意篡改,也缺乏有效的共识算法和智能合约机制。而区块链本身的不可篡改和消息协同这类天然特性,以及 Fabric 或以太坊建立的终极抽象的基础层,使得区块链应用能在其方案中一施拳脚。
FreeWheel 主任工程师王敏解释说,目前,公司对区块链的主要需求是针对多方集成账本不一致的问题,期望增强交易的透明性以达到账本的最终一致性,所以基于对共识机制和编程语言支持等考虑,FreeWheel 目前的选择是以 Fabric 作为基础,搭建广告行业联盟链。
FreeWheel 区块链应用架构层级及原理
正因为广告商业建立的联盟链特性,所有参与者都是已知的并且验证过,因此所有交易参与者需要先从 Root CA 处获得公钥和私钥,每个参与者也同样会负责创建交易——生成帐单系统查询该区块链并对其定价。创建的区块链交易包含上层发送的原始请求信息、所有 DSP 的返回、参与者的签名。
FreeWheel 区块链应用整体架构如下:
该区块链架构中包含客户端(Client)和服务端(Peer)。
区块链的客户端(Client)在收到上层次所有应用和发出的调用后,负责创建一个包含原始广告请求的交易。服务端(Peer)收到区块链创建的交易后,会通过验证签名来确保交易的合法性。如果合法,服务端就在存储账本里新增 Block,同时 State DB 会统计不同参与者之间调用的次数,生成 Billing Report。
整体架构中的上半部分则是广告行业内已有的系统,主要包括 OpenRTB 集成和 Mesurement 集成:
-
OpenRTB 集成:在收到多家 DSP 返回结果之后,SSP 会根据当前所有候选广告选出最终投放广告,计算第二高价返回给 DSP 并播放该广告。同时 SSP 也会将完整的、包含多方签名的交易记录通过 RPC 的调用方式(无论是 SSP、DSP,还是 Nielsen,每个参与者都有这样一套系统)记录到相应的账本中 。
-
Mesurement 集成:评测机构在收到包含调用者签名的请求并附加自己的签名后,将该条包含多方签名的交易记录到相应的账本中 。
整体架构中的下半部分则需要每个参与者维护:
Intermediate Certificate Authority
:需要从 Root CA 注册、更新相应的证书,并且验证交易里签名的合法性。
客户端层
:
-
Blockchain Client:对接上层服务,打包原始交易记录并加上自身的签名,创建区块链的交易发送给相应的服务(Peer)。
-
Billing System:查询系统,根据区块链记录产生账单。
服务层
:部署智能合约和产生新 Block 到区块链。
数据层(包含两个部分,StateDB 和账本)
:
-
State DB: State DB 统计了多方相互调用的总次数, 方便快速查询。
-
账本:包含了所有的交易记录,在参与者中都是相同的备份,具有可追溯、无法篡改等特性。
另外,在 OpenRTB 集成、Mesurement 集成和 Participants' Blockchain 部分外,整体架构中还包括一个联盟链管理平台。管理平台由各中心委员会负责运维:
-
会员管理系统和认证中心:当有新公司、组织加入该平台时负责发放证书。
-
账本管理:即 Channel,一个账本对应一个 Channel。Public Channel 由中心委员创建,被所有参与者共享,每个参与者可以创建 Private Channel 并授权给部分参与者,但其不允许别的参与者访问以避免信息泄露。
-
共识管理:即 Order Service。Fabric 可以选择不同的共识机制:Solo、KafKa、SBFT(尚在开发中)。不同的账本可以选择不同的 Order Service,同一个 Order Service 也可加入到多个 Channel。Order Service 由中心委员会运维。
-
智能合约管理:即 Chaincode。智能合约是多方对特定交易类型达成一致的业务逻辑,对于相应参与者来说,Chaincode 的实现都是公开的,且能部署在参与者的 Endorse 节点上。
FreeWheel 区块链应用系统运作模式
在评测集成的场景下,比如系统 A 调用评测机构 B 服务时,A 会把投放的广告、观看广告的终端用户和当前视频内容等信息及其对交易的签名发送至 B,B 在收到系统 A 请求之后,其所属的客户端会包装原始的请求信息并加上 B 的签名发送给区块链:
-
B 将包含双方签名的交易发给 A 和 B 的 Endorser ,双方节点各自验证并确定交易的真实性,接着调用相同的 Chaincode 产生一致的收费结果;
-
Endorser 节点把 Chaincode 执行后的结果、节点签名返回结果给 Client;
-
Client 收到双方 Endorser 节点的返回,综合执行结果,背书节点的签名,原始交易记录的信息发送给 Order Service;
-
Order Service 将背书后的结果广播给所有节点(当有多个节点的时候,参与者可指定一个节点为主节点,Order Service 将新交易广播至主节点,再由其广播到内部剩余节点,从而提高广播的效率)。
-
Order Service 会按时间戳或 Client 发送的先后顺序对所有的交易进行排序。虽然往帐本里记时不会调用智能合约,但会有一些额外的检查(如查看交易 ID 是否重复等)。因为签名原因,所以 Client 不能偷改交易 ID。
-
所有节点把新交易更新到自己一方的账本中。
这里值得一提的是,Farbic 记账流程与以太坊有很大的不同。
以太坊包含两种账户:外部账户和合约账户每笔交易都需要指定最大 gas 的值,以太坊虚拟机会基于 gas 的设置来控制智能合约执行的数量,防止恶意攻击。而 Fabric 联盟链里所有的客户端和服务端都必须已认证,所有的交易必须有参与者签名(交易发起者的签名,背书节点的签名等),降低公有链的恶意节点问题。
相对于以太坊共识机制 PoW,Fabric 共识机制可以选择(目前支持 Solo,Kafka),达成共识效率也更高,避免计算资源的浪费。
目前 Fabric 共识机制处理得非常简化,比较适合广告行业联盟链中的场景——即参与者数量相对有限,参与者之间基本可信,并发高。Fabric 主要采用 Kafka——Order Server 收到 Client 发的请求之后往 Kafka 集群里「塞」(相当一个 Producer 不停地产生记录),接着按照塞的先后顺序排序打包并广播给 Commit Peer,Commit Peer 收到消息块则验证里面所有的消息并记账。
对于 Kafka,其本身支持向下游发送完全一样的数据,顺序不会颠倒。当 Client 端偶遇网络不稳定而形成的消息堆积或系统宕机时,重启后 Kafka 会自动把缺省的消息再次推送。这是其非常重要的功能。对于类似的系统宕机或消息堆积,FreeWheel 搭建的区块链系统有实时监控机制,可实现暂缓发送。
另外,如果参与者内部有大批节点连接 Kafka 并需要训练该 Kafka 集群,这样对 Kafka 性能要求也较高。对于这种问题的解决方案是:每个参与者选一个类似于 VIP 或 Leader 节点,并且只需 该节点连 Kafka 的 Order Service。 待 Order Service 下发至 Leader 后,Leader 会做内部的转发,从而减小 Order Service 的压力,而参与者内部的记账节点数量可自己随意添加。
如何使用智能合约技术进行区块链开发?
智能合约属于多方针对某交易达成一致的业务处理逻辑,即达成一致的链码(Chaincode)。如上文所说,Chaincode 在参与者之间公开,且部署在其 Endorse 节点上,可自动执行交易并产生结果,不需要第三方介入。
相对于以太坊主要支持 Solidity(类似 JavaScript)、Serpent(类似 Python),Fabric 支持用 Golang、Java、Node.js 实现智能合约,FreeWheel 在开发过程中主要基于 Golang。要实现智能合约,只需集成 Fabric 的一个接口,实现 Init 和 Invoke 两个函数即可,而 Fabric Chaincode 通过 gRPC 与 Peer 节点交互。Init 函数只会在第一次启动和每次升级的时候会被调用,负责初始化的内部参数。
type Chaincode interface {
Init(stub ChaincodeStubInterface) pb.Response
Invoke(stub ChaincodeStubInterface) pb.Response
}
Invoke 函数会在每笔交易验证中调用。例如,验证签名和收费模式的判定都由 Invoke 函数执行,负责主要业务逻辑的实现。传入的参数主要包含以下部分,可以通过 GetFunctionAndParameters 拿到 Client 发送的待背书的原始交易记录和期望的操作。
对于简单的业务场景,或许一个 Invoke 函数就可以实现。但针对复杂的业务场景,则可以通过多个 Chaincode 之间调用来实现,进而模块化复杂的智能合约,并且 Chaincode 间的调用不会产生非预期的交易记录和非预期的 Block,而是产生一个综合的帐本,或若干个小帐本。
type ChaincodeStub struct {
TxID string
args [][]byte
…
}
//get transactions from parameters
func (stub *ChaincodeStub) GetFunctionAndParameters() (function string, params []string)
//invoke other chaincode
func (stub *ChaincodeStub) InvokeChaincode(chaincodeName string, args [][]byte, channel string) pb.Response
FreeWheel 在开发中发现 Golang 的 Chaincode 目前只支持官方标准包,否则无法正常运行在 Endorser 节点上。这也是其目前在实际开发中遇到的重要问题之一,关于如何更好地引入第三方包,FreeWheel 目前还没有更好的解决方案。
区块链中的微服务化和安全