github.com/piotrnar/gocoin@v0.0.0-20240512203912-faa0448c5e96/client/rpcapi/rpcapi.go (about)

     1  package rpcapi
     2  
     3  // test it with:
     4  // curl --user someuser:somepass --data-binary '{"method":"Arith.Add","params":[{"A":7,"B":1}],"id":0}' -H 'content-type: text/plain;' http://127.0.0.1:8222/
     5  
     6  import (
     7  	"bytes"
     8  	"encoding/json"
     9  	"fmt"
    10  	"io/ioutil"
    11  	"net/http"
    12  	"os/exec"
    13  	"github.com/piotrnar/gocoin/client/common"
    14  )
    15  
    16  type RpcError struct {
    17  	Code    int    `json:"code"`
    18  	Message string `json:"message"`
    19  }
    20  
    21  type RpcResponse struct {
    22  	Id     interface{} `json:"id"`
    23  	Result interface{} `json:"result"`
    24  	Error  interface{} `json:"error"`
    25  }
    26  
    27  type RpcCommand struct {
    28  	Id     interface{} `json:"id"`
    29  	Method string      `json:"method"`
    30  	Params interface{} `json:"params"`
    31  }
    32  
    33  func process_rpc(b []byte) (out []byte) {
    34  	ioutil.WriteFile("rpc_cmd.json", b, 0777)
    35  	ex_cmd := exec.Command("C:\\Tools\\DEV\\Git\\mingw64\\bin\\curl.EXE",
    36  		"--user", "gocoinrpc:gocoinpwd", "--data-binary", "@rpc_cmd.json", "http://127.0.0.1:18332/")
    37  	out, _ = ex_cmd.Output()
    38  	return
    39  }
    40  
    41  func my_handler(w http.ResponseWriter, r *http.Request) {
    42  	u, p, ok := r.BasicAuth()
    43  	if !ok {
    44  		println("No HTTP Authentication data")
    45  		return
    46  	}
    47  	if u != common.CFG.RPC.Username {
    48  		println("HTTP Authentication: bad username")
    49  		return
    50  	}
    51  	if p != common.CFG.RPC.Password {
    52  		println("HTTP Authentication: bad password")
    53  		return
    54  	}
    55  	//fmt.Println("========================handler", r.Method, r.URL.String(), u, p, ok, "=================")
    56  	b, e := ioutil.ReadAll(r.Body)
    57  	if e != nil {
    58  		println(e.Error())
    59  		return
    60  	}
    61  
    62  	var RpcCmd RpcCommand
    63  	jd := json.NewDecoder(bytes.NewReader(b))
    64  	jd.UseNumber()
    65  	e = jd.Decode(&RpcCmd)
    66  	if e != nil {
    67  		println(e.Error())
    68  	}
    69  
    70  	var resp RpcResponse
    71  	resp.Id = RpcCmd.Id
    72  	switch RpcCmd.Method {
    73  		case "getblocktemplate":
    74  			var resp_my RpcGetBlockTemplateResp
    75  
    76  			GetNextBlockTemplate(&resp_my.Result)
    77  
    78  			if false {
    79  				var resp_ok RpcGetBlockTemplateResp
    80  				bitcoind_result := process_rpc(b)
    81  				//ioutil.WriteFile("getblocktemplate_resp.json", bitcoind_result, 0777)
    82  
    83  				//fmt.Print("getblocktemplate...", sto.Sub(sta).String(), string(b))
    84  
    85  				jd = json.NewDecoder(bytes.NewReader(bitcoind_result))
    86  				jd.UseNumber()
    87  				e = jd.Decode(&resp_ok)
    88  
    89  				if resp_my.Result.PreviousBlockHash != resp_ok.Result.PreviousBlockHash {
    90  					println("satoshi @", resp_ok.Result.PreviousBlockHash, resp_ok.Result.Height)
    91  					println("gocoin  @", resp_my.Result.PreviousBlockHash, resp_my.Result.Height)
    92  				} else {
    93  					println(".", len(resp_my.Result.Transactions), resp_my.Result.Coinbasevalue)
    94  					if resp_my.Result.Mintime != resp_ok.Result.Mintime {
    95  						println("\007Mintime:", resp_my.Result.Mintime, resp_ok.Result.Mintime)
    96  					}
    97  					if resp_my.Result.Bits != resp_ok.Result.Bits {
    98  						println("\007Bits:", resp_my.Result.Bits, resp_ok.Result.Bits)
    99  					}
   100  					if resp_my.Result.Target != resp_ok.Result.Target {
   101  						println("\007Target:", resp_my.Result.Target, resp_ok.Result.Target)
   102  					}
   103  				}
   104  			}
   105  
   106  			b, _ = json.Marshal(&resp_my)
   107  			//ioutil.WriteFile("json/"+RpcCmd.Method+"_resp_my.json", b, 0777)
   108  			w.Write(append(b, 0x0a))
   109  			return
   110  
   111  
   112  		case "validateaddress":
   113  			switch uu := RpcCmd.Params.(type) {
   114  			case []interface{}:
   115  				if len(uu) == 1 {
   116  					resp.Result = ValidateAddress(uu[0].(string))
   117  				}
   118  			default:
   119  				println("unexpected type", uu)
   120  			}
   121  
   122  		case "submitblock":
   123  			//ioutil.WriteFile("submitblock.json", b, 0777)
   124  			SubmitBlock(&RpcCmd, &resp, b)
   125  
   126  		default:
   127  			fmt.Println("Method:", RpcCmd.Method, len(b))
   128  			//w.Write(bitcoind_result)
   129  			resp.Error = RpcError{Code: -32601, Message: "Method not found"}
   130  	}
   131  
   132  	b, e = json.Marshal(&resp)
   133  	if e != nil {
   134  		println("json.Marshal(&resp):", e.Error())
   135  	}
   136  
   137  	//ioutil.WriteFile(RpcCmd.Method+"_resp.json", b, 0777)
   138  	w.Write(append(b, 0x0a))
   139  }
   140  
   141  func StartServer(port uint32) {
   142  	fmt.Println("Starting RPC server at port", port)
   143  	mux := http.NewServeMux()
   144  	mux.HandleFunc("/", my_handler)
   145  	http.ListenAndServe(fmt.Sprint("127.0.0.1:",port), mux)
   146  }