javascriptecdsahedera-hashgraph

Is it possible to update an existing (ECDSA) account on Hedera to use Multisig & Threshold Keys for Signing?


I have an existing ECDSA Hedera account I've created. I would now like to be able to update this account to be a Multisig account (using three other keys) with a threshold of 3/3 (so all keys have to sign).

Our current code (taken from here), where privateKey(n) are derived from ECDSA DER-encoded Private Keys, editAccount represents the account being changed, and editKey is the private key for the editAccount:

// Create a `KeyList` that represents a 3 of 3 multisig threshold
const multisigPublicKeys = [(await privateKey1).publicKey, (await privateKey2).publicKey, (await privateKey3).publicKey];
const multisigKeyList = new KeyList(multisigPublicKeys, 3);

//Log Keys (**Only visual output at this stage**)
console.log('These are your new credentials...');
console.log('Multisig Keylist ' + multisigKeyList.toString());

//Create the transaction to update the key on the account
const transaction = await new AccountUpdateTransaction()
    .setAccountId(editAccount)
    .setKey(multisigKeyList)
    .freezeWith(client);

//Sign the transaction with the old key and new key(s)
const SignedByOriginalTx = await transaction.sign(editKey);
const SignedByFirstTx = await SignedByOriginalTx.sign(privateKey1);
const SignedBySecondTx = await SignedByFirstTx.sign(privateKey2);
const SignedByThirdTx = await SignedBySecondTx.sign(privateKey3);

//Sign the transaction with the client operator private key and submit to a Hedera network
const txResponse = await SignedByThirdTx.execute(client);

I'm seeing the following error response:

const publicKeyData = publicKey.toBytesRaw();
                                        ^
TypeError: Cannot read properties of undefined (reading 'toBytesRaw')

Solution

  • Having explored the Hedera JS SDK code I spotted this comment:

    // note: this omits the DER prefix on purpose because Hedera doesn't
    // support that in the protobuf. this means that we would fail
    // to re-inflate [this._signerPublicKeys] during [fromBytes] if we used DER
    // prefixes here
    const publicKeyHex = hex.encode(publicKeyData);
    

    I then tried to rebuild the ECDSA private keys using their HEX-encoded version (i.e. 0x....) and this allowed the Account Update Transaction to proceed successfully.

    // Add Keys for Multisig (based on 3 accounts)
    const privateKey1 = PrivateKey.fromStringECDSA('<Insert HEX-encoded Private Key String Here>');
    const privateKey2 = PrivateKey.fromStringECDSA('<Insert HEX-encoded Private Key String Here>');
    const privateKey3 = PrivateKey.fromStringECDSA('<Insert HEX-encoded Private Key String Here>');