Hi guys, I am working on the project. But have a lot of problems, mostly because do not have good examples on how I can do it on Sophia. Most of them I solved…
Right now got another issue. SO I want to sign some message using oracle private key, and verify it on smartcontracts. On ethereium it works perfect.
how I generate signature
async function getSignature(web3, account, swapId) {
let message = swapId;
let hash = await web3.eth.personal.sign(message, account);
return hash;
}
How I verify it on ethereum side
function parseSignature(bytes memory _signature)
internal
pure
returns (
bytes32 r,
bytes32 s,
uint8 v
)
{
assembly {
r := mload(add(_signature, 32))
s := mload(add(_signature, 64))
v := and(mload(add(_signature, 65)), 0xff)
}
if (v < 27) v += 27;
if (v != 27 && v != 28) revert SignatureInvalidV();
}
function sign(bytes32 swapId, bytes memory signature) external {
(bytes32 r, bytes32 s, uint8 v) = parseSignature(signature);
address signer = ecrecover(getUnsignedMsg(swapId), v, r, s);
if (signer != oracle) {
revert SignatureInvalidV();
}
swaps[swapId].signature = signature;
emit SwapSigned(swapId, signature);
}
function getUnsignedMsg(bytes32 data) internal pure returns (bytes32) {
return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", data));
}
It works like a charm. Trying to calidate it on ae side.
entrypoint get_unsigned_msg(data: hash) : hash =
// 19457468657265756d205369676e6564204d6573736167653a0a3332 - is hash of the "\x19Ethereum Signed Message:\n32"
Crypto.sha3(Bytes.concat(#19457468657265756d205369676e6564204d6573736167653a0a3332, data))
require(Crypto.ecverify_secp256k1(get_unsigned_msg(swapId), state.oracle, signature), "Signature is not valid")
and it fails.
What I tried. I generate hash on ethereum using
let hash = await web3.eth.accounts.hashMessage(swapId);
and using get_unsigned_msg(swapId)
and the are the same.
In Sophia’s tests I found this code:
contract BitcoinAuth =
record state = { nonce : int, owner : bytes(20) }
entrypoint init(owner' : bytes(20)) = { nonce = 1, owner = owner' }
stateful entrypoint authorize(n : int, s : bytes(65)) : bool =
require(n >= state.nonce, "Nonce too low")
require(n =< state.nonce, "Nonce too high")
put(state{ nonce = n + 1 })
switch(Auth.tx_hash)
None => abort("Not in Auth context")
Some(tx_hash) => Crypto.ecverify_secp256k1(to_sign(tx_hash, n), state.owner, s)
entrypoint to_sign(h : hash, n : int) : hash =
Crypto.blake2b((h, n))
But why hash is generated using blake2b? SHould be sha3?
So my main question. Does anybody have worked example how I can sign message using web3 and verify it on ae side?