1
Fabric除了在底层文件系统中记录区块链数据,还提供world state(stateDatabase)作为区块链缓存数据库进行更便捷的数据写入和查询操作。
如此设计我的理解是为了解决区块链查询和写入的效率问题。在实际项目使用中处于好奇尝试了对world state中数据的给中直接修改去探寻world state数据和blockchain上的数据关系。
2
首先将节点Peer配置文件core.yaml中将state设置为CouchDB,启动CouchDB的docker后通过CouchDB utils访问CouchDB数据库,这时可以看到该节点下的channel和chaincode部署以及每个chaincode下的数据(一个chaincode在这里我的理解就映射成了一个CouchDB的数据库表)。
3
设置两个Org,4个节点的区块链网络,节点加入channel并部署智能合约后,模拟两个账号A&B,初始A的balance为100,B的balance为200。
部署智能合约时背书策略使用-P "AND('Org1MSP.member','Org2MSP.member')", 两个节点的锚节点同时进行背书。
进行A与B在智能合约上的转账50,A的余额为50, B的余额为250。
访问4个节点的区块链数据和world state数据可以看到一致的结果。
4
之后直接登录world state(CouchDB的管理控制台)进行数据修改,将A的balance在Peer0.Org0中修改为100,这样在Peer0.Org0的world state中A显示的余额就成了100.
通过chaincode query的方式获得A的balance得到的余额结果也是100。
通过shim.ChaincodeStubInterface.GetHistoryForKey的方式获得A的balance为50(区块链中A账号所有的账户变更记录)
通过chaincode在此进行A和B直接的转账时,因背书策略智能合约调用失败,Fabric发现两个组织下的缓存数据库world state不一致。
5
同时将两个组织内的world state中的A账号余额都改为100后发现在此调用A和B之间转账的智能合约是可以成功的,且数据按A为100的情况下变更。
在使用GetHistoryForKey获得区块链A账号所有数据的时候账户余额是直接从50到了100再错变更,在审计的过程中很容易发现这笔数据出现了问题。
6
毕竟链圈的发展依然是个起步阶段,Fabric还是个半成品的状态,针对于此情况可进行更安全的优化(更安全同时意味着损失一定的效率):
1. chaincode智能合约写入数据时进行加密和解密的处理。目前Fabric的数据在world state中看到的是明文,将明文加密后在没有算法支持的情况下就无法对world state中的数据进行修改
2. 数据读取和写入通过qscc或GetHistoryForKey从链上读写(这个方式可能有点二,就完全跳过了world state这种提高效率的方案)
3. 提供一个不属于联盟任何一方的节点作为数据背书,并在执行智能合约的时候将此节点加入到背书策略中,防止联盟内存在单节点作恶。
领取专属 10元无门槛券
私享最新 技术干货