学习记录:fabric(6)- 系统设计(2)

新开一节,继续做项目

出现一个很有趣的问题,ENDORSEMENT_POLICY_FAILURE。官网教程可以搜得到,但其实不是那样的。

后来发现是我调用mysql,创建表,然后肯定另一个节点运行不通啊。。。那一个节点成功,另一个不成功,那肯定返回出错呀。。。

所以这就需要考虑到背书阶段,看看怎么在背书之后再执行。

现在两个思路,1,如果能够找到入口,那就可以;2,不行就用定时器,任务队列这样。3.两步法,第一步日志上链,返回交易id,第二步调用交易id执行命令ExecTx2SQL。

所以,现在以便排除这个错误,一边先把其他的SQL语句构建弄好。

条件的构建,可能还是得用sql-build,这个能简单些。

现在弄好了,CreateTable,TableExist,DropTable,RenameTable,InsertRecord,UpdateRecord,DeleteRecord,GetRecord。

现在的核心问题依然是:需要先共识,再执行SQL。所以还是考虑那两个方法1)弄一个定时任务,就是隔一段时间,查询当达成了共识,则执行。(也就是有一些延迟)。2)查看能不能通过客户端两步执行。

第一个方法要关注一下能不能获得账本信息;第二个方法是要看peer能不能实时的获得共识结果。

// GetState returns the value of the specified `key` from the
	// ledger. Note that GetState doesn't read data from the writeset, which
	// has not been committed to the ledger. In other words, GetState doesn't
	// consider data modified by PutState that has not been committed.
	// If the key does not exist in the state database, (nil, nil) is returned.
	GetState(key string) ([]byte, error)

	// PutState puts the specified `key` and `value` into the transaction's
	// writeset as a data-write proposal. PutState doesn't effect the ledger
	// until the transaction is validated and successfully committed.
	// Simple keys must not be an empty string and must not start with a
	// null character (0x00) in order to avoid range query collisions with
	// composite keys, which internally get prefixed with 0x00 as composite
	// key namespace. In addition, if using CouchDB, keys can only contain
	// valid UTF-8 strings and cannot begin with an underscore ("_").
	PutState(key string, value []byte) error

GetState可以获取账本信息,获取不到还未达成共识的。

应该是做成一个队列,定时器不断的检测队列。

在同一个方法内部是不能等待的,肯定得不到结果。因为节点上还没执行完成,所以必须二次才会有结果。只能是发送,返回一个已经提交任务。二次请求才行。

现在尝试一下这种做法。当然,同时队列也加上,在查到数据后,自动执行SQL。这样我可以看看到底多久可以查到数据

不行,使用go语句执行异步线程不成功,出现了Failed to handle GET_STATE. error: no ledger context。无法获取到账本的信息。

通过在客户端再次调用GetValue,看到,其实已经提交成功。但是在链码中使用go语句异步执行是不行的。
在这里插入图片描述其实这里,就有一个问题,就是得改fabric本身了,也就是队列要构建在fabric中,这样才能在共识执行完成之后,一个挨着一个去执行。其实就是peer节点内部。那这样一来,mysql的连接操作,也得放进mysql了。链码中,其实就成了一个SQL语句组织和方法的调用。
在这里插入图片描述按照chainsql的这个内容,其实就是应该返回一个交易id,在链码中,我是使用交易ID作为key写入了SQL语句。
所以,在fabric中应当可以查到相关内容,并进行读取。
这一点还需验证,就是顺着fabric的peer部分,查看一下,为peer添加逻辑:1.队列,2.mysql数据库操作

转进fabric

现在的任务变成了如何把fabric自主编译一下。先看fabric代码如何编译,这样才能修改。

fabric编译遇到一个问题:go install: cannot install cross-compiled binaries when GOBIN is set

先看懂makefile。

注意:把go的GOARCH设为amd64,因为本机是linux/amd64,不要设为别的,之前设为386,算是跨平台。
注意:注意开启梯子,有些东西要下载。

这里还能打包自定义的docker镜像。

在这里插入图片描述

等下专门写一个MakeFile的解析。

或者应当搞清楚链码的执行流程。

第二种方法

客户端两步执行,
在这里插入图片描述
看到了这个东西,如果能够监听到区块变化,然后真正执行,那就没问题了。

反正把SDK封装成一个新的SDK,chainsql也是封装了ripple。

在这里插入图片描述测试得到,每一次putstate,会出现新的区块。

解析一下区块数据是什么,看看能不能找到真正的数据.

可以的,二步法是可行的。可以获取到区块内部的详细信息。

// listener内部
var block  = event.blockData;
var payload = block.data.data[0].payload 
var rwset = payload.data.actions[0].payload.action.proposal_response_payload.extension.results.ns_rwset


network.addBlockListener(listener);

block的一些介绍
在这里插入图片描述那个listener也不用加什么option,默认就是监听最近的一个块。那刚刚提交了,肯定是获取包含刚刚交易的最近一个块。

现在就是还得试试不能达成一致的时候会不会获取不到东西,处理一下错误情况。
不用担心了,共识失败,外部直接会出错。

这是暂时比较靠谱的一个玩法,先把这个弄通。

现在把重要的表操作都真正实现,不过这里注意,表创建还是不行的,因为这里我操作的是同一个数据库

现在不需要,其实直接从第一次的result中提取txid即可,然后调用。现在写一下chaincode的执行SQL。

可以了,扩展。

现在还有一个时间过长需要检查数据库连接的问题。因为可能断开。而且也不能长时间保持连接。

  1. 数据加密
  2. 节点间同步
  3. 表权限

第一个是基础,先得能够加密,然后构造表

ClientID, table_name, table_name_in_db, tx hash, block hash, block num, deleted, autosync, tx_time

主要是有一个自动同步的东西比较难操作,这个东西如果纯用链码,需要参照账本中的信息,进行操作。

数据加密,这个秘钥可以用自动生成的,但是需要考虑节点重启的问题。重启的话,必须要找个地方存起来。但是不知道chainsql是怎么处理的。

chainsql好像是当做一次交易保存在链上的。我也可以这么做,初始化的时候,写入状态,键就是自身节点peer的ID。

放进全局状态不行,因为全局状态读写必须所有节点运行一致。这里只能保存到私有数据。
私有数据和全局状态是分开的:This private data is stored in private state db on the peer (separate from public state db), and is disseminated between authorized peers via gossip protocol.
实际的账本存储在:/var/hyperledger/production/ledgersData中。

但是这样其实更公开,其实不好,按说应当是保存在某一笔交易中。或者说,这还是应该属于是peer节点的功能。

现在有点麻烦,私有数据也需要一致,行为模式和世界状态一样的。
私有数据不行,一样是要同步到权限内节点的,所以必须修改peer。

加密,秘钥放在了core.yaml中,现在主要就是改一下sqlmaker中,加密过程放在这里,sql生成。
但是感觉应该单独弄一个类来处理这个功能。字段转hex之类的。

秘钥从启动的时候传入,在dbmanager中保存,然后在生成SQL的时候执行,有一个特殊的点,表名,这个需要查询得到,不过也不要紧,这个属于dbmanager内部操作。

参考

  • https://blog.csdn.net/qq_22211217/article/details/102729151
  • http://cn.piliapp.com/mysql-syntax-check/ SQL语法检查
  • https://blog.csdn.net/darmao/article/details/81077055
  • https://my.oschina.net/jamesren/blog/3123882
  • https://blog.csdn.net/lwldcr/article/details/78722330
  • https://blog.csdn.net/z199172177/article/details/78954503
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值