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
}