アカウント制限でスパム攻撃を防ぐ

アカウント制限の追加・削除の方法を学ぶ

Use case

あなたの会社は自社製品の品質を証明するためにパブリックチェーンを使用していると想像してください。

品質検証プロセスが終了すると、オペレータは製品アカウントに 品質シール を送信します。顧客はQRコードをスキャンすることでそれを確認できます。顧客が便利に利用するために、製品アカウントに 関連するトランザクションだけを表示 して、スパムで煩雑になるのを防ぐ必要があります。

最終的な顧客はQRコードを読み取って、製品モザイクを検証します。そのため、会社としては関連するトランザクションだけをを見せたく、それ以外のスパムなどの製品に関係ない情報を避けたいのです。

../../_images/account-restrictions-spam1.png

スパム攻撃のブロック

したがって、あなたは一連の条件に従うトランザクションのみを受信するように、製品に アカウント制限 を設定することにしました。

前提条件

方法 #01: SDK を使用する

アドレスによるトランザクションのブロック

アカウントは許可リストの アドレス からのみトランザクションを受信できるようにすることができます。同様にアカウントはトランザクションをブロックしたいアドレスのブロックリストを指定することもできます。

注釈

許可とブロック制限は制限タイプごとに相互に排他的です。つまり、アカウントは制限の種類ごとに許可リストまたはブロックリストのいずれかを持つようにしか構成できません。

デフォルトでは、制限セットがない場合、ネットワーク内のすべてのアカウントが指定されたアカウントにトランザクションをアナウンスできます。

前の例に戻り、会社アカウントからの受信トランザクションのみを受け入れるように製品アカウントを構成するとします。これを行うには次の手順を実行します。

  1. Define the company’s address TCWYXK-VYBMO4-NBCUF3-AXKJMX-CGVSYQ-OS7ZG2-TLI in a new variable.
// replace with company address
const companyRawAddress = 'TCWYXK-VYBMO4-NBCUF3-AXKJMX-CGVSYQ-OS7ZG2-TLI';
const companyAddress = Address.createFromRawAddress(companyRawAddress);
// replace with company address
const companyRawAddress = 'TCWYXK-VYBMO4-NBCUF3-AXKJMX-CGVSYQ-OS7ZG2-TLI';
const companyAddress = symbol_sdk_1.Address.createFromRawAddress(companyRawAddress);

2. Create an AccountRestrictionTransaction, with restrictionType AllowAddress. Add to the company’s address from the previous step to the allowed list.

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

const transaction = AccountRestrictionTransaction
    .createAddressRestrictionModificationTransaction(
        Deadline.create(),
        AddressRestrictionFlag.AllowIncomingAddress,
        [companyAddress],
        [],
        networkType,
        UInt64.fromUint(2000000));
// replace with network type
const networkType = symbol_sdk_1.NetworkType.TEST_NET;
const transaction = symbol_sdk_1.AccountRestrictionTransaction
    .createAddressRestrictionModificationTransaction(symbol_sdk_1.Deadline.create(), symbol_sdk_1.AddressRestrictionFlag.AllowIncomingAddress, [companyAddress], [], networkType, symbol_sdk_1.UInt64.fromUint(2000000));
  1. 製品のアカウントでトランザクションへ署名してアナウンスをします。
// 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 = 'http://api-01.us-east-1.096x.symboldev.network:3000';
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 = symbol_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 = 'http://api-01.us-east-1.096x.symboldev.network:3000';
const repositoryFactory = new symbol_sdk_1.RepositoryFactoryHttp(nodeUrl);
const transactionHttp = repositoryFactory.createTransactionRepository();
transactionHttp
    .announce(signedTransaction)
    .subscribe((x) => console.log(x), (err) => console.error(err));

Now, if you send a TransferTransaction from another account, you will get an error since only TCWYXK-VYBMO4-NBCUF3-AXKJMX-CGVSYQ-OS7ZG2-TLI is allowed to send transactions to the product’s account.

MosaicID によるトランザクションのブロック

会社を表すアカウントが次のモザイクを所有しているとします:

  • company.share: 会社の株式を表現
  • company.quality.seal: 製品の品質テストの合格を表現
  • company.safety.seal: 製品の安全テストの合格を表現

この場合、製品はシールを受け取ることができるだけで、会社の株は受け取ることができないようにすることに役立ちます。

したがって、否定を使用することで、製品が会社のアカウントから受け取ることができるトランザクションの種類を絞り込むことができます。シールを明確に許可する代わりに company.share が含まれる受信トランザクションをブロックするように製品を設定できます。このようにします:

1. Define the AccountRestrictionModification. Add the mosaic id you want to block to the blocked list.

// replace with mosaic id
const companyShareMosaicIdHex = '7cdf3b117a3c40cc';
const companyShareMosaicId = new MosaicId(companyShareMosaicIdHex);
// replace with mosaic id
const companyShareMosaicIdHex = '7cdf3b117a3c40cc';
const companyShareMosaicId = new symbol_sdk_1.MosaicId(companyShareMosaicIdHex);

2. Create an AccountRestrictionTransaction, with restrictionType BlockMosaic. Add to the array the modification created in the previous step.

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

const transaction = AccountRestrictionTransaction
    .createMosaicRestrictionModificationTransaction(
        Deadline.create(),
        MosaicRestrictionFlag.BlockMosaic,
        [companyShareMosaicId],
        [],
        networkType,
        UInt64.fromUint(2000000));
// replace with network type
const networkType = symbol_sdk_1.NetworkType.TEST_NET;
const transaction = symbol_sdk_1.AccountRestrictionTransaction
    .createMosaicRestrictionModificationTransaction(symbol_sdk_1.Deadline.create(), symbol_sdk_1.MosaicRestrictionFlag.BlockMosaic, [companyShareMosaicId], [], networkType, symbol_sdk_1.UInt64.fromUint(2000000));
  1. 製品のアカウントでトランザクションへ署名してアナウンスをします。
// 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 = 'http://api-01.us-east-1.096x.symboldev.network:3000';
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 = symbol_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 = 'http://api-01.us-east-1.096x.symboldev.network:3000';
const repositoryFactory = new symbol_sdk_1.RepositoryFactoryHttp(nodeUrl);
const transactionHttp = repositoryFactory.createTransactionRepository();
transactionHttp
    .announce(signedTransaction)
    .subscribe((x) => console.log(x), (err) => console.error(err));

プロセスが成功すると、製品アカウントは company.share モザイクが含まれない会社アカウントからのトランザクションだけを受け取ることができます。

制限の除去

会社が最終顧客に商品を販売した後は、彼らは会社アカウントが商品にトランザクションを送信することのみを許可していたという条件を取り除きたいのです。アカウント制限は設定するのと同じくらい簡単に削除できます。

1. Define the AccountRestrictionModification. Remove from the allowed list the company’s address.

const companyRawAddress = 'TCWYXK-VYBMO4-NBCUF3-AXKJMX-CGVSYQ-OS7ZG2-TLI';
const companyAddress = Address.createFromRawAddress(companyRawAddress);
const companyRawAddress = 'TCWYXK-VYBMO4-NBCUF3-AXKJMX-CGVSYQ-OS7ZG2-TLI';
const companyAddress = symbol_sdk_1.Address.createFromRawAddress(companyRawAddress);
  1. AllowAddress タイプ を設定して AccountRestrictionTransaction を作成します。作成した変更も追加します。
// replace with network type
const networkType = NetworkType.TEST_NET;

const transaction = AccountRestrictionTransaction
    .createAddressRestrictionModificationTransaction(
        Deadline.create(),
        AddressRestrictionFlag.AllowIncomingAddress,
        [],
        [companyAddress],
        networkType,
        UInt64.fromUint(2000000));
// replace with network type
const networkType = symbol_sdk_1.NetworkType.TEST_NET;
const transaction = symbol_sdk_1.AccountRestrictionTransaction
    .createAddressRestrictionModificationTransaction(symbol_sdk_1.Deadline.create(), symbol_sdk_1.AddressRestrictionFlag.AllowIncomingAddress, [], [companyAddress], networkType, symbol_sdk_1.UInt64.fromUint(2000000));
  1. 製品のアカウントでトランザクションへ署名してアナウンスをします。
// 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 = 'http://api-01.us-east-1.096x.symboldev.network:3000';
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 = symbol_sdk_1.Account.createFromPrivateKey(productPrivateKey, networkType);
const signedTransaction = productAccount.sign(transaction, networkGenerationHash);
// replace with node endpoint
const nodeUrl = 'http://api-01.us-east-1.096x.symboldev.network:3000';
const repositoryFactory = new symbol_sdk_1.RepositoryFactoryHttp(nodeUrl);
const transactionHttp = repositoryFactory.createTransactionRepository();
transactionHttp
    .announce(signedTransaction)
    .subscribe((x) => console.log(x), (err) => console.error(err));

トランザクションが承認された後に、あなたは再び任意のアカウントから製品アカウントにトランザクションを送ることができるはずです。