I would like to know if when signing messages through Polkadot-JS it adds a prefix to the message before the signing to avoid signing transactions.

Do we have different functions for signing messages and transactions? Or they are the same and the validation of whether it is a transaction or not should be done on client-side?

1 Answer 1


No, it doesn't add a prefix.

But signing messages and transactions do use separate functions.

The Signer interface is defined as:

export interface Signer
   * @description signs an extrinsic payload from a serialized form
  signPayload?: (payload: SignerPayloadJSON) => Promise<SignerResult>;

   * @description signs a raw payload, only the bytes data as supplied
  signRaw?: (raw: SignerPayloadRaw) => Promise<SignerResult>;

   * @description Receives an update for the extrinsic signed by a `signer.sign`
  update?: (id: number, status: H256 | ISubmittableResult) => void;

When signing messages, signRaw is called. When signing transactions, signPayload is used.

If you call alice.sign('a') to sign a message, the payload would always be like

  type: "bytes",
  data: "a",
  address: "15StioR7cW1cui19icpxivT6iZR6e9RFKtj2urou1opJsCms"

But the result will vary each time you call it, because in sr25519 signatures are non-deterministic.

When you call await api.tx.system.remark('a'), the payload will be like

  specVersion: "0x0000240e",
  transactionVersion: "0x0000000c",
  address: "15StioR7cW1cui19icpxivT6iZR6e9RFKtj2urou1opJsCms",
  blockHash: "0x00b2aa61d007c887d20050856c9fd98d649dd92dda14eedc2faea189dfac05ad",
  blockNumber: "0x00a6409f",
  era: "0xf501",
  genesisHash: "0x91b171bb158e2d3848fa23a9f1c25182fb8e20313b2c1eb49219da7a70ce90c3",
  method: "0x00011448656c6c6f",
  nonce: "0x00000000",
  signedExtensions: [
  tip: "0x00000000000000000000000000000000",
  version: 4

The two types of payloads are not compatible with each other. Therefore you cannot send a spoofed transaction that way.

  • I see if the default behavior is not to add a prefix. This would mean that if we are using an external tool to sign a message that is not polkadot-js. It will follow the same pattern and not add a prefix as well. That means this tool could be signing a valid transaction since it will not add a prefix. I guess we will have to add some kind of validation to check if what was sent to sign is not a transaction. Would we have to decode the whole data and try to fit it into the transaction metadata to see if it is a valid transaction or not?
    – C. Leo
    Commented Jun 30, 2022 at 15:10

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.