淘先锋技术网

首页 1 2 3 4 5 6 7

go访问区块链,采用的是json-rpc的方式来进行访问。这里用了github上的库ethrpc,这个库采用json-rpc的方式来访问geth节点。

1 先下载ethrpc库

go get -u github.com/onrik/ethrpc

2 上代码

package main

import (
	"fmt"
	"log"
	"github.com/onrik/ethrpc"
)

ar url string = "http://192.168.1.20:8100"

func main() {
	client := ethrpc.New(url)

	version, err := client.Web3ClientVersion()
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(version)
	
	// Send 1 eth
	for {
		txid, err := client.EthSendTransaction(ethrpc.T{
			From:"0xb3b1275f38ed3ace62ce0c114fe1686a66194cf5",
			//From:  "0xe0d268886b753fd1778b3698956726c3dbf5d9a4",
			To:    "0xc004fdeb4dac9827c695c672daa2afb0ed2d0779",
			Value: ethrpc.Eth1(),
		})
		if err != nil {
			log.Fatal(err)
		}
		fmt.Println(txid)
	}

}

3 带Http Basic Athulization安全认证的访问

追踪client.Web3ClientVersion()函数,可以看到ethrpc/ethrpc.go源码中:

// Call returns raw response of method call
func (rpc *EthRPC) Call(method string, params ...interface{}) (json.RawMessage, error) {
	request := ethRequest{
		ID:      1,
		JSONRPC: "2.0",
		Method:  method,
		Params:  params,
	}

	body, err := json.Marshal(request)
	if err != nil {
		return nil, err
	}

	response, err := rpc.client.Post(rpc.url, "application/json", bytes.NewBuffer(body))

	if response != nil {
		defer response.Body.Close()
	}
	if err != nil {
		return nil, err
	}

	data, err := ioutil.ReadAll(response.Body)
	if err != nil {
		return nil, err
	}

	if rpc.Debug {
		rpc.log.Println(fmt.Sprintf("%s\nRequest: %s\nResponse: %s\n", method, body, data))
	}

	resp := new(ethResponse)
	if err := json.Unmarshal(data, resp); err != nil {
		return nil, err
	}

	if resp.Error != nil {
		return nil, *resp.Error
	}

	return resp.Result, nil

}

这里发起关键的是

response, err := rpc.client.Post(rpc.url, "application/json", bytes.NewBuffer(body))

rpc.client对象是一个Http.Client对象,调用了Post方法。Post方法声明在ethrpc/options.go中:

type httpClient interface {
	Post(url string, contentType string, body io.Reader) (*http.Response, error)
}

要给Http.Client对象在发送Post之前添加BasicAthulization字段。所以需要修改Post方法。

4 修改

ethrpc/ethrpc.go中,添加方法:

func (rpc *EthRPC) Post(url string, contentType string, body io.Reader) (resp *http.Response, err error) {
	req, err := http.NewRequest("POST", url, body)
	if err != nil {
		return nil, err
	}
	req.Header.Add("Content-Type", contentType)
	req.SetBasicAuth(user_str,password_str)//设置Http Basic Auth的用户名和密码
	return rpc.client.Do(req)
}

ethrpc/options.go中修改:

type httpClient interface {
	Post(url string, contentType string, body io.Reader) (*http.Response, error)
	Do(req *http.Request)(*http.Response, error)
}

ethrpc/ethrpc.go中修改call方法:

// Call returns raw response of method call
func (rpc *EthRPC) Call(method string, params ...interface{}) (json.RawMessage, error) {
	request := ethRequest{
		ID:      1,
		JSONRPC: "2.0",
		Method:  method,
		Params:  params,
	}

	body, err := json.Marshal(request)
	if err != nil {
		return nil, err
	}

	//response, err := rpc.client.Post(rpc.url, "application/json", bytes.NewBuffer(body))
	response,err:=rpc.Post(rpc.url, "application/json", bytes.NewBuffer(body))

	if response != nil {
		defer response.Body.Close()
	}
	if err != nil {
		return nil, err
	}

	data, err := ioutil.ReadAll(response.Body)
	if err != nil {
		return nil, err
	}

	if rpc.Debug {
		rpc.log.Println(fmt.Sprintf("%s\nRequest: %s\nResponse: %s\n", method, body, data))
	}

	resp := new(ethResponse)
	if err := json.Unmarshal(data, resp); err != nil {
		return nil, err
	}

	if resp.Error != nil {
		return nil, *resp.Error
	}

	return resp.Result, nil

}