SDK de Go - Transacciones Patrocinadas
Normalmente, la cuenta que ejecuta una transacción paga las comisiones de gas. Puedes permitir que otra cuenta cubra esos cargos patrocinando una transacción.
Esto puede usarse para ayudar a gestionar comisiones desde una cuenta central al trabajar con contratos inteligentes complicados.
Cómo Patrocinar una Transacción
Sección titulada «Cómo Patrocinar una Transacción»-
Construir la transacción con el parámetro FeePayer().
rawTxn, err := client.BuildTransactionMultiAgent(alice.Address,aptos.TransactionPayload{Payload: transferPayload,},aptos.FeePayer(&sponsor.Address),) -
Firmar la transacción con AMBOS, el remitente y el feePayer.
- Firmar con la cuenta remitente usando
rawTxn.Sign()
. - Firmar con la cuenta patrocinadora usando
rawTxn.Sign()
.
aliceAuth, err := rawTxn.Sign(alice)if err != nil {panic("Failed to sign transaction as sender:" + err.Error())}sponsorAuth, err := rawTxn.Sign(sponsor)if err != nil {panic("Failed to sign transaction as sponsor:" + err.Error())} - Firmar con la cuenta remitente usando
-
Enviar la transacción combinando ambas firmas.
signedFeePayerTxn, ok = rawTxn.ToFeePayerSignedTransaction(aliceAuth,sponsorAuth,[]crypto.AccountAuthenticator{},)if !ok {panic("Failed to build fee payer signed transaction")}// Enviar y esperar a que se completesubmitResult, err = client.SubmitTransaction(signedFeePayerTxn)if err != nil {panic("Failed to submit transaction:" + err.Error())} -
Esperar a que la transacción se ejecute.
// Esperar la transacción_, err = client.WaitForTransaction(txnHash)
Ejemplo de Código de Transacción Patrocinada en Go
Sección titulada «Ejemplo de Código de Transacción Patrocinada en Go»// sponsored_transaction es un ejemplo de cómo hacer una transacción patrocinada en Aptos.package main
import ( "fmt"
"github.com/aptos-labs/aptos-go-sdk" "github.com/aptos-labs/aptos-go-sdk/crypto")
const FundAmount = 100_000_000const TransferAmount = 1_000
// example This example shows you how to make an APT transfer transaction in the simplest possible wayfunc example(networkConfig aptos.NetworkConfig) { // Create a client for Aptos client, err := aptos.NewClient(networkConfig) if err != nil { panic("Failed to create client:" + err.Error()) }
// Create accounts locally for alice and bob alice, err := aptos.NewEd25519Account() if err != nil { panic("Failed to create alice:" + err.Error()) } bob, err := aptos.NewEd25519Account() if err != nil { panic("Failed to create bob:" + err.Error()) } sponsor, err := aptos.NewEd25519Account() if err != nil { panic("Failed to create sponsor:" + err.Error()) }
fmt.Printf("\n=== Addresses ===\n") fmt.Printf("Alice: %s\n", alice.Address.String()) fmt.Printf("Bob:%s\n", bob.Address.String()) fmt.Printf("Sponsor:%s\n", sponsor.Address.String())
// Fund the alice with the faucet to create it on-chain err = client.Fund(alice.Address, FundAmount) if err != nil { panic("Failed to fund alice:" + err.Error()) }
// And the sponsor err = client.Fund(sponsor.Address, FundAmount) if err != nil { panic("Failed to fund sponsor:" + err.Error()) }
aliceBalance, err := client.AccountAPTBalance(alice.Address) if err != nil { panic("Failed to retrieve alice balance:" + err.Error()) } bobBalance, err := client.AccountAPTBalance(bob.Address) if err != nil { panic("Failed to retrieve bob balance:" + err.Error()) } sponsorBalance, err := client.AccountAPTBalance(sponsor.Address) if err != nil { panic("Failed to retrieve sponsor balance:" + err.Error()) } fmt.Printf("\n=== Initial Balances ===\n") fmt.Printf("Alice: %d\n", aliceBalance) fmt.Printf("Bob: %d\n", bobBalance) fmt.Printf("Sponsor: %d\n", sponsorBalance)
// Build transaction transferPayload, err := aptos.CoinTransferPayload(&aptos.AptosCoinTypeTag, bob.Address, TransferAmount) if err != nil { panic("Failed to build transfer payload:" + err.Error()) } rawTxn, err := client.BuildTransactionMultiAgent( alice.Address, aptos.TransactionPayload{ Payload: transferPayload, }, aptos.FeePayer(&sponsor.Address),
) if err != nil { panic("Failed to build transaction:" + err.Error()) }
// Sign transaction aliceAuth, err := rawTxn.Sign(alice) if err != nil { panic("Failed to sign transaction as sender:" + err.Error()) } sponsorAuth, err := rawTxn.Sign(sponsor) if err != nil { panic("Failed to sign transaction as sponsor:" + err.Error()) }
signedFeePayerTxn, ok := rawTxn.ToFeePayerSignedTransaction( aliceAuth, sponsorAuth, []crypto.AccountAuthenticator{}, ) if !ok { panic("Failed to build fee payer signed transaction") }
// Submit and wait for it to complete submitResult, err := client.SubmitTransaction(signedFeePayerTxn) if err != nil { panic("Failed to submit transaction:" + err.Error()) } txnHash := submitResult.Hash println("Submitted transaction hash:", txnHash)
// Wait for the transaction _, err = client.WaitForTransaction(txnHash) if err != nil { panic("Failed to wait for transaction:" + err.Error()) } aliceBalance, err = client.AccountAPTBalance(alice.Address) if err != nil { panic("Failed to retrieve alice balance:" + err.Error()) } bobBalance, err = client.AccountAPTBalance(bob.Address) if err != nil { panic("Failed to retrieve bob balance:" + err.Error()) } sponsorBalance, err = client.AccountAPTBalance(sponsor.Address) if err != nil { panic("Failed to retrieve sponsor balance:" + err.Error()) } fmt.Printf("\n=== Intermediate Balances ===\n") fmt.Printf("Alice: %d\n", aliceBalance) fmt.Printf("Bob: %d\n", bobBalance) fmt.Printf("Sponsor: %d\n", sponsorBalance)
fmt.Printf("\n=== Now do it without knowing the signer ahead of time ===\n")
rawTxn, err = client.BuildTransactionMultiAgent( alice.Address, aptos.TransactionPayload{ Payload: transferPayload, }, aptos.FeePayer(&aptos.AccountZero), // Note that the Address is 0x0, because we don't know the signer ) if err != nil { panic("Failed to build transaction:" + err.Error()) }
// Alice signs the transaction, without knowing the sponsor aliceAuth, err = rawTxn.Sign(alice) if err != nil { panic("Failed to sign transaction as sender:" + err.Error()) }
// The sponsor has to add themselves to the transaction to sign, note that this would likely be on a different // server ok = rawTxn.SetFeePayer(sponsor.Address) if !ok { panic("Failed to set fee payer") }
sponsorAuth, err = rawTxn.Sign(sponsor) if err != nil { panic("Failed to sign transaction as sponsor:" + err.Error()) }
signedFeePayerTxn, ok = rawTxn.ToFeePayerSignedTransaction( aliceAuth, sponsorAuth, []crypto.AccountAuthenticator{}, ) if !ok { panic("Failed to build fee payer signed transaction") }
// Submit and wait for it to complete submitResult, err = client.SubmitTransaction(signedFeePayerTxn) if err != nil { panic("Failed to submit transaction:" + err.Error()) } txnHash = submitResult.Hash println("Submitted transaction hash:", txnHash)
// Wait for the transaction _, err = client.WaitForTransaction(txnHash) if err != nil { panic("Failed to wait for transaction:" + err.Error()) } aliceBalance, err = client.AccountAPTBalance(alice.Address) if err != nil { panic("Failed to retrieve alice balance:" + err.Error()) } bobBalance, err = client.AccountAPTBalance(bob.Address) if err != nil { panic("Failed to retrieve bob balance:" + err.Error()) } sponsorBalance, err = client.AccountAPTBalance(sponsor.Address) if err != nil { panic("Failed to retrieve sponsor balance:" + err.Error()) } fmt.Printf("\n=== Final Balances ===\n") fmt.Printf("Alice: %d\n", aliceBalance) fmt.Printf("Bob: %d\n", bobBalance) fmt.Printf("Sponsor: %d\n", sponsorBalance)}
func main() { example(aptos.DevnetConfig)}