Send PrivateTransaction
Last updated
Last updated
This API is used to receive private transactions submitted by users, with the method name eth_sendPrivateTransaction
eth_sendPrivateTransaction
only implements auth restrictions for advanced features (such as gRPC). If you need to use advanced features, please first set in the request.
transaction
Mandatory
String
"0x…4b"
signed raw transaction hash
{
"jsonrpc": "2.0",
"id": "1",
"method": "eth_sendPrivateTransaction",
"params": ["0x…4b"] // signed raw transaction hash
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 // non-TLS connection is defaulted. It is recommended to enable TLS configuration in production
}
func main() {
blzrelayEndPoint := "endpoint_url"
auth := Authentication{
Token: "your_token",
}
conn, err := grpc.Dial(
blzrelayEndPoint,
grpc.WithInsecure(), // non-TLS connection
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()},
})
//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
}
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;
}
message SendTransactionArgs {
bytes tx = 1;
}
message SendBundleResponse {
string result = 1;
}
message SendTransactionResponse {
string result = 1;
}
{
"jsonrpc":"2.0",
"id":"1",
"result":"0xa06b……f7e8ec" // tx hash
}
{
"jsonrpc":"2.0",
"id":"1",
"error":{
"code":-32000,
"message":"nonce too low: next nonce 57, tx nonce 56"
}
}