2
1

More than 1 year has passed since last update.

symbol-sdk@3.0.7で作るマルチシグ化のトランザクション

Last updated at Posted at 2023-07-12

はじめに

こんにちは。

symbol-sdkの3系、トランザクションシリーズ第五弾です。

今回はマルチシグをやっていきます。

注意事項

書いてあるコードについて、正確性や完全性を保証するものではありません。あくまで参考程度として頂き、最新情報は公式ドキュメンテーションをご確認ください。

共通

まずは共通となる個所について。デッドラインと鍵ペアです。

import symbolSdk from 'symbol-sdk';

const network = symbolSdk.symbol.Network.TESTNET;
const deadline = network.fromDatetime(new Date(Date.now() + 7200000)).timestamp;

const facade = new symbolSdk.facade.SymbolFacade(network.name);

const privateKey = new symbolSdk.PrivateKey(PRIVATE_KEY);
const keyPair = new facade.constructor.KeyPair(privateKey);

XEMのモザイクIDも書いておきます。

const currencyMosaicId = 0x72C0212E67A08BCEn;

マルチシグアカウントを作成するにあたって、登場人物を3人用意します。

Alice, Bob, Carol です。それぞれ、ランダムな秘密鍵を生成します。

import crypto from 'crypto';

const alicePrivateKey = new symbolSdk.PrivateKey(crypto.randomBytes(32).toString('hex').toUpperCase());
const aliceKeyPair = new facade.constructor.KeyPair(alicePrivateKey);
const aliceAddress = network.publicKeyToAddress(aliceKeyPair.publicKey);

const bobPrivateKey = new symbolSdk.PrivateKey(crypto.randomBytes(32).toString('hex').toUpperCase());
const bobKeyPair = new facade.constructor.KeyPair(bobPrivateKey);
const bobAddress = network.publicKeyToAddress(bobKeyPair.publicKey);

const carolPrivateKey = new symbolSdk.PrivateKey(crypto.randomBytes(32).toString('hex').toUpperCase());
const carolKeyPair = new facade.constructor.KeyPair(carolPrivateKey);
const carolAddress = network.publicKeyToAddress(carolKeyPair.publicKey);

マルチシグ構成

image.png

事前準備

今回は、Alice がトランザクションの送信者(署名者)にする予定です。

そのためにはXEM残高が必要ですが、ランダム生成したアカウントなので残高ゼロです。

そこでXEMを少し送っておきます。

const fundTransaction = facade.transactionFactory.create({
  type: 'transfer_transaction_v1',
  signerPublicKey: keyPair.publicKey.toString(),
  fee: 1000000n,
  deadline,
  recipientAddress: aliceAddress,
  mosaics: [
    { mosaicId: currencyMosaicId, amount: 1000000n },
  ],
});
const fundSignature = facade.signTransaction(keyPair, fundTransaction);
const fundJsonPayload = facade.transactionFactory.constructor.attachSignature(fundTransaction, fundSignature);
const fundHash = facade.hashTransaction(fundTransaction).toString();
const fundSendRes = await axios.put(`${NODE_INFO}/transactions`, fundJsonPayload).then((res) => res.data);

マルチシグ化

今回は、 Alice をマルチシグアカウントとし、Bob と Carol の 2 of 2 マルチシグを組みます。

そのためには、3人全員の署名が必要になります(確か)。

なのでまずは、マルチシグモディフィケーショントランザクションを作成し、

次に、アグリゲートコンプリートトランザクションでラップして全員の署名を付けていきます。

マルチシグモディフィケーショントランザクション

createEmbedded を使うところに注意。

const innerTransaction1 = facade.transactionFactory.createEmbedded({
  type: 'multisig_account_modification_transaction_v1',
  signerPublicKey: aliceKeyPair.publicKey,
  minRemovalDelta: 2,
  minApprovalDelta: 2,
  addressAdditions: [ bobAddress, carolAddress ],
  addressDeletions: [],
});

アグリゲートコンプリートトランザクション

const innerTransactions = [ innerTransaction1 ];
const transactionsHash = symbolSdk.facade.SymbolFacade.hashEmbeddedTransactions(innerTransactions);

const transaction = facade.transactionFactory.create({
  type: 'aggregate_complete_transaction_v2',
  signerPublicKey: aliceKeyPair.publicKey,
  fee: 1000000n,
  deadline,
  transactions: innerTransactions,
  transactionsHash,
});

署名とハッシュ計算

先に Alice の署名を行い、トランザクションハッシュを計算します。ここで、 attachSignature の戻り値は破棄します。

const signature = facade.signTransaction(aliceKeyPair, transaction);
facade.transactionFactory.constructor.attachSignature(transaction, signature);
const hash = facade.hashTransaction(transaction).toString();

Bob と Carol の連署を作成し、トランザクションに取り込みます。

const bobCosignature = facade.cosignTransaction(bobKeyPair, transaction);
const carolCosignature = facade.cosignTransaction(carolKeyPair, transaction);

transaction.cosignatures.push(bobCosignature);
transaction.cosignatures.push(carolCosignature);

ここで、もう一度 attachSignature を行い、トランザクションのペイロードを入手します。

const jsonPayload = facade.transactionFactory.constructor.attachSignature(transaction, signature);

送信

あとは、トランザクションを送信すれば、マルチシグ化が完了します。

const sendRes = await axios.put(`${NODE_URL}/transactions`, jsonPayload).then((res) => res.data);
console.log(sendRes);

おわりに

今回はマルチシグのトランザクションを作りました。

シリーズ

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1