Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to verify signed Tx and signer's address? #640

Closed
golddydev opened this issue Sep 8, 2023 · 4 comments
Closed

How to verify signed Tx and signer's address? #640

golddydev opened this issue Sep 8, 2023 · 4 comments

Comments

@golddydev
Copy link

Hello everybody.
I am now facing an issue while I tried to verify the signed Tx.

I was trying to verify this signed Tx in the same way I verify the signed Data using

@emurgo/cardano-message-signing-nodejs
@emurgo/cardano-serialization-lib-nodejs

I send the signedData like this

const signedData = {
    signature: transaction string,
    key: signed transaction
}

But I got error like this.

Deserialization failed in TransactionWitnessSet because: Invalid cbor: not the right type, expected Map' byte received Array'.

I think it is because the transaction format and the message (signedData) format is different.
But how to fix this?

Can anyone help?

Thank you.

@lisicky
Copy link
Contributor

lisicky commented Sep 8, 2023

Hi @eageringdev ! Unfortunately I can not help with additional information like a code example, cbor of transaction

@golddydev
Copy link
Author

golddydev commented Sep 8, 2023

At least, verifying signed transaction is doable?
The blockchain itself certainly do.
But how can we do on our own code?

@lisicky
Copy link
Contributor

lisicky commented Sep 8, 2023

You can check it by CSL:

  1. Use FixedTransaction type to deserialize a transaction
  2. get raw_body from FixedTransaction and and body hash by TransactionHash.from_bytes(blake2b(32).update(raw_body).digest('binary'))
  3. After you can get signatures and public keys from tx witness set and verify it by calling verify from PublicKey type

@golddydev
Copy link
Author

Thanks, @lisicky
Your answer inspires me.
Extract the public key from transaction body.

import { C } from 'lucid-cardano';

export const decodeSignedData = ({ signedData }) => {
  const { signature, data } = signedData;
  const txVkeyWitnesses = C.TransactionWitnessSet.from_bytes(
    Buffer.from(signature, 'hex')
  );
  const pubKeyHash = txVkeyWitnesses
    .vkeys()
    ?.get(0)
    .vkey()
    .public_key()
    .hash()
    .to_hex();

  const tx = C.Transaction.from_bytes(Buffer.from(data, 'hex'));
  const txSignerPubKeyHash = tx.body().required_signers()?.get(0).to_hex();

  const isVerified = pubKeyHash?.length > 0 && pubKeyHash == txSignerPubKeyHash;

  const rewardAddress = C.RewardAddress.new(
    C.NetworkInfo.mainnet().network_id(),
    C.StakeCredential.from_keyhash(C.Ed25519KeyHash.from_hex(pubKeyHash))
  );
  return {
    isVerified,
    signerAddress: rewardAddress.to_address().to_bech32(),
  };
};

This is the code snippet to verify the signed transaction.
Where the signedData.signature is signed transaction and signedData.data is transaction data (hex string).

What do you think?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants