Very interesting proposal!
Can the data be composite at multiple layers, like [[x₁, x₂, ..., xₙ], [y₁, y₂, ..., yₙ]]
?
And what’s the actual gas cost for a specific number of messages (n)?
@hellohanchen thanks for the review!
Currently the messages must be flattened for signature: [x₁, x₂, ..., xₙ]
.
Gas cost for verification? Thats a good question I can run a test to find out. Runtime should be log(n)
number of messages, if the tree is properly constructed.
Thanks for replying. I currently don’t have a great use case for this but this is interesting. Signature and validation work should become more flexible to prepare for the future use cases.
I do have some use cases that the signatures need to be layered like
sig1 = sign(message, key_1)
sig2 = sign(sig1, key_2)
And both signatures need to be verified.
Nice idea…
I noticed that signTypedData has a “backward compatibility”, to return a single result.
however, the sample solidity code only uses a merkle-proof, and doesn’t work with a single-entry proof returned by signTypedData_v5
Hi @dror, thanks for reviewing.
The proposed schema for signedTypedData_v5
result is:
{
signature: `0x${string}`; // Hex encoded 65 byte signature
merkleRoot: `0x${string}`; // 32 byte Merkle root as hex string
proofs: Array<Array<`0x${string}`>>; // Array of Merkle proofs (one for each input message)
}
When N=1
, the derivation path is an empty array as the sole message is root and signedTypedData_v5
returns:
{
signature: `<< sign(keccak256(encode(m))) >>`;
merkleRoot: `<< keccak256(encode(m)) >>`;
proofs: [
[]
]
}
During verification
_verifyMerkleProof(N=1) = root == leaf
Simplifying check to
isVerified = isValidSignature && root == leaf
Here is a unit test for this case: ERCs/assets/erc-7920/test/solidity.test.ts at 5580d029fc43c7cffb1300788fe5db0bc7f386eb · ethereum/ERCs · GitHub
ok, so just to verify:
I can take a “standard” signTypedData result, and pass it as “root” with an empty merkle proof, and it will succeed. right ?
Hi @dror, here’s what verification would look like with a signedTypedData_v4
result
isVerified = isValidSignature(fullSig) && _verifyMerkleProof(messageHash, [], messageHash)
This would always evaluate as true
_verifyMerkleProof(messageHash, [], messageHash)
Leaving
isVerified = isValidSignature(fullSig)