ethereum rpc 调用分析

作者: wade_van | 来源:发表于2017-09-26 22:41 被阅读5037次

以太坊以JSON RPC的方式提供API service。本文将从go-ethereum源码中挖掘服务端如何提供JSON RPC 服务。

服务端启动rpc server

➜  go-ethereum git:(master) ✗ tree -d -L 1
├── cmd
          ├── geth
                   ├── main.go
├── internal
          ├── ethapi
                   ├── api.go
├── node
├── rpc
...

go-ethereum的代码很多,单从发起一笔转账这样一个api而言,geth节点涉及的代码相对简单。
首先,cmd/geth/main.go是整个geth节点的entrypoint,main函数会实例化一个全功能的节点:

func geth(ctx *cli.Context) error {
    node := makeFullNode(ctx)
    startNode(ctx, node)
    node.Wait()
    return nil
}

实例化之后,将调用node/node.go中的Start方法,来配置node相应的服务, 然后启动,等到所有的服务启动完成之后,节点开启RPC服务,根据config将相应的服务注册到RPC服务的白名单中:

func (s *Server) RegisterName(name string, rcvr interface{}) error {
    ...
    methods, subscriptions := 
    suitableCallbacks(rcvrVal, svc.typ)
    ...
    svc.name = name
    svc.callbacks, svc.subscriptions = methods, subscriptions

上述方法将一个service中的可以rpc调用的method存储到server的map中。
go-ethereum节点的rpc提供了四种能力的rpc,以HTTP为例:

func (n *Node) startHTTP(endpoint string, apis []rpc.API, modules []string, cors []string) error {
    // Register all the APIs exposed by the services
    ...
    // All APIs registered, start the HTTP listener
    var (
        listener net.Listener
        err      error
    )
    if listener, err = net.Listen("tcp", endpoint); err != nil {
        return err
    }
    go rpc.NewHTTPServer(cors, handler).Serve(listener)
    ...
}

geth节点将监听端口,默认是8545,然后开启HTTPServer,等待http rpc请求。

HTTP RPC 请求响应流程

一个标准的HTTP RPC请求如下:

curl -H "Content-Type: application/json" -X POST --data \
'{"jsonrpc":"2.0","method":"eth_sendRawTransaction","params":["0xd46e8dd67c5d32be8d"],"id":1}' http://localhost:8545

需要jsonrpc, method, paramsid构成request body。当我们的geth节点的rpc server监听到新的request到来时,将会:

  1. 实例化一个NewJSONCodec编码器。
  2. 通过编码器来将request转换成jsonRequest,然后获取service_name和service_method以及params。
  3. 通过service_name 和service_method,可以找到当时注册的rpc服务。
  4. 通过反射方式运行rpc服务reply := req.callb.method.Func.Call(arguments),得到method的返回值
  5. 利用编码器将返回值json序列化,然后返回codec.Write(response)

针对一个转账交易的话,我们得知service_name 是eth,service_method是sendRawTransaction,其方法在internal/api.go中。运行reply := req.callb.method.Func.Call(arguments)之后我们得到的reply是一个common.Hash对象,然后通过json序列化我们得到的结果是TxnHash的字符串。

{
  "id":1,
  "jsonrpc": "2.0",
  "result": "0xe670ec64341771606e55d6b4ca35a1a6b75ee3d5145a99d05921026d1527331"
}

相关文章

  • ethereum rpc 调用分析

    以太坊以JSON RPC的方式提供API service。本文将从go-ethereum源码中挖掘服务端如何提供J...

  • Call Ethereum rpc

    运行geth curl 请求 python script personal 模块 开启 personal模块api...

  • Ethereum 以太坊智能合约调用源码分析

    title: Ethereum 以太坊智能合约调用源码分析date: 2018-06-16 09:47:08tag...

  • WHC RPC业务解析

    WormHole RPC的处理流程 RPC 的业务整理 RPC的调用流程 燃烧BCH,获取基础货币RPC调用流程 ...

  • JavaGuide知识点整理——RPC原理

    何为RPC? RPC即远程过程调用,通过名字我们就能看出RPC关注的是远程调用而非本地调用。为什么要RPC?因为两...

  • 基于netty手写RPC框架

    代码目录结构 rpc-common存放公共类 rpc-interface为rpc调用方需要调用的接口 rpc-re...

  • rpc学习

    什么是RPC RPC:Remote Produre Call-远程过程调用,像调用本地方法一样调用远程方法 RPC...

  • JAVA常用的RPC框架

    RPC(Remote Process Call),远程过程调用。RPC将本地调用转化为远程调用(非本地调用,个人理...

  • ethereum的txpool

    参考:1.https://github.com/ethereum/wiki/wiki/JSON-RPC#eth_s...

  • RPC框架原理

    RPC调用是面向服务架构场景下进行服务间调用的常用组件,一个完整的RPC调用的流程如图1所示: 为了方便RPC调用...

网友评论

    本文标题:ethereum rpc 调用分析

    本文链接:https://www.haomeiwen.com/subject/rspeextx.html