Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
R
rpcproxy
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
vicotor
rpcproxy
Commits
c802d497
Commit
c802d497
authored
Sep 15, 2025
by
vicotor
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
add cors support
parent
d34c2e55
Changes
1
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
46 additions
and
15 deletions
+46
-15
main.go
main.go
+46
-15
No files found.
main.go
View file @
c802d497
...
...
@@ -35,9 +35,9 @@ func (t *TbAccountInfo) TableName() string {
return
"tb_account_info"
}
// RPC
请求结构体
//
这里只处理eth_getBalance的params
//
其他方法直接转发
// RPC
request structure
//
Only handle params for eth_getBalance here
//
Forward other methods directly
type
RPCRequest
struct
{
Jsonrpc
string
`json:"jsonrpc"`
...
...
@@ -55,36 +55,45 @@ type RPCResponse struct {
var
(
db
*
sql
.
DB
rpcBackend
=
os
.
Getenv
(
"ETH_RPC_BACKEND"
)
//
真实以太坊RPC地址,建议用环境变量配置
rpcBackend
=
os
.
Getenv
(
"ETH_RPC_BACKEND"
)
//
Real Ethereum RPC address, recommend using environment variable
)
func
main
()
{
//
初始化数据库连接
//
Initialize database connection
var
err
error
dsn
:=
os
.
Getenv
(
"MYSQL_DSN"
)
//
例如
"user:password@tcp(127.0.0.1:3306)/dbname"
dsn
:=
os
.
Getenv
(
"MYSQL_DSN"
)
//
Example:
"user:password@tcp(127.0.0.1:3306)/dbname"
db
,
err
=
sql
.
Open
(
"mysql"
,
dsn
)
if
err
!=
nil
{
log
.
Fatalf
(
"
数据库连接失败
: %v"
,
err
)
log
.
Fatalf
(
"
Database connection failed
: %v"
,
err
)
}
defer
db
.
Close
()
http
.
HandleFunc
(
"/"
,
proxyHandler
)
log
.
Println
(
"RPC
代理服务启动,监听端口
: 8545"
)
log
.
Println
(
"RPC
proxy service started, listening on port
: 8545"
)
log
.
Fatal
(
http
.
ListenAndServe
(
":8545"
,
nil
))
}
func
proxyHandler
(
w
http
.
ResponseWriter
,
r
*
http
.
Request
)
{
// Add CORS support
setCORSHeaders
(
w
,
r
)
// Handle preflight requests
if
r
.
Method
==
"OPTIONS"
{
w
.
WriteHeader
(
http
.
StatusOK
)
return
}
body
,
err
:=
ioutil
.
ReadAll
(
r
.
Body
)
if
err
!=
nil
{
http
.
Error
(
w
,
"
读取请求失败
"
,
http
.
StatusBadRequest
)
http
.
Error
(
w
,
"
Failed to read request
"
,
http
.
StatusBadRequest
)
return
}
defer
r
.
Body
.
Close
()
var
reqs
[]
RPCRequest
//
先尝试解析为批量请求
//
Try to parse as batch request first
if
err
:=
json
.
Unmarshal
(
body
,
&
reqs
);
err
==
nil
{
//
处理批量请求
//
Handle batch request
if
len
(
reqs
)
>
1
{
req
:=
reqs
[
0
]
resp
:=
RPCResponse
{
...
...
@@ -128,10 +137,24 @@ func proxyHandler(w http.ResponseWriter, r *http.Request) {
return
}
}
//
其他情况直接转发
//
Forward other cases directly
forwardToBackend
(
w
,
body
)
}
func
setCORSHeaders
(
w
http
.
ResponseWriter
,
r
*
http
.
Request
)
{
origin
:=
r
.
Header
.
Get
(
"Origin"
)
if
origin
!=
""
{
w
.
Header
()
.
Set
(
"Access-Control-Allow-Origin"
,
origin
)
}
else
{
w
.
Header
()
.
Set
(
"Access-Control-Allow-Origin"
,
"*"
)
}
w
.
Header
()
.
Set
(
"Access-Control-Allow-Methods"
,
"POST, GET, OPTIONS, PUT, DELETE"
)
w
.
Header
()
.
Set
(
"Access-Control-Allow-Headers"
,
"Accept, Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token, Authorization, X-Real-IP, X-Forwarded-For"
)
w
.
Header
()
.
Set
(
"Access-Control-Allow-Credentials"
,
"true"
)
w
.
Header
()
.
Set
(
"Access-Control-Max-Age"
,
"86400"
)
}
func
accountExists
(
address
string
)
bool
{
var
count
int
query
:=
"SELECT COUNT(1) FROM tb_account_info WHERE account_address = ? AND is_deleted = 0"
...
...
@@ -140,7 +163,7 @@ func accountExists(address string) bool {
if
err
==
sql
.
ErrNoRows
{
return
false
}
else
{
log
.
Printf
(
"
数据库查询错误
: %v"
,
err
)
log
.
Printf
(
"
Database query error
: %v"
,
err
)
}
return
true
}
...
...
@@ -150,10 +173,18 @@ func accountExists(address string) bool {
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
)
http
.
Error
(
w
,
"
Backend RPC request failed
"
,
http
.
StatusBadGateway
)
return
}
defer
resp
.
Body
.
Close
()
w
.
Header
()
.
Set
(
"Content-Type"
,
"application/json"
)
// Copy response headers, including possible CORS headers
for
key
,
values
:=
range
resp
.
Header
{
for
_
,
value
:=
range
values
{
w
.
Header
()
.
Add
(
key
,
value
)
}
}
w
.
WriteHeader
(
resp
.
StatusCode
)
io
.
Copy
(
w
,
resp
.
Body
)
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment