兄弟连区块链教程分享eth源码分析RPC分析

栏目: 服务器 · 发布时间: 5年前

内容简介:兄弟连区块链教程分享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分析》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

深入理解并行编程

深入理解并行编程

[美] Paul E.Mckenney(保罗·E·麦肯尼) / 谢宝友 鲁阳 / 电子工业出版社 / 2017-7-1 / 129

《深入理解并行编程》首先以霍金提出的两个理论物理限制为引子,解释了多核并行计算兴起的原因,并从硬件的角度阐述并行编程的难题。接着,《深入理解并行编程》以常见的计数器为例,探讨其不同的实现方法及适用场景。在这些实现方法中,除了介绍常见的锁以外,《深入理解并行编程》还重点介绍了RCU的使用及其原理,以及实现RCU的基础:内存屏障。最后,《深入理解并行编程》还介绍了并行软件的验证,以及并行实时计算等内容......一起来看看 《深入理解并行编程》 这本书的介绍吧!

在线进制转换器
在线进制转换器

各进制数互转换器

随机密码生成器
随机密码生成器

多种字符组合密码

HEX HSV 转换工具
HEX HSV 转换工具

HEX HSV 互换工具