createTransactionSC method

Future<({KeyPair previousKeyPair, Transaction transaction})> createTransactionSC({
  1. required Keychain keychain,
  2. required ApiService apiService,
  3. required List<String> membersPubKey,
  4. required String discussionName,
  5. required List<String> adminsPubKey,
  6. required String adminAddress,
  7. required String serviceName,
  8. int indexSCTransaction = 0,
})

Implementation

Future<({Transaction transaction, KeyPair previousKeyPair})>
    createTransactionSC({
  required Keychain keychain,
  required ApiService apiService,
  required List<String> membersPubKey,
  required String discussionName,
  required List<String> adminsPubKey,
  required String adminAddress,
  required String serviceName,
  int indexSCTransaction = 0,
}) async {
  /// AESKey (32-byte (256-bit) random key) manages message access (encryption/decryption)
  final discussionKeyAccess = generateRandomAESKey();

  /// AESKey (32-byte (256-bit) random key) manages SC secrets
  final aesKey = generateRandomAESKey();

  final membersAuthorizedKeys = _addMembersInAuthorized(
    aesKey: aesKey,
    membersPubKey: membersPubKey,
  );

  /// Seed of the Smart Contract
  final storageNoncePublicKey = await apiService.getStorageNoncePublicKey();
  final seedSC = generateRandomSeed();

  final scAuthorizedKeys = List<AuthorizedKey>.empty(growable: true);
  scAuthorizedKeys.add(
    AuthorizedKey(
      publicKey: storageNoncePublicKey,
      encryptedSecretKey:
          uint8ListToHex(ecEncrypt(aesKey, storageNoncePublicKey)),
    ),
  );

  final originPrivateKey = apiService.getOriginKey();

  final blockchainTxVersion = int.parse(
    (await apiService.getBlockchainVersion()).version.transaction,
  );

  /// Create a new transaction typed Smart Contract to manage a discussion
  final transactionSCBuildResult = Transaction(
    type: 'contract',
    data: Transaction.initData(),
    version: blockchainTxVersion,
  )
      .setCode(_generateDiscussionSCCode(membersPubKey: membersPubKey))
      .setContent(
        _generateDiscussionSCContent(
          discussionName: discussionName,
          adminsPubKey: adminsPubKey,
          discussionKeyAccess: discussionKeyAccess,
        ),
      )

      /// Secret 1 : Seed of the SC only accessible by nodes
      .addOwnership(
        uint8ListToHex(
          aesEncrypt(seedSC, aesKey),
        ),
        scAuthorizedKeys,
      )

      /// Secret 2 : DiscussionKeyAccess only accessible by the discussion's members
      .addOwnership(
        uint8ListToHex(
          aesEncrypt(discussionKeyAccess, aesKey),
        ),
        membersAuthorizedKeys,
      )
      .build(seedSC, indexSCTransaction);

  final transactionSC =
      transactionSCBuildResult.transaction.originSign(originPrivateKey);

  // Estimation of fees and send to SC's transaction chain
  final transactionTransferResult = await _provisionSC(
    apiService: apiService,
    issuerAddress: adminAddress,
    keychain: keychain,
    originPrivateKey: originPrivateKey,
    seedSC: seedSC,
    serviceName: serviceName,
    transactionSC: transactionSC,
  );

  await TransactionUtil().sendTransactions(
    [transactionTransferResult.transaction, transactionSC],
    apiService,
  );

  return (
    transaction: transactionSC,
    previousKeyPair: transactionSCBuildResult.keyPair,
  );
}