How to sign a tuple/struct array #1678
Unanswered
SleepingProgrammer
asked this question in
Q&A
Replies: 1 comment
-
Using EIP-191This is very convenient when you have a single piece of data to sign, could be simply some message (in english). const data = '0x123456';
const signature = await this.wallet.signMessage(data);
// later verifying signature
const recoveredAddress = ethers.utils.verifyMessage(data, signature)
console.log(recoveredAddress === walletAddress) However, when you have multiple values or even complex data like structs. Writing logic to encode all the values into single data requires some time, as well as there is a risk of introducing some ambiguity (meaning one encoded message could mean multiple things). Using EIP-712This is convenient when you multiple values in your message. const domain = {
name: 'My App',
version: '1',
chainId: 1,
verifyingContract: '0x1111111111111111111111111111111111111111'
};
const types = {
WithdrawRequest: [
{ name: 'recipient', type: 'address' },
{ name: 'value', type: 'uint256' }
]
}
const withdrawRequest = {
recipient: '0x2222222222222222222222222222222222222222',
value: 10000
};
const signature = signer._signTypedData(domain, types, withdrawRequest)
// later verifying signature
const recoveredAddress = ethers.utils.verifyTypedData(domain, types, withdrawRequest, signature)
console.log(recoveredAddress === walletAddress) |
Beta Was this translation helpful? Give feedback.
0 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
I've been looking for an implementation to a sign a struct array but none of the ones I found worked for me.
Here's the contract struct I'm using
struct WithdrawRequest { address recipient; uint256 value; }
Here's the way I currently do it.
`
//Method used to sign the request
async signRequest(encodedData) {
// 66 byte string, which represents 32 bytes of data
let messageHash = ethers.utils.solidityKeccak256(["string], [encodedData]);
}
//Calls to sign
async DoRequest() {
var signer = this.state.wallet;
var amount = this.state.amount;
var receipient = await signer.getAddress();
const abiCoder = ethers.utils.defaultAbiCoder;
const encodedData = await abiCoder.encode([{
"components": [
{
"internalType": "address",
"name": "recipient",
"type": "address"
},
{
"internalType": "uint256",
"name": "value",
"type": "uint256"
}
],
"internalType": "struct SalesContract.Request[]",
"name": "_requests",
"type": "tuple[]"
}],
[
[
[receipient, amount] //For some reason, I have to enclose the tuple values inside 2 brackets, or it wouldn't work, would like to know why too
]
]);
}`
I've been trying different combinations for this but couldn't get the right combination where the address is the same as the actual signer's address.
Beta Was this translation helpful? Give feedback.
All reactions