Icon HelpCircleForumIcon Link

⌘K

Icon HelpCircleForumIcon Link
Verify Signature

Icon LinkVerifying Signatures in Sway

Example of how to verify signatures in Sway

contract;
 
use std::hash::*;
use std::ecr::{ec_recover_address, EcRecoverError};
use std::bytes::Bytes;
use std::b512::B512;
use std::constants::ZERO_B256;
 
abi VerifySignature {
    fn GetMessageHash(to: b256, amount: u64, message: str, nonce: u64) -> b256;
    fn GetEthSignedMessageHash(message_hash: b256) -> b256;
    fn RecoverSigner(eth_signed_message_hash: b256, signature: B512) -> b256;
    fn verify(signer: b256, to: b256, amount: u64, message: str, nonce: u64, signature: B512) -> bool;
    
}
 
fn GetMessageHash(to: b256, amount: u64, message: str, nonce: u64) -> b256 {
        keccak256({
        let mut bytes = Bytes::new();
        bytes.append(Bytes::from(core::codec::encode(to)));
        bytes.append(Bytes::from(core::codec::encode(amount)));
        bytes.append(Bytes::from(core::codec::encode(message)));
        bytes.append(Bytes::from(core::codec::encode(nonce)));
        bytes
    })
    }
 
    fn GetEthSignedMessageHash(message_hash: b256) -> b256 {
        keccak256({
        let mut bytes = Bytes::new();
        bytes.append(Bytes::from(core::codec::encode("\x19Fuel Signed Message:\n32")));
        bytes.append(Bytes::from(core::codec::encode(message_hash)));
        bytes
    })
    }
 
    fn RecoverSigner(eth_signed_message_hash: b256, signature: B512) -> b256 {
        match ec_recover_address(signature, eth_signed_message_hash) {
            Ok(address) => address.bits(),
            Err(_) => ZERO_B256,
        }
    }
 
impl VerifySignature for Contract {
 
 
    fn GetMessageHash(to: b256, amount: u64, message: str, nonce: u64) -> b256{
        ::GetMessageHash(to, amount, message, nonce)
    }
 
    fn GetEthSignedMessageHash(message_hash: b256) -> b256 {
        ::GetEthSignedMessageHash(message_hash)
    }
 
    fn RecoverSigner(eth_signed_message_hash: b256, signature: B512) -> b256{
        ::RecoverSigner(eth_signed_message_hash, signature)
    }
    
   fn verify(signer: b256, to: b256, amount: u64, message: str, nonce: u64, signature: B512) -> bool {   
        let MessageHash = GetMessageHash(to, amount, message, nonce);
        let EthSignedMessage = GetEthSignedMessageHash(MessageHash);
        let RecoverSigner = RecoverSigner(EthSignedMessage, signature);
        RecoverSigner == signer
    }
}