I am looking for an example code snippet that demonstrates how to retrieve the public key of a sender account within a contract function. Specifically, we want to verify that the message and signature were signed by the sender, similar to the functionality shown in this code snippet - where we need the public key for the verify_ed25519_signatur call: fn test_signature_verification (
ctx: &ReceiveContext,
host: &mut Host,
crypto_primitives: &impl HasCryptoPrimitives,
) → ContractResult<()> {
// Get the contract owner.
let owner = ctx.owner();
// Get the sender of the transaction.
let sender = ctx.sender();
// Parse the parameter.
let params: VerificationParams = ctx.parameter_cursor().get()?;
// state and builder
let state = host.state();
// get PublicKeyEd25519 for the sender???
let is_valid = crypto_primitives.verify_ed25519_signature(
// key,
params.signature,
¶ms.message,
);
ensure!(is_valid, concordium_cis2::Cis2Error::Custom(CustomContractError::InvalidSignature));
Ok(())
}
Dear NHS,
for checking the signature generated by an account in a Concordium wallet (meaning the keys associated with an account), there is a function check_account_signature available that can be used in a smart contract context.
Concordium by default supports multi-sig accounts, hence an account can have several public keys and you would need to add some more custom logic if you retrieve the public key/keys yourself and do the verification manually. I recommend using the check_account_signature function since it simplifies the verification.
Please also note, that Concordium wallets prepend the signer address and 8 zero bytes before signing the message, and the check_account_signature does the same reverse construction when verifying the signature.
This isn’t urgent, but I was wondering if you have any tools to generate test data for this (account, signature, message) that can be used for the smart contract tests. Here’s the structure we’re working with:
You can deploy a very simple contract (such as the below one) and use it to verify your generated signature. By the way, that contract also shows how to look up the public_keys within the contract: