On-Chain Signature Verification & Replay Protection (blaze-v1
)
The blaze-v1
contract is the on-chain authority for verifying signed intents within the Blaze protocol. It ensures two critical properties: authenticity (the intent was signed by the claimed user) and uniqueness (the intent cannot be replayed).
The execute
Function
When a subnet contract wants to act on a user's signed intent, it calls the blaze-v1.execute
public function. This is the primary entry point for verification.
(define-public (execute
(signature (buff 65)) ;; The 65-byte signature from the user
(intent (string-ascii 32)) ;; Intent string (e.g., "TRANSFER_TOKENS")
(opcode (optional (buff 16))) ;; Optional opcode
(amount (optional uint)) ;; Optional amount
(target (optional principal)) ;; Optional target principal
(uuid (string-ascii 36)) ;; The unique UUID for this intent
)
;; ... implementation details ...
)
Key Operations within execute
:
-
Replay Protection:
(if (map-insert submitted-uuids uuid true)
;; ... proceed to verification ...
ERR_UUID_SUBMITTED
)The function first attempts to insert the provided
uuid
into thesubmitted-uuids
map.- If
map-insert
returnstrue
, it means the UUID was successfully inserted because it wasn't already present. The intent is considered new, and verification proceeds. - If
map-insert
returnsfalse
(because the keyuuid
already exists), it means this intent has been submitted before. The function immediately returnsERR_UUID_SUBMITTED
(u409000), preventing replay.
- If
-
Hash Reconstruction: The function reconstructs the 32-byte message hash that the user should have signed. It does this by calling its internal
hash
function (detailed in "Intents & Signing") usingcontract-caller
as thecontract
parameter for the hash. This is crucial:blaze-v1
assumes thecontract
part of the signed message is the principal of the contract callingexecute
(i.e., the subnet contract).(try! (hash contract-caller intent opcode amount target uuid))
-
Signature Verification: The reconstructed hash is then passed to the
verify
function along with the user'ssignature
.(verify <reconstructed_hash> signature)
-
Return Value: If both replay protection and signature verification pass,
execute
returns(ok signer-principal)
, wheresigner-principal
is the Stacks principal corresponding to the public key recovered from the signature. If any step fails, an appropriate error is returned.
The verify
Function
This internal read-only function performs the cryptographic signature check:
(define-read-only (verify
(message (buff 32)) ;; The 32-byte hash that was supposedly signed
(signature (buff 65)) ;; The user's secp256k1 signature
)
(match (secp256k1-recover? message signature)
public-key (principal-of? public-key) ;; If recovery is successful, get principal from public key
error ERR_INVALID_SIGNATURE ;; If recovery fails
)
)
- It uses the built-in
secp256k1-recover?
function to attempt to recover the public key from themessage
hash andsignature
. - If successful, it converts the recovered
public-key
to a Stacksprincipal
usingprincipal-of?
and returns(ok recovered-principal)
. - If
secp256k1-recover?
fails (e.g., the signature is invalid for the given message hash), it returnsERR_INVALID_SIGNATURE
(u401000).
Other Helper Functions
recover
: A read-only version that allows anyone to check a signature against a fully specified intent without attempting to mark the UUID as submitted. Useful for off-chain validation or UI feedback.check
: A read-only function to see if auuid
has already been submitted.
By combining these mechanisms, blaze-v1
provides a robust foundation for building secure, intent-driven applications on Stacks.