Envío de múltiples transacciones juntas

Envía transacciones a diferentes cuentas al mismo tiempo utilizando transacciones de agregación.

Casos de uso

Dan quiere enviar tokens a Alice y Bob. Podría lograr esto enviando un par de TransferTransactions. Sin embargo, para asegurarse de que Alice y Bob reciban los fondos al mismo tiempo, decide usar una transacción de agregación.

../../_images/aggregate-sending-payouts.png

Envío de transacciones a diferentes destinatarios de manera atómica

Requisitos previos

Método #01: Usando el SDK

  1. Abre un archivo nuevo y define dos TransferTransaction para enviar 10 unidades de bitxor a diferentes destinatarios.

// replace with network type
const networkType = NetworkType.TEST_NET;
// replace with sender private key
const privateKey =
  'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA';
const account = Account.createFromPrivateKey(privateKey, networkType);
// replace with address
const aliceAddress = 'BXRBDE-NCLKEB-ILBPWP-3JPB2X-NY64OE-7PYHHE-32I';
const aliceAccount = Address.createFromRawAddress(aliceAddress);
// replace with address
const bobAddress = 'BXRQ5E-YACWBP-CXKGIL-I6XWCH-DRFLTB-KUK34I-YJQ';
const bobAccount = Address.createFromRawAddress(bobAddress);
// replace with bitxor id
const networkCurrencyTokenId = new TokenId('5E62990DCAC5BE8A');
// replace with network currency divisibility
const networkCurrencyDivisibility = 6;

const token = new Token(
  networkCurrencyTokenId,
  UInt64.fromUint(10 * Math.pow(10, networkCurrencyDivisibility)),
);

const aliceTransferTransaction = TransferTransaction.create(
  Deadline.create(123456789),
  aliceAccount,
  [token],
  PlainMessage.create('payout'),
  networkType,
);
const bobTransferTransaction = TransferTransaction.create(
  Deadline.create(123456789),
  bobAccount,
  [token],
  PlainMessage.create('payout'),
  networkType,
);
// replace with network type
const networkType = bitxor_sdk_1.NetworkType.TEST_NET;
// replace with sender private key
const privateKey =
    'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA';
const account = bitxor_sdk_1.Account.createFromPrivateKey(
    privateKey,
    networkType,
);
// replace with address
const aliceAddress = 'BXRBDE-NCLKEB-ILBPWP-3JPB2X-NY64OE-7PYHHE-32I';
const aliceAccount = bitxor_sdk_1.Address.createFromRawAddress(aliceAddress);
// replace with address
const bobAddress = 'BXRQ5E-YACWBP-CXKGIL-I6XWCH-DRFLTB-KUK34I-YJQ';
const bobAccount = bitxor_sdk_1.Address.createFromRawAddress(bobAddress);
// replace with bitxor id
const networkCurrencyTokenId = new bitxor_sdk_1.TokenId('5E62990DCAC5BE8A');
// replace with network currency divisibility
const networkCurrencyDivisibility = 6;
const token = new bitxor_sdk_1.Token(
    networkCurrencyTokenId,
    bitxor_sdk_1.UInt64.fromUint(10 * Math.pow(10, networkCurrencyDivisibility)),
);
const aliceTransferTransaction = bitxor_sdk_1.TransferTransaction.create(
    bitxor_sdk_1.Deadline.create(123456789),
    aliceAccount, [token],
    bitxor_sdk_1.PlainMessage.create('payout'),
    networkType,
);
const bobTransferTransaction = bitxor_sdk_1.TransferTransaction.create(
    bitxor_sdk_1.Deadline.create(123456789),
    bobAccount, [token],
    bitxor_sdk_1.PlainMessage.create('payout'),
    networkType,
);
            NetworkType networkType = repositoryFactory.getNetworkType().toFuture().get();

            // replace with sender private key
            String privateKey = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA";
            Account account = Account.createFromPrivateKey(privateKey, networkType);
            // replace with address
            String aliceAddress = "BXRBDE-NCLKEB-ILBPWP-3JPB2X-NY64OE-7PYHHE-32I";
            Address aliceAccount = Address.createFromRawAddress(aliceAddress);
            // replace with address
            String bobAddress = "BXRQ5E-YACWBP-CXKGIL-I6XWCH-DRFLTB-KUK34I-YJQ";
            Address bobAccount = Address.createFromRawAddress(bobAddress);

            NetworkCurrency networkCurrency = repositoryFactory.getNetworkCurrency().toFuture().get();

            Token token = networkCurrency.createRelative(BigDecimal.valueOf(10));

            TransferTransaction aliceTransferTransaction = TransferTransactionFactory
                .create(networkType, aliceAccount, Collections.singletonList(token), PlainMessage.create("payout"))
                .build();

            TransferTransaction bobTransferTransaction = TransferTransactionFactory
                .create(networkType, bobAccount, Collections.singletonList(token), PlainMessage.create("payout"))
                .build();
  1. Envuelva ambas transacciones en una transacción agregada, agregando la cuenta pública de Dan como el firmante requerido. Como una clave privada, la cuenta de Dan, puede firmar todas las transacciones en conjunto, podemos definir la transacción como completa.

const aggregateTransaction = AggregateTransaction.createComplete(
  Deadline.create(123456789),
  [
    aliceTransferTransaction.toAggregate(account.publicAccount),
    bobTransferTransaction.toAggregate(account.publicAccount),
  ],
  networkType,
  [],
  UInt64.fromUint(2000000),
);
const aggregateTransaction = bitxor_sdk_1.AggregateTransaction.createComplete(
    bitxor_sdk_1.Deadline.create(123456789), [
        aliceTransferTransaction.toAggregate(account.publicAccount),
        bobTransferTransaction.toAggregate(account.publicAccount),
    ],
    networkType, [],
    bitxor_sdk_1.UInt64.fromUint(2000000),
);
            AggregateTransaction aggregateTransaction = AggregateTransactionFactory.createComplete(networkType, Arrays
                .asList(aliceTransferTransaction.toAggregate(account.getPublicAccount()),
                    bobTransferTransaction.toAggregate(account.getPublicAccount()))).maxFee(BigInteger.valueOf(2000000))
                .build();
  1. Firme y anuncie la transacción con la cuenta de Dan.

// replace with meta.networkGenerationHash (nodeUrl + '/node/info')
const networkGenerationHash =
  '1DFB2FAA9E7F054168B0C5FCB84F4DEB62CC2B4D317D861F3168D161F54EA78B';
const signedTransaction = account.sign(
  aggregateTransaction,
  networkGenerationHash,
);
// replace with node endpoint
const nodeUrl = 'NODE_URL';
const repositoryFactory = new RepositoryFactoryHttp(nodeUrl);
const transactionHttp = repositoryFactory.createTransactionRepository();

transactionHttp.announce(signedTransaction).subscribe(
  (x) => console.log(x),
  (err) => console.error(err),
);
// replace with meta.networkGenerationHash (nodeUrl + '/node/info')
const networkGenerationHash =
    '1DFB2FAA9E7F054168B0C5FCB84F4DEB62CC2B4D317D861F3168D161F54EA78B';
const signedTransaction = account.sign(
    aggregateTransaction,
    networkGenerationHash,
);
// replace with node endpoint
const nodeUrl = 'NODE_URL';
const repositoryFactory = new bitxor_sdk_1.RepositoryFactoryHttp(nodeUrl);
const transactionHttp = repositoryFactory.createTransactionRepository();
transactionHttp.announce(signedTransaction).subscribe(
    (x) => console.log(x),
    (err) => console.error(err),
);
            String generationHash = repositoryFactory.getGenerationHash().toFuture().get();
            SignedTransaction signedTransaction = account.sign(aggregateTransaction, generationHash);

            try (Listener listener = repositoryFactory.createListener()) {
                listener.open().get();
                TransactionService transactionService = new TransactionServiceImpl(repositoryFactory);
                transactionService.announce(listener, signedTransaction).toFuture().get();

            }