マルチシグアカウントに新しい署名者の追加

このガイドでは、マルチシグアカウントに新しい署名者を追加する方法を説明します。

ユースケース

Alice と Bob は 2-of-2 マルチシグアカウントの連署者として Carol を追加 したいと仮定します。しかし、彼らはトランザクションを受け入れるために必要な署名数を増やしたくないので、新しいアカウントはトランザクションに ** 2-of-3** の署名を必要とするようにします。

../../_images/multisig-2-of-31.png

2-of-3 マルチシグアカウントの例

前提条件

方法 #01: デスクトップウォレットを使用する

  1. マルチシグアカウントの連署者アカウントにログインします。これは Alice または Bob のアカウントである可能性があります。
  2. 左側のメニューの 「マルチシグ」 をクリックします。
  3. 上部のフィールドのドロップダウンメニューから変更するマルチシグウォレットを選択します。これにより 「Operation Type」 が 「Modifying account multisig properties」 に変換されます。
  4. 署名者の追加」 をクリックして、マルチシグに新しい署名者として追加するアカウントのアドレスまたは公開鍵を入力します。 「送信」 をクリックします。ポップアップの情報を確認します。ウォレットパスワードを入力して 「確認」 をクリックします。
../../_images/add-signer-1.gif
  1. マルチシグアカウントの 「最小承認数」 が 1 より大きい数に設定されている場合は、別の連署者アカウントにログインし トランザクションに署名します 。最小承認数が満たされるまで、この手順を繰り返します。
../../_images/add-signer-21.gif
  1. 「マルチシグ」 ページに移動すると、新しい署名者が追加されたことを確認できます。新しい署名者は 「署名者」 の下に表示されます。
../../_images/add-signer-3.png

方法 #02: SDK を使用する

  1. 新しいファイルを開きます。マルチシグアカウントの公開鍵と追加する新しいアカウントを変数へ格納して定義します。
// replace with network type
const networkType = NetworkType.TEST_NET;
// replace with multisig public key
const multisigAccountPublicKey =
  '3A537D5A1AF51158C42F80A199BB58351DBF3253C4A6A1B7BD1014682FB595EA';
const multisigAccount = PublicAccount.createFromPublicKey(
  multisigAccountPublicKey,
  networkType,
);
// replace with new cosignatory public key
const newCosignatoryPublicKey =
  '17E42BDF5B7FF5001DC96A262A1141FFBE3F09A3A45DE7C095AAEA14F45C0DA0';
const newCosignatoryAccount = PublicAccount.createFromPublicKey(
  newCosignatoryPublicKey,
  networkType,
);
// replace with network type
const networkType = symbol_sdk_1.NetworkType.TEST_NET;
// replace with multisig public key
const multisigAccountPublicKey =
  '3A537D5A1AF51158C42F80A199BB58351DBF3253C4A6A1B7BD1014682FB595EA';
const multisigAccount = symbol_sdk_1.PublicAccount.createFromPublicKey(
  multisigAccountPublicKey,
  networkType,
);
// replace with new cosignatory public key
const newCosignatoryPublicKey =
  '17E42BDF5B7FF5001DC96A262A1141FFBE3F09A3A45DE7C095AAEA14F45C0DA0';
const newCosignatoryAccount = symbol_sdk_1.PublicAccount.createFromPublicKey(
  newCosignatoryPublicKey,
  networkType,
);
  1. MultisigAccountModificationTransaction を作り、連署者として新しい参加者を追加します。

注釈

前の例に続いて、新しい署名者を追加しているが minApprovalDelta を増加させていないため、マルチシグアカウントは 2-of-3 になります。

const multisigAccountModificationTransaction = MultisigAccountModificationTransaction.create(
  Deadline.create(epochAdjustment),
  0,
  0,
  [newCosignatoryAccount.address],
  [],
  networkType,
);
const multisigAccountModificationTransaction = symbol_sdk_1.MultisigAccountModificationTransaction.create(
  symbol_sdk_1.Deadline.create(epochAdjustment),
  0,
  0,
  [newCosignatoryAccount.address],
  [],
  networkType,
);
  1. MultisigAccountModificationTransactionAggregateBondedTransaction へラップします。それに、元のマルチシグアカウントの連署者で署名します。
const aggregateTransaction = AggregateTransaction.createBonded(
  Deadline.create(epochAdjustment),
  [multisigAccountModificationTransaction.toAggregate(multisigAccount)],
  networkType,
  [],
  UInt64.fromUint(2000000),
);

// replace with cosignatory private key
const cosignatoryPrivateKey =
  '1111111111111111111111111111111111111111111111111111111111111111';
const cosignatoryAccount = Account.createFromPrivateKey(
  cosignatoryPrivateKey,
  networkType,
);
// replace with meta.networkGenerationHash (nodeUrl + '/node/info')
const networkGenerationHash =
  '1DFB2FAA9E7F054168B0C5FCB84F4DEB62CC2B4D317D861F3168D161F54EA78B';
const signedTransaction = cosignatoryAccount.sign(
  aggregateTransaction,
  networkGenerationHash,
);
console.log(signedTransaction.hash);
const aggregateTransaction = symbol_sdk_1.AggregateTransaction.createBonded(
  symbol_sdk_1.Deadline.create(epochAdjustment),
  [multisigAccountModificationTransaction.toAggregate(multisigAccount)],
  networkType,
  [],
  symbol_sdk_1.UInt64.fromUint(2000000),
);
// replace with cosignatory private key
const cosignatoryPrivateKey =
  '1111111111111111111111111111111111111111111111111111111111111111';
const cosignatoryAccount = symbol_sdk_1.Account.createFromPrivateKey(
  cosignatoryPrivateKey,
  networkType,
);
// replace with meta.networkGenerationHash (nodeUrl + '/node/info')
const networkGenerationHash =
  '1DFB2FAA9E7F054168B0C5FCB84F4DEB62CC2B4D317D861F3168D161F54EA78B';
const signedTransaction = cosignatoryAccount.sign(
  aggregateTransaction,
  networkGenerationHash,
);
console.log(signedTransaction.hash);

4. Before sending an AggregateBondedTransaction, an account must lock at least 10 symbol.xym. This transaction is required to prevent spamming the network. After the HashLockTransaction has been confirmed, announce the AggregateTransaction.

// replace with symbol.xym id
const networkCurrencyMosaicId = new MosaicId('5E62990DCAC5BE8A');
// replace with network currency divisibility
const networkCurrencyDivisibility = 6;

const hashLockTransaction = HashLockTransaction.create(
  Deadline.create(epochAdjustment),
  new Mosaic(
    networkCurrencyMosaicId,
    UInt64.fromUint(10 * Math.pow(10, networkCurrencyDivisibility)),
  ),
  UInt64.fromUint(480),
  signedTransaction,
  networkType,
  UInt64.fromUint(2000000),
);

const signedHashLockTransaction = cosignatoryAccount.sign(
  hashLockTransaction,
  networkGenerationHash,
);

// replace with node endpoint
const nodeUrl = 'http://api-01.us-east-1.testnet.symboldev.network:3000';
const repositoryFactory = new RepositoryFactoryHttp(nodeUrl);
const listener = repositoryFactory.createListener();
const receiptHttp = repositoryFactory.createReceiptRepository();
const transactionHttp = repositoryFactory.createTransactionRepository();
const transactionService = new TransactionService(transactionHttp, receiptHttp);

listener.open().then(() => {
  transactionService
    .announceHashLockAggregateBonded(
      signedHashLockTransaction,
      signedTransaction,
      listener,
    )
    .subscribe(
      (x) => console.log(x),
      (err) => console.log(err),
      () => listener.close(),
    );
});
// replace with symbol.xym id
const networkCurrencyMosaicId = new symbol_sdk_1.MosaicId('5E62990DCAC5BE8A');
// replace with network currency divisibility
const networkCurrencyDivisibility = 6;
const hashLockTransaction = symbol_sdk_1.HashLockTransaction.create(
  symbol_sdk_1.Deadline.create(epochAdjustment),
  new symbol_sdk_1.Mosaic(
    networkCurrencyMosaicId,
    symbol_sdk_1.UInt64.fromUint(
      10 * Math.pow(10, networkCurrencyDivisibility),
    ),
  ),
  symbol_sdk_1.UInt64.fromUint(480),
  signedTransaction,
  networkType,
  symbol_sdk_1.UInt64.fromUint(2000000),
);
const signedHashLockTransaction = cosignatoryAccount.sign(
  hashLockTransaction,
  networkGenerationHash,
);
// replace with node endpoint
const nodeUrl = 'http://api-01.us-east-1.testnet.symboldev.network:3000';
const repositoryFactory = new symbol_sdk_1.RepositoryFactoryHttp(nodeUrl);
const listener = repositoryFactory.createListener();
const receiptHttp = repositoryFactory.createReceiptRepository();
const transactionHttp = repositoryFactory.createTransactionRepository();
const transactionService = new symbol_sdk_1.TransactionService(
  transactionHttp,
  receiptHttp,
);
listener.open().then(() => {
  transactionService
    .announceHashLockAggregateBonded(
      signedHashLockTransaction,
      signedTransaction,
      listener,
    )
    .subscribe(
      (x) => console.log(x),
      (err) => console.log(err),
      () => listener.close(),
    );
});

5. The new account must opt-in first in order to become a cosignatory of the multisig account. Cosign the AggregateTransaction hash with the account to be added to the multisig.

symbol-cli transaction cosign --hash A6A374E66B32A3D5133018EFA9CD6E3169C8EEA339F7CCBE29C47D07086E068C --profile carol

6. Cosign the AggregateTransaction with all other multisig account participants required to reach quorum. The amount of symbol.xym locked becomes available again on the account that sent the HashLockTransaction, and the new participant is added to the multisig.

symbol-cli transaction cosign --hash A6A374E66B32A3D5133018EFA9CD6E3169C8EEA339F7CCBE29C47D07086E068C --profile bob

次のガイド に従って、マルチシグアカウントから署名者を削除します。