Send PrivateTransaction
接口說明
本接口用於接收用戶提交的隱私交易,方法名為eth_sendPrivateTransaction
流控說明
eth_sendPrivateTransaction
僅針對高級特性(如gRPC)做auth限制,如需使用高級特性請先在請求中設置Authentication,详见 Authentication
請求參數
参数
必选
格式
示例
描述
transaction
是
String
"0x…4b"
經過簽名的raw transaction
請求示例
{
"jsonrpc": "2.0",
"id": "1",
"method": "eth_sendPrivateTransaction",
"params": ["0x…9c"], // 經過簽名的raw transaction
}
package main
import (
"context"
"crypto/ecdsa"
"fmt"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/crypto"
"github.com/xkwang/go-builder-client/sendbundle"
"google.golang.org/grpc"
"log"
"math/big"
)
type Authentication struct {
Token string
}
func (a *Authentication) GetRequestMetadata(ctx context.Context, uri ...string) (map[string]string, error) {
return map[string]string{
"authorization": a.Token,
}, nil
}
func (a *Authentication) RequireTransportSecurity() bool {
return false // 非 TLS 鏈接設置為 false,生產環境建議用 true + TLS
}
func main() {
blzrelayEndPoint := "endpoint_url"
auth := Authentication{
Token: "your_token",
}
conn, err := grpc.Dial(
blzrelayEndPoint,
grpc.WithInsecure(), // 沒有TLS使用
grpc.WithPerRPCCredentials(&auth),
)
if err != nil {
panic(err)
}
defer conn.Close()
chainId := int64(56)
to := common.HexToAddress("toAddress")
pk, _ := crypto.HexToECDSA("private key")
_, rawTx, err := GenerateAndSignTx(
big.NewInt(0), //value
big.NewInt(21000), //gas limit
big.NewInt(1e9), //gas price
&to, nil, 1, big.NewInt(chainId), pk)
fmt.Printf("rawTx:%x\n", rawTx)
if err != nil {
log.Println("Error creating signed tx:", err)
}
client := sendbundle.NewBundleServiceClient(conn)
r, err := client.SendBundle(context.Background(), &sendbundle.SendBundleArgs{
Txs: [][]byte{
rawTx,
},
//MaxBlockNumber: 1,
//RevertingTxHashes: []string{signedTx.Hash().String()},
//DroppingTxHashes: []string{signedTx.Hash().String()},
//MinTimestamp: convertedTime,
//MaxTimestamp: convertedTime + 100000,
})
//r, err := client.SendTransaction(context.Background(), &sendbundle.SendTransactionArgs{Tx: rawTx})
if err != nil {
fmt.Println(err)
} else {
println("response:", r.Result)
}
}
func GenerateAndSignTx(value, gas, gasPrice *big.Int, to *common.Address, dataBytes []byte, nonce uint64, chainID *big.Int, privateKeyECDSA *ecdsa.PrivateKey) (*types.Transaction, []byte, error) {
tx := types.NewTx(&types.LegacyTx{
Nonce: nonce,
To: to,
Value: value,
Gas: gas.Uint64(),
GasPrice: gasPrice,
Data: dataBytes,
})
signer := types.NewEIP155Signer(chainID)
signedTx, err := types.SignTx(tx, signer, privateKeyECDSA)
if err != nil {
return nil, nil, fmt.Errorf("failed to sign transaction: %v", err)
}
rawTxBytes, err := signedTx.MarshalBinary()
if err != nil {
return nil, nil, fmt.Errorf("failed to marshal signed transaction: %v", err)
}
return signedTx, rawTxBytes, nil
}
Proto
syntax = "proto3";
package sendbundle;
option go_package = "internal/ethapi/sendbundle;sendbundle";
service BundleService {
rpc SendBundle (SendBundleArgs) returns (SendBundleResponse);
rpc SendTransaction (SendTransactionArgs) returns (SendTransactionResponse);
}
message SendBundleArgs {
repeated bytes txs = 1;
uint64 maxBlockNumber = 2;
uint64 minTimestamp = 3;
uint64 maxTimestamp = 4;
repeated string revertingTxHashes = 5;
repeated string droppingTxHashes = 6;
}
message SendTransactionArgs {
bytes tx = 1;
}
message SendBundleResponse {
string result = 1;
}
message SendTransactionResponse {
string result = 1;
}
返回示例
{
"jsonrpc":"2.0",
"id":"1",
"result":"0xa06b……f7e8ec" // 交易哈希
}
{
"jsonrpc":"2.0",
"id":"1",
"error":{
"code":-32000,
"message":"nonce too low: next nonce 57, tx nonce 56"
}
}
Last updated