Commit b8e2a174 authored by vicotor's avatar vicotor

add code

parents
Pipeline #895 canceled with stages
.idea
.vscode
FROM golang:1.24-alpine AS build
# Set up dependencies
#ENV PACKAGES build-base
# Install dependencies
#RUN apk add --update $PACKAGES
# Add source files
WORKDIR /build
COPY ./ /build/rpcproxy
RUN cd /build/rpcproxy && go mod tidy && go build -ldflags="-s -w" -o /tmp/rpcproxy ./
FROM alpine
WORKDIR /app
COPY --from=build /tmp/rpcproxy /usr/bin/rpcproxy
EXPOSE 8545
\ No newline at end of file
.PHONY: default all clean
GOBIN = $(shell pwd)
BUILD_FLAGS = -ldflags "-s -w"
default: all
all: rpcproxy
rpcproxy:
go build $(BUILD_FLAGS) -v -o=${GOBIN}/$@ ./
docker:
docker build --no-cache -t rpcproxy:latest -f ./Dockerfile .
.PHONY: docker
start:
docker compose up -d
.PHONY: start
stop:
docker compose down
.PHONY: stop
networks:
default:
name: rpcproxy
services:
rpcproxy:
image: rpcproxy:latest
environment:
- ETH_RPC_BACKEND=http://172.17.0.1:26658
- MYSQL_DSN=""
command:
- "/bin/sh"
- "-c"
- "/usr/bin/rpcproxy"
restart:
unless-stopped
\ No newline at end of file
module code.wuban.net.cn/luxueqian/rpcproxy
go 1.24.4
require github.com/go-sql-driver/mysql v1.9.3
require filippo.io/edwards25519 v1.1.0 // indirect
filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA=
filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4=
github.com/go-sql-driver/mysql v1.9.3 h1:U/N249h2WzJ3Ukj8SowVFjdtZKfu9vlLZxjPXV1aweo=
github.com/go-sql-driver/mysql v1.9.3/go.mod h1:qn46aNg1333BRMNU69Lq93t8du/dwxI64Gl8i5p1WMU=
package main
import (
"bytes"
"database/sql"
"encoding/json"
"io"
"io/ioutil"
"log"
"net/http"
"os"
"strings"
"time"
_ "github.com/go-sql-driver/mysql"
)
type TbAccountInfo struct {
Id int64 `json:"id"`
BlockId int64 `json:"block_id"`
BlockHash string `json:"block_hash"`
TxHash string `json:"tx_hash"`
AccountAddress string `json:"account_address"`
AccountType int `json:"account_type"`
MyNameTag string `json:"my_name_tag"`
Balance float64 `json:"balance"`
Status int `json:"status"`
IsDeleted int8 `json:"is_deleted"`
SyncTime time.Time `json:"sync_time"`
CreateTime time.Time `json:"create_time"`
UpdateTime time.Time `json:"update_time"`
}
func (t *TbAccountInfo) TableName() string {
return "tb_account_info"
}
// RPC请求结构体
// 这里只处理eth_getBalance的params
// 其他方法直接转发
type RPCRequest struct {
Jsonrpc string `json:"jsonrpc"`
Method string `json:"method"`
Params []interface{} `json:"params"`
Id interface{} `json:"id"`
}
type RPCResponse struct {
Jsonrpc string `json:"jsonrpc"`
Id interface{} `json:"id"`
Result interface{} `json:"result"`
Error interface{} `json:"error,omitempty"`
}
var (
db *sql.DB
rpcBackend = os.Getenv("ETH_RPC_BACKEND") // 真实以太坊RPC地址,建议用环境变量配置
)
func main() {
// 初始化数据库连接
var err error
dsn := os.Getenv("MYSQL_DSN") // 例如 "user:password@tcp(127.0.0.1:3306)/dbname"
db, err = sql.Open("mysql", dsn)
if err != nil {
log.Fatalf("数据库连接失败: %v", err)
}
defer db.Close()
http.HandleFunc("/", proxyHandler)
log.Println("RPC代理服务启动,监听端口: 8545")
log.Fatal(http.ListenAndServe(":8545", nil))
}
func proxyHandler(w http.ResponseWriter, r *http.Request) {
body, err := ioutil.ReadAll(r.Body)
if err != nil {
http.Error(w, "读取请求失败", http.StatusBadRequest)
return
}
defer r.Body.Close()
var req RPCRequest
if err := json.Unmarshal(body, &req); err != nil {
forwardToBackend(w, body)
return
}
if req.Method == "eth_getBalance" && len(req.Params) > 0 {
address, ok := req.Params[0].(string)
if !ok {
forwardToBackend(w, body)
return
}
if !accountExists(strings.ToLower(address)) {
resp := RPCResponse{
Jsonrpc: req.Jsonrpc,
Id: req.Id,
Result: "0x0",
}
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(resp)
return
}
}
// 其他情况直接转发
forwardToBackend(w, body)
}
func accountExists(address string) bool {
var count int
query := "SELECT COUNT(1) FROM tb_account_info WHERE account_address = ? AND is_deleted = 0"
err := db.QueryRow(query, address).Scan(&count)
if err != nil {
if err == sql.ErrNoRows {
return false
}
return true
}
return count > 0
}
func forwardToBackend(w http.ResponseWriter, body []byte) {
resp, err := http.Post(rpcBackend, "application/json", bytes.NewReader(body))
if err != nil {
http.Error(w, "后端RPC请求失败", http.StatusBadGateway)
return
}
defer resp.Body.Close()
w.Header().Set("Content-Type", "application/json")
io.Copy(w, resp.Body)
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment