Transacciones de aumento de tarifas
Las transacciones de aumento de tarifas se introdujeron en CAP-0015 y permiten que una cuenta pague las tarifas de transacción de una transacción existente sin tener que volver a firmar la transacción o gestionar los números de secuencia.
Una transacción de aumento de tarifas se compone de dos partes:
- Un sobre de transacción interno con su(s) firma(s)
- Un sobre de transacción externo con la transacción de aumento de tarifas y la firma de la cuenta de tarifas
Casos de uso comunes
Podrías considerar usar aumentos de tarifas cuando:
- Estás construyendo un servicio donde deseas cubrir las tarifas de los usuarios
- Deseas aumentar la tarifa en una transacción existente para que tenga una mejor oportunidad de llegar al ledger durante el aumento de precios
- Necesitas ajustar la tarifa en una transacción preautorizada para que pueda llegar al ledger si las tarifas mínimas de la red han aumentado
Atributos
Sobre de transacción existente (transacción interna)
Antes de crear una transacción de aumento de tarifas, primero debes tener una transacción envuelta con sus firmas en un sobre de transacción. Llamaremos a esta transacción la transacción interna. Llamaremos a esta transacción la transacción interna.
Cuenta de tarifa
La cuenta que pagará la tarifa por la transacción de aumento de tarifas. Esta cuenta incurrirá en la tarifa en lugar de la cuenta fuente especificada en la transacción interna. Sin embargo, el número de secuencia aún se toma de la cuenta fuente.
Tarifa
La tarifa máxima por operación que estás dispuesto a pagar por la transacción de aumento de tarifas. La transacción de aumento de tarifas es una operación. Por lo tanto, el número total de operaciones es igual al número de operaciones en la transacción interna más uno.
Lee más sobre las tarifas de transacción en nuestra sección de tarifas.
Reemplazar por tarifa
Puedes aplicar una transacción de aumento de tarifas para aumentar una tarifa que proviene de tu propia cuenta. Sin embargo, si envías dos transacciones distintas con la misma cuenta fuente y número de secuencia, siendo la segunda transacción una transacción de aumento de tarifas, la segunda transacción reemplazará la primera transacción en la cola si y solo si la oferta de tarifa de la segunda transacción es 10 veces la oferta de tarifa de la primera transacción. Este número puede parecer aleatorio, es una decisión de diseño deliberada para limitar los ataques DOS sin introducir demasiada complejidad en el protocolo.
Sobre de transacción de aumento de tarifas
Cuando una transacción de aumento de tarifas esté lista para ser firmada, se envuelve en un sobre de transacción. Este sobre contiene la transacción de aumento de tarifas y la firma de la cuenta de tarifas especificada.
Validez de una transacción de aumento de tarifas
Una transacción de aumento de tarifas pasa por una serie de verificaciones en su ciclo de vida para determinar su validez. Las siguientes condiciones deben cumplirse:
- Cuenta de tarifas — la cuenta de tarifas para la transacción de aumento de tarifas debe existir en el ledger.
- Tarifa
- La tarifa debe ser mayor o igual a la tarifa mínima de la red para el número de operaciones en la transacción interna, más uno por el aumento de tarifas.
- La tarifa también debe ser mayor o igual a la tarifa especificada en la transacción interna.
- Si la transacción de aumento de tarifas está aprovechando el reemplazo por tarifa, la tarifa debe ser 10 veces más alta que la primera transacción.
- Firma de cuenta de tarifas — el sobre de transacción de aumento de tarifas debe contener una firma válida para la cuenta de tarifas. Además, el peso de esa firma debe cumplir con el umbral bajo para la cuenta de tarifas, y el pasphrase de red apropiado debe ser parte del hash de transacción firmado por la cuenta de tarifas.
- Saldo de cuenta de tarifas — la cuenta de tarifas debe tener un saldo suficiente de XLM para cubrir la tarifa
- Transacción interna — la transacción interna debe ser válida, lo que significa que debe cumplir con los requisitos descritos en la Sección de validez de una transacción. Si la validación de la transacción interna es exitosa, el resultado es
FEE_BUMP_INNER_SUCCESS
, y los resultados de la validación de la transacción interna aparecen en el resultado interno. Si la transacción interna es inválida, el resultado esFEE_BUMP_INNER_FAILED
, y la transacción de aumento de tarifas es inválida porque la transacción interna es inválida. Si la validación de la transacción interna es exitosa, entonces el resultado esFEE_BUMP_INNER_SUCCESS
, y los resultados de la validación de la transacción interna aparecen en el resultado interno. Si la transacción interna es inválida, el resultado esFEE_BUMP_INNER_FAILED
, y la transacción de aumento de tarifa es inválida porque la transacción interna es inválida.
Aplicación
El único propósito de una transacción de aumento de tarifas es incluir una transacción interna en un conjunto de transacciones. Dado que la transacción de aumento de tarifas no tiene efectos secundarios además de pagar una tarifa — y en el momento en que se paga la tarifa, la transacción externa debe haber sido válida (de lo contrario, los nodos no habrían votado por ella) — no hay razón para verificar la validez de la transacción de aumento de tarifas en el momento de aplicar. Por lo tanto, el número de secuencia de la transacción interna siempre se consume en el momento de aplicar. Sin embargo, la transacción interna todavía tendrá su validez verificada en el momento de aplicar.
Cada resultado de transacción de aumento de tarifas contiene un resultado completo de transacción interna. Este resultado de la transacción interna es exactamente lo que se hubiera producido si no hubiera habido una transacción de aumento de tarifas, excepto que la tarifa interna siempre será 0.
Ejemplo: implementación de una transacción de aumento de tarifas
Este ejemplo muestra cómo crear y enviar una transacción de aumento de tarifas en la red Stellar. Reemplaza los valores de clave secreta, SECREY_KEY_1
y SECREY_KEY_2
de keypairs de tu elección. Este no es un ejemplo de producción, y debes tener cuidado de nunca exponer tus claves secretas en la web.
- JavaScript
import * as StellarSDK from "@stellar/stellar-sdk";
// Define the network passphrase (use 'Testnet' for testing and 'Public Global Stellar Network ; September 2015' for production)
const networkPassphrase = StellarSDK.Networks.TESTNET;
// Create keypairs for the source account and the fee account
const sourceKeypair = StellarSDK.Keypair.fromSecret("SECREY_KEY_1");
const feeKeypair = StellarSDK.Keypair.fromSecret("SECREY_KEY_2");
// Load the source account (this requires network interaction)
const server = new StellarSDK.Horizon.Server(
"https://horizon-testnet.stellar.org",
);
const sourceAccount = await server.loadAccount(sourceKeypair.publicKey());
// Construct the inner transaction, just a example tx, to transfer 10 XLM to a destination account
const innerTransaction = new StellarSDK.TransactionBuilder(sourceAccount, {
fee: StellarSDK.BASE_FEE,
networkPassphrase,
})
.addOperation(
StellarSDK.Operation.payment({
destination: "GDWH3P3MNTCMOY42CA7RVEACUUAUPZ73XDYKPYUL3TWOFRF37FD6OVM6",
asset: StellarSDK.Asset.native(),
amount: "10",
}),
)
.setTimeout(30)
.build();
// Sign the inner transaction with the source account
innerTransaction.sign(sourceKeypair);
// Build the fee-bump transaction
const feeBumpTransaction =
StellarSDK.TransactionBuilder.buildFeeBumpTransaction(
feeKeypair,
StellarSDK.BASE_FEE * 2,
innerTransaction,
networkPassphrase,
);
// Sign the fee-bump transaction with the fee account
feeBumpTransaction.sign(feeKeypair);
// Submit the fee-bump transaction to the Stellar network
server
.submitTransaction(feeBumpTransaction)
.then((response) => {
console.log("Success! Results:", response);
})
.catch((error) => {
console.error("Something went wrong!", error);
});