Prevención de ataques de spam con restricciones de cuenta

Aprende cómo agregar y eliminar restricciones de cuenta.

Caso de uso

Imagina que eres una empresa que utiliza la cadena pública para certificar la calidad de tus productos.

Cuando el proceso de verificación de calidad concluye, un operador envía un sello de calidad a la cuenta del producto, que los clientes pueden revisar escaneando un código QR. Con el fin de brindar comodidad a los clientes, deseas mostrar solo las transacciones relevantes y evitar el spam que pueda saturar la cuenta del producto.

Los clientes finales pueden revisar los tokens del producto escaneando un código QR. Por esa razón, la empresa desea mostrar solo las transacciones relacionadas, evitando que otros envíen spam con información no relacionada.

../../_images/account-restrictions-spam.png

Bloqueo de ataques de spam

Por lo tanto, decides configurar las restricciones de cuenta del producto para que solo reciba transacciones que cumplan con un conjunto de condiciones.

Prerrequisitos

Método #01: Usando el SDK

Bloqueo de transacciones por dirección

Una cuenta puede decidir recibir transacciones solo de una lista permitida de direcciones. De manera similar, una cuenta puede especificar una lista bloqueada de direcciones para bloquear transacciones de ellas.

Note

Las restricciones permitidas y bloqueadas son mutuamente excluyentes por tipo de restricción. En otras palabras, una cuenta solo puede configurarse para tener una lista permitida o bloqueada por tipo de restricción.

De forma predeterminada, cuando no hay restricciones establecidas, todas las cuentas de la red pueden anunciar transacciones a la cuenta indicada.

Volviendo a nuestro ejemplo anterior, supongamos que deseas configurar la cuenta del producto para que solo acepte recibir transacciones provenientes de la cuenta de la empresa. Puedes seguir estos pasos para hacerlo:

  1. Define la dirección de la empresa como BXRYXK-VYBMO4-NBCUF3-AXKJMX-CGVSYQ-OS7ZG2-TLI en una nueva variable.

// replace with company address
const companyRawAddress = 'BXRYXK-VYBMO4-NBCUF3-AXKJMX-CGVSYQ-OS7ZG2-TLI';
const companyAddress = Address.createFromRawAddress(companyRawAddress);
// replace with company address
const companyRawAddress = 'BXRYXK-VYBMO4-NBCUF3-AXKJMX-CGVSYQ-OS7ZG2-TLI';
const companyAddress = bitxor_sdk_1.Address.createFromRawAddress(
    companyRawAddress,
);

2. Crea una AccountRestrictionTransaction, con el tipo de restricción AllowAddress. Agrega la dirección de la empresa al lista permitida.

// replace with network type
const networkType = NetworkType.TEST_NET;

const transaction = AccountRestrictionTransaction.createAddressRestrictionModificationTransaction(
  Deadline.create(epochAdjustment),
  AddressRestrictionFlag.AllowIncomingAddress,
  [companyAddress],
  [],
  networkType,
  UInt64.fromUint(2000000),
);
// replace with network type
const networkType = bitxor_sdk_1.NetworkType.TEST_NET;
const transaction = bitxor_sdk_1.AccountRestrictionTransaction.createAddressRestrictionModificationTransaction(
    bitxor_sdk_1.Deadline.create(epochAdjustment),
    bitxor_sdk_1.AddressRestrictionFlag.AllowIncomingAddress, [companyAddress], [],
    networkType,
    bitxor_sdk_1.UInt64.fromUint(2000000),
);
  1. Firmar y anunciar la transacción con la cuenta del producto.

// replace with product private key
const productPrivateKey =
  'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF';
const productAccount = Account.createFromPrivateKey(
  productPrivateKey,
  networkType,
);
// replace with meta.networkGenerationHash (nodeUrl + '/node/info')
const networkGenerationHash =
  '1DFB2FAA9E7F054168B0C5FCB84F4DEB62CC2B4D317D861F3168D161F54EA78B';
const signedTransaction = productAccount.sign(
  transaction,
  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 product private key
const productPrivateKey =
    'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF';
const productAccount = bitxor_sdk_1.Account.createFromPrivateKey(
    productPrivateKey,
    networkType,
);
// replace with meta.networkGenerationHash (nodeUrl + '/node/info')
const networkGenerationHash =
    '1DFB2FAA9E7F054168B0C5FCB84F4DEB62CC2B4D317D861F3168D161F54EA78B';
const signedTransaction = productAccount.sign(
    transaction,
    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),
);

Ahora, si envías una TransferTransaction desde otra cuenta, recibirás un error ya que solo BXRYXK-VYBMO4-NBCUF3-AXKJMX-CGVSYQ-OS7ZG2-TLI tiene permitido enviar transacciones a la cuenta del producto.

Bloqueo de transacciones por ID de token

Imagina que la cuenta que representa a la empresa posee los siguientes tokens:

  • “company.share�? representa las acciones de la empresa.

  • “company.quality.seal�? representa que el producto ha pasado una prueba de calidad.

  • “company.safety.seal�? representa que el producto ha pasado una prueba de seguridad.

En este caso, podría ser útil si el producto solo pudiera recibir sellos y no acciones de la empresa.

Por lo tanto, puedes limitar el tipo de transacciones que el producto puede recibir de la cuenta de la empresa mediante el uso de la negación. En lugar de permitir específicamente los sellos, el producto puede configurarse para bloquear la recepción de transacciones que contengan “company.share�? Así es cómo se puede hacer:

1. Define la AccountRestrictionModification. Agrega el ID del token que deseas bloquear a la lista de bloqueados.

// replace with token id
const companyShareTokenIdHex = '7cdf3b117a3c40cc';
const companyShareTokenId = new TokenId(companyShareTokenIdHex);
// replace with token id
const companyShareTokenIdHex = '7cdf3b117a3c40cc';
const companyShareTokenId = new bitxor_sdk_1.TokenId(companyShareTokenIdHex);

2. Crea una AccountRestrictionTransaction, con restrictionType “BlockToken�? Agrega la modificación creada en el paso anterior al arreglo.

// replace with network type
const networkType = NetworkType.TEST_NET;

const transaction = AccountRestrictionTransaction.createTokenRestrictionModificationTransaction(
  Deadline.create(epochAdjustment),
  TokenRestrictionFlag.BlockToken,
  [companyShareTokenId],
  [],
  networkType,
  UInt64.fromUint(2000000),
);
// replace with network type
const networkType = bitxor_sdk_1.NetworkType.TEST_NET;
const transaction = bitxor_sdk_1.AccountRestrictionTransaction.createTokenRestrictionModificationTransaction(
  bitxor_sdk_1.Deadline.create(epochAdjustment),
  bitxor_sdk_1.TokenRestrictionFlag.BlockToken,
  [companyShareTokenId],
  [],
  networkType,
  bitxor_sdk_1.UInt64.fromUint(2000000),
);
  1. Firma y anuncia la transacción con la cuenta del producto.

// replace with product private key
const productPrivateKey =
  'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF';
const productAccount = Account.createFromPrivateKey(
  productPrivateKey,
  networkType,
);
// replace with meta.networkGenerationHash (nodeUrl + '/node/info')
const networkGenerationHash =
  '1DFB2FAA9E7F054168B0C5FCB84F4DEB62CC2B4D317D861F3168D161F54EA78B';
const signedTransaction = productAccount.sign(
  transaction,
  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 product private key
const productPrivateKey =
  'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF';
const productAccount = bitxor_sdk_1.Account.createFromPrivateKey(
  productPrivateKey,
  networkType,
);
// replace with meta.networkGenerationHash (nodeUrl + '/node/info')
const networkGenerationHash =
  '1DFB2FAA9E7F054168B0C5FCB84F4DEB62CC2B4D317D861F3168D161F54EA78B';
const signedTransaction = productAccount.sign(
  transaction,
  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),
);

Si el proceso fue exitoso, la cuenta del producto ahora solo puede recibir transacciones de la cuenta de la empresa que no incluyan ningún token “company.share�?

Eliminar una restricción

Después de que la empresa venda el producto al cliente final, desea eliminar la condición que solo permitía que la cuenta de la empresa enviara transacciones al producto. Las restricciones de la cuenta se pueden eliminar tan fácilmente como se configuraron:

1. Define la AccountRestrictionModification. Elimina de la lista permitida la dirección de la empresa.

const companyRawAddress = 'BXRYXK-VYBMO4-NBCUF3-AXKJMX-CGVSYQ-OS7ZG2-TLI';
const companyAddress = Address.createFromRawAddress(companyRawAddress);
const companyRawAddress = 'BXRYXK-VYBMO4-NBCUF3-AXKJMX-CGVSYQ-OS7ZG2-TLI';
const companyAddress = bitxor_sdk_1.Address.createFromRawAddress(
    companyRawAddress,
);
  1. Crea una AccountRestrictionTransaction, estableciendo el tipo “AllowAddress�? Agrega la modificación creada.

// replace with network type
const networkType = NetworkType.TEST_NET;

const transaction = AccountRestrictionTransaction.createAddressRestrictionModificationTransaction(
  Deadline.create(epochAdjustment),
  AddressRestrictionFlag.AllowIncomingAddress,
  [],
  [companyAddress],
  networkType,
  UInt64.fromUint(2000000),
);
// replace with network type
const networkType = bitxor_sdk_1.NetworkType.TEST_NET;
const transaction = bitxor_sdk_1.AccountRestrictionTransaction.createAddressRestrictionModificationTransaction(
    bitxor_sdk_1.Deadline.create(epochAdjustment),
    bitxor_sdk_1.AddressRestrictionFlag.AllowIncomingAddress, [], [companyAddress],
    networkType,
    bitxor_sdk_1.UInt64.fromUint(2000000),
);
  1. Firma y anuncia la transacción con la cuenta del producto.

// replace with product private key
const productPrivateKey =
  'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF';
// replace with meta.networkGenerationHash (nodeUrl + '/node/info')
const networkGenerationHash =
  '1DFB2FAA9E7F054168B0C5FCB84F4DEB62CC2B4D317D861F3168D161F54EA78B';
const productAccount = Account.createFromPrivateKey(
  productPrivateKey,
  networkType,
);
const signedTransaction = productAccount.sign(
  transaction,
  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 product private key
const productPrivateKey =
    'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF';
// replace with meta.networkGenerationHash (nodeUrl + '/node/info')
const networkGenerationHash =
    '1DFB2FAA9E7F054168B0C5FCB84F4DEB62CC2B4D317D861F3168D161F54EA78B';
const productAccount = bitxor_sdk_1.Account.createFromPrivateKey(
    productPrivateKey,
    networkType,
);
const signedTransaction = productAccount.sign(
    transaction,
    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),
);

Después de que la transacción se confirme, deberías poder enviar transacciones desde cualquier cuenta a la cuenta del producto nuevamente.