Go SDK:批量处理交易
Go SDK 内置了并发发送多笔交易并为其排序的方式。 当需要从同一账户快速执行多笔交易时,这会是一个方便的工具。
如下面的示例所示,可以使用 client.BuildSignAndSubmitTransactions 完成此操作。
完整 Go 示例
Section titled “完整 Go 示例”// sending_concurrent_transactions shows how to submit transactions serially or concurrently on a single accountpackage main
import ( "github.com/aptos-labs/aptos-go-sdk" "github.com/aptos-labs/aptos-go-sdk/api" "time")
func setup(networkConfig aptos.NetworkConfig) (*aptos.Client, aptos.TransactionSigner) { client, err := aptos.NewClient(networkConfig) if err != nil { panic("Failed to create client:" + err.Error()) }
sender, err := aptos.NewEd25519Account() if err != nil { panic("Failed to create sender:" + err.Error()) }
err = client.Fund(sender.Address, 100_000_000) if err != nil { panic("Failed to fund sender:" + err.Error()) }
return client, sender}
func payload() aptos.TransactionPayload { receiver := aptos.AccountAddress{} err := receiver.ParseStringRelaxed("0xBEEF") if err != nil { panic("Failed to parse address:" + err.Error()) } amount := uint64(100) p, err := aptos.CoinTransferPayload(nil, receiver, amount) if err != nil { panic("Failed to serialize arguments:" + err.Error()) } return aptos.TransactionPayload{Payload: p}}
func sendManyTransactionsSerially(networkConfig aptos.NetworkConfig, numTransactions uint64) { client, sender := setup(networkConfig)
responses := make([]*api.SubmitTransactionResponse, numTransactions) payload := payload()
senderAddress := sender.AccountAddress() sequenceNumber := uint64(0) for i := uint64(0); i < numTransactions; i++ { rawTxn, err := client.BuildTransaction(senderAddress, payload, aptos.SequenceNumber(sequenceNumber)) if err != nil { panic("Failed to build transaction:" + err.Error()) }
signedTxn, err := rawTxn.SignedTransaction(sender) if err != nil { panic("Failed to sign transaction:" + err.Error()) }
submitResult, err := client.SubmitTransaction(signedTxn) if err != nil { panic("Failed to submit transaction:" + err.Error()) } responses[i] = submitResult sequenceNumber++ }
// Wait on last transaction response, err := client.WaitForTransaction(responses[numTransactions-1].Hash) if err != nil { panic("Failed to wait for transaction:" + err.Error()) } if response.Success == false { panic("Transaction failed due to " + response.VmStatus) }}
func sendManyTransactionsConcurrently(networkConfig aptos.NetworkConfig, numTransactions uint64) { client, sender := setup(networkConfig) payload := payload()
// start submission goroutine payloads := make(chan aptos.TransactionBuildPayload, 50) results := make(chan aptos.TransactionSubmissionResponse, 50) go client.BuildSignAndSubmitTransactions(sender, payloads, results)
// Submit transactions to goroutine go func() { for i := uint64(0); i < numTransactions; i++ { payloads <- aptos.TransactionBuildPayload{ Id: i, Type: aptos.TransactionSubmissionTypeSingle, Inner: payload, } } close(payloads) }()
// Wait for all transactions to be processed for result := range results { if result.Err != nil { panic("Failed to submit and wait for transaction:" + result.Err.Error()) } }}
// example This example shows you how to improve performance of the transaction submission//// Speed can be improved by locally handling the sequence number, gas price, and other factorsfunc example(networkConfig aptos.NetworkConfig, numTransactions uint64) { println("Sending", numTransactions, "transactions Serially") startSerial := time.Now() sendManyTransactionsSerially(networkConfig, numTransactions) endSerial := time.Now() println("Serial:", time.Duration.Milliseconds(endSerial.Sub(startSerial)), "ms")
println("Sending", numTransactions, "transactions Concurrently") startConcurrent := time.Now() sendManyTransactionsConcurrently(networkConfig, numTransactions) endConcurrent := time.Now() println("Concurrent:", time.Duration.Milliseconds(endConcurrent.Sub(startConcurrent)), "ms")
println("Concurrent is", time.Duration.Milliseconds(endSerial.Sub(startSerial)-endConcurrent.Sub(startConcurrent)), "ms faster than Serial")}
func main() { example(aptos.DevnetConfig, 100)}