Fteepromax/sever.go
2025-02-21 00:31:21 +08:00

141 lines
4.8 KiB
Go

package main
import (
"crypto/ecdsa"
"encoding/json"
"fmt"
"log"
"math/big"
"net/http"
"strings"
"github.com/ethereum/go-ethereum/abi"
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/ethclient"
"github.com/ethereum/go-ethereum/rpc"
)
// SimpleStorage 是从 Solidity 合约生成的绑定。
type SimpleStorage struct {
*bind.BoundContract
}
// NewSimpleStorage 创建一个与 SimpleStorage 合约绑定的新实例。
func NewSimpleStorage(address common.Address, backend bind.ContractBackend) (*SimpleStorage, error) {
parsed, err := abi.JSON(strings.NewReader(simpleStorageABI))
if err != nil {
return nil, err
}
contract := bind.NewBoundContract(address, parsed, backend, backend, backend)
return &SimpleStorage{contract}, nil
}
// Set 调用合约的 set 方法。
func (s *SimpleStorage) Set(opts *bind.TransactOpts, key string, value *big.Int) (*types.Transaction, error) {
return s.Transact(opts, "set", key, value)
}
// Get 调用合约的 get 方法。
func (s *SimpleStorage) Get(opts *bind.CallOpts, key string) (*big.Int, error) {
var res []interface{}
err := s.Call(opts, &res, "get", key)
if err != nil {
return nil, err
}
decoded, ok := res[0].(*big.Int)
if !ok {
return nil, fmt.Errorf("failed to decode result")
}
return decoded, nil
}
var simpleStorageABI = `[{"constant":false,"inputs":[{"name":"key","type":"string"},{"name":"value","type":"uint256"}],"name":"set","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"key","type":"string"}],"name":"get","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"}]`
var simpleStorageBytecode = "0x608060405234801561001057600080fd5b5060c08061001f6000396000f3fe60806040526004361061004e576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680632e1a7d4d14610053575b600080fd5b34801561005f57600080fd5b5061006c600480360381019080803590602001909291905050506100a2565b6040518082815260200191505060405180910390f35b60008160008190555056fea26469706673582212209c6b1e4d375b6083c4d98b45a74086c425c7f89f2f0f8e0f40d1b28b1dfb3d4664736f6c634300080a0033"
var contractAddress = common.HexToAddress("0x5FbDB2315678afecb367f032d93F642f64180aa3") // 替换为实际的合约地址
func main() {
// 使用 WebSocket 连接到本地运行的 Geth 实例
rpcClient, err := rpc.Dial("ws://localhost:8546")
if err != nil {
log.Fatalf("Failed to connect to the Ethereum client: %v", err)
}
defer rpcClient.Close()
client := ethclient.NewClient(rpcClient)
// 生成一个新的随机账户
privateKey, err := crypto.GenerateKey()
if err != nil {
log.Fatalf("Failed to generate private key: %v", err)
}
publicKey := privateKey.Public()
// publicKeyECDSA 已删除,因为未使用
fromAddress := crypto.PubkeyToAddress(publicKey.(ecdsa.PublicKey))
// 创建交易选项
auth, err := bind.NewKeyedTransactorWithChainID(privateKey, big.NewInt(1337))
if err != nil {
log.Fatalf("Failed to create transactor: %v", err)
}
auth.Nonce = big.NewInt(0) // 设置初始 nonce
auth.Value = big.NewInt(0) // 没有转账价值
auth.GasLimit = uint64(300000) // 设置 gas limit
auth.GasPrice = big.NewInt(1) // 设置 gas 价格
// 创建合约实例
instance, err := NewSimpleStorage(contractAddress, client)
if err != nil {
log.Fatalf("Failed to instantiate contract: %v", err)
}
http.HandleFunc("/set", func(w http.ResponseWriter, r *http.Request) {
valueStr := r.URL.Query().Get("value")
key := r.URL.Query().Get("key")
if valueStr == "" || key == "" {
http.Error(w, "Missing 'value' or 'key' parameter", http.StatusBadRequest)
return
}
value, ok := new(big.Int).SetString(valueStr, 10)
if !ok {
http.Error(w, "Invalid 'value' parameter", http.StatusBadRequest)
return
}
tx, err := instance.Set(auth, key, value)
if err != nil {
http.Error(w, fmt.Sprintf("Failed to set value: %v", err), http.StatusInternalServerError)
return
}
fmt.Fprintf(w, "Transaction sent: %s\n", tx.Hash().Hex())
})
http.HandleFunc("/get", func(w http.ResponseWriter, r *http.Request) {
key := r.URL.Query().Get("key")
if key == "" {
http.Error(w, "Missing 'key' parameter", http.StatusBadRequest)
return
}
value, err := instance.Get(&bind.CallOpts{}, key)
if err != nil {
http.Error(w, fmt.Sprintf("Failed to get value: %v", err), http.StatusInternalServerError)
return
}
json.NewEncoder(w).Encode(map[string]interface{}{
"key": key,
"value": value,
})
})
log.Println("Starting server on :8081...")
if err := http.ListenAndServe(":8081", nil); err != nil {
log.Fatalf("Failed to start server: %v", err)
}
}