After reviewing the tECDSA documents and examples, I understand that the sign_with_ecdsa
method is signing using the key from the canister root key or a key obtained through further derivation.
So in theory, as in the tECDSA Rust example, this sign function:
async fn sign(message: String) -> Result<SignatureReply, String> {
let request = SignWithECDSA {
message_hash: sha256(&message).to_vec(),
derivation_path: vec![],
key_id: EcdsaKeyIds::TestKeyLocalDevelopment.to_key_id(),
};
let (response,): (SignWithECDSAReply,) = ic_cdk::api::call::call_with_payment(
mgmt_canister_id(),
"sign_with_ecdsa",
(request,),
25_000_000_000,
)
.await
.map_err(|e| format!("sign_with_ecdsa failed {}", e.1))?;
Ok(SignatureReply {
signature_hex: format!("0x{}", hex::encode(&response.signature)),
})
}
should be signed using the public key generated by this ecdsa_public_key
method, given that I am not changing the deviation path between the two functions and using them in the same canister.
async fn public_key() -> Result<PublicKeyReply, String> {
let request = ECDSAPublicKey {
canister_id: None,
derivation_path: vec![],
key_id: EcdsaKeyIds::TestKeyLocalDevelopment.to_key_id(),
};
let (res,): (ECDSAPublicKeyReply,) =
ic_cdk::call(mgmt_canister_id(), "ecdsa_public_key", (request,))
.await
.map_err(|e| format!("ecdsa_public_key failed {}", e.1))?;
Ok(PublicKeyReply {
public_key_hex: hex::encode(&res.public_key),
})
}
In my code, I convert the public key to an Ethereum address. However, when I deploy this and attempt to send an Ethereum transaction, I always receive an “insufficient funds to pay for gas” error. I initially assumed the Ethereum address of the public key generated by my canister did not have enough funds.
To confirm, I used ethers
to verify a signature (received from the sign function) against the message I passed in (matching the one sent to the sign function). Surprisingly, this returned a different Ethereum address each time.
I assume that there could be a possibility that the sign function is signing a different public key each time.
- Should I be explicit with the canister ID in the request to sign_with_ecdsa?
- Is there anything else that I could be overlooking?