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

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

内容简介:兄弟连区块链教程分享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调用方法标准如下:

·对象必须导出
·方法必须导出
·方法返回01(响应或错误)或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分析》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

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

Effective Java

Effective Java

Joshua Bloch / Addison-Wesley Professional / 2018-1-6 / USD 54.99

The Definitive Guide to Java Platform Best Practices—Updated for Java 9 Java has changed dramatically since the previous edition of Effective Java was published shortly after the release of Jav......一起来看看 《Effective Java》 这本书的介绍吧!

MD5 加密
MD5 加密

MD5 加密工具

SHA 加密
SHA 加密

SHA 加密工具

正则表达式在线测试
正则表达式在线测试

正则表达式在线测试