内容简介:兄弟连区块链教程分享eth源码分析RPC分析。这是一个交互式的 JavaScript 执行环境,在这里面可以执行 JavaScript 代码,其中 > 是命令提示符。在这个环境里也内置了一些用来操作eth的 JavaScript 对象,可以直接使用这些对象。这些对象主要包括:eth:包含一些跟操作区块链相关的方法;
兄弟连区块链教程分享eth源码分析RPC分析。
这是一个交互式的 JavaScript 执行环境,在这里面可以执行 JavaScript 代码,其中 > 是命令提示符。在这个环境里也内置了一些用来操作eth的 JavaScript 对象,可以直接使用这些对象。这些对象主要包括:
eth:包含一些跟操作区块链相关的方法;
net:包含一些查看p2p网络状态的方法;
admin:包含一些与管理节点相关的方法;
miner:包含启动&停止挖矿的一些方法;
personal:主要包含一些管理账户的方法;
txpool:包含一些查看交易内存池的方法;
web3:包含了以上对象,还包含一些单位换算的方法。
personal.newAccount('liyuechun')
personal.listAccounts
account1 = web3.eth.coinbase
web3.eth.getBalance(account1)
发送交易:
eth.sendTransaction({from:"0x1c0f18be339b56073e5d18b479bbc43b0ad5349c", to:"0x13d0dc1c592570f48360d7b779202d8df404563e", value: web3.toWei(0.05, "ether")})
增加节点
admin.addPeers("..")
查看当前链连接信息
admin.nodeInfo.enode
查看连接了几个节点
web3.net.peerCount
net.listening
查看连接了几个节点
net.peerCount
连接对应workid链的控制台
--networkid=1114 console
初始化创世块
init /home/yujian/eth-go/genesis.json --datadir /home/yujian/eth-go
根据创世块启动,并且开启控制台
--datadir /home/yujian/eth-go --networkid 1114 --port 30304 console 2>>/home/yujian/eth-go/myEth2.log
RPC包概述
RPC包主要的服务逻辑在server.go和subscription.go包中。接口的定义在types.go中。
RPC包主要实现在启动节点的时候,将自己写的api包通过反射的形式将方法名和调用的api绑定。在启动命令行之后,通过输入命令的形式,通过RPC方法找到对应的方法调用,获取返回值。
RPC方法追踪
首先,在geth启动时,geth中有startNode方法,通过层层跟踪我们进入到了Node.Start()方法中。
在start方法中,有一个startRPC方法,启动节点的RPC。
// startRPC is a helper method to start all the various RPC endpoint during node // startup. It's not meant to be called at any time afterwards as it makes certain // assumptions about the state of the node. func (n *Node) startRPC(services map[reflect.Type]Service) error { // Gather all the possible APIs to surface apis := n.apis() for _, service := range services { apis = append(apis, service.APIs()...) } // Start the various API endpoints, terminating all in case of errors if err := n.startInProc(apis); err != nil { return err } if err := n.startIPC(apis); err != nil { n.stopInProc() return err } if err := n.startHTTP(n.httpEndpoint, apis, n.config.HTTPModules, n.config.HTTPCors); err != nil { n.stopIPC() n.stopInProc() return err } if err := n.startWS(n.wsEndpoint, apis, n.config.WSModules, n.config.WSOrigins, n.config.WSExposeAll); err != nil { n.stopHTTP() n.stopIPC() n.stopInProc() return err } // All API endpoints started successfully n.rpcAPIs = apis return nil }
这里,startRPC方法在执行时就会去读取api,然后暴露各个api。
apis()的定义如下:
// apis returns the collection of RPC descriptors this node offers. func (n *Node) apis() []rpc.API { return []rpc.API{ { Namespace: "admin", Version: "1.0", Service: NewPrivateAdminAPI(n), }, { Namespace: "admin", Version: "1.0", Service: NewPublicAdminAPI(n), Public: true, }, { Namespace: "debug", Version: "1.0", Service: debug.Handler, }, { Namespace: "debug", Version: "1.0", Service: NewPublicDebugAPI(n), Public: true, }, { Namespace: "web3", Version: "1.0", Service: NewPublicWeb3API(n), Public: true, }, } }
其中,Namespace是我们定义的包名,即在命令行中可以调用的方法。
Version是这个包的版本号。
Service是所映射的API管理的结构体,这里API的方法需要满足RPC的标准才能通过校验。
成为RPC调用方法标准如下:
·对象必须导出 ·方法必须导出 ·方法返回0,1(响应或错误)或2(响应和错误)值 ·方法参数必须导出或是内置类型 ·方法返回值必须导出或是内置类型
在将各个API都写入到列表中之后,然后启动多个API endpoints。
这里我们以启动IPC为例,主要看startIPC方法。
func (n *Node) startIPC(apis []rpc.API) error { // Short circuit if the IPC endpoint isn't being exposed if n.ipcEndpoint == "" { return nil } // Register all the APIs exposed by the services handler := rpc.NewServer() for _, api := range apis { if err := handler.RegisterName(api.Namespace, api.Service); err != nil { return err } n.log.Debug(fmt.Sprintf("IPC registered %T under '%s'", api.Service, api.Namespace)) } ...
这里会首先启创建一个rpc server。在启动的过程中,rpc server会将自己注册到handler中,即rpc包。
在创建rpc server之后,handler会通过RegisterName方法将暴露的方法注册到rpc server中。
// RegisterName will create a service for the given rcvr type under the given name. When no methods on the given rcvr // match the criteria to be either a RPC method or a subscription an error is returned. Otherwise a new service is // created and added to the service collection this server instance serves. func (s *Server) RegisterName(name string, rcvr interface{}) error { if s.services == nil { s.services = make(serviceRegistry) } svc := new(service) svc.typ = reflect.TypeOf(rcvr) rcvrVal := reflect.ValueOf(rcvr) if name == "" { return fmt.Errorf("no service name for type %s", svc.typ.String()) } if !isExported(reflect.Indirect(rcvrVal).Type().Name()) { return fmt.Errorf("%s is not exported", reflect.Indirect(rcvrVal).Type().Name()) } methods, subscriptions := suitableCallbacks(rcvrVal, svc.typ) // already a previous service register under given sname, merge methods/subscriptions if regsvc, present := s.services[name]; present { if len(methods) == 0 && len(subscriptions) == 0 { return fmt.Errorf("Service %T doesn't have any suitable methods/subscriptions to expose", rcvr) } for _, m := range methods { regsvc.callbacks[formatName(m.method.Name)] = m } for _, s := range subscriptions { regsvc.subscriptions[formatName(s.method.Name)] = s } return nil } svc.name = name svc.callbacks, svc.subscriptions = methods, subscriptions if len(svc.callbacks) == 0 && len(svc.subscriptions) == 0 { return fmt.Errorf("Service %T doesn't have any suitable methods/subscriptions to expose", rcvr) } s.services[svc.name] = svc return nil }
在RegisterName方法中,这个方法会将所提供包下所有符合RPC调用标准的方法注册到Server的callback调用集合中等待调用。
这里,筛选符合条件的RPC调用方法又suitableCallbacks方法实现。
这样就将对应包中的方法注册到Server中,在之后的命令行中即可调用。
以上所述就是小编给大家介绍的《兄弟连区块链教程分享eth源码分析RPC分析》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:- 兄弟连区块链教程以太坊源码分析core-genesis创世区块源码分析
- 兄弟连区块链教程以太源码分析accounts账户管理分析
- 分析区块链的技术发展趋势
- 兄弟连区块链教程以太坊源码分析CMD深入分析(一)
- 中国区块链行业融资数据分析:北上深杭区块链创业活跃度最高
- 区块链教程Fabric1.0源代码分析blockfile区块文件存储2
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
《Unity3D网络游戏实战(第2版)》
罗培羽 / 机械工业出版社 / 2019-1-1 / 89.00元
详解Socket编程,搭建稳健的网络框架;解决网游中常见的卡顿、频繁掉线等问题;探求适宜的实时同步算法。完整的多人对战游戏案例,揭秘登录注册、游戏大厅、战斗系统等模块的实现细节。 想要制作当今热门的网络游戏,特别是开发手机网络游戏,或者想要到游戏公司求职,都需要深入了解网络游戏的开发技术。本书分为三大部分,揭示网络游戏开发的细节。 第一部分“扎基础”(1-5章) 介绍TCP网络游......一起来看看 《《Unity3D网络游戏实战(第2版)》》 这本书的介绍吧!