erc20的签名值为629680c82f82ad9ea02704a988d70565741def2d93ec95efe07d8bd6976340e15b87a837d96406516436eef6d88491598e9c4f1c15aaf7260db8ef25af5b5851c,使用js求erc20的permit的r,s,v的值
时间: 2024-03-03 15:48:26 浏览: 206
以下是使用JavaScript计算ERC20 permit的r,s,v值的示例代码:
```javascript
const ethers = require('ethers');
const abi = require('ethereumjs-abi');
const signature = '629680c82f82ad9ea02704a988d70565741def2d93ec95efe07d8bd6976340e15b87a837d96406516436eef6d88491598e9c4f1c15aaf7260db8ef25af5b5851c';
const owner = '0x1234567890123456789012345678901234567890';
const spender = '0x0987654321098765432109876543210987654321';
const value = 100;
const nonce = 1;
const deadline = 1634028589;
// Define the EIP712 domain separator
const domainType = [
{ name: 'name', type: 'string' },
{ name: 'version', type: 'string' },
{ name: 'chainId', type: 'uint256' },
{ name: 'verifyingContract', type: 'address' }
];
const domainData = {
name: 'My Token',
version: '1.0',
chainId: 1, // Change to the correct chain ID
verifyingContract: '0x1234567890123456789012345678901234567890' // Change to the correct contract address
};
const domainSeparator = '0x' + ethers.utils.keccak256(
ethers.utils.defaultAbiCoder.encode(
['bytes32', 'bytes32', 'bytes32', 'uint256', 'address'],
[
ethers.utils.keccak256(ethers.utils.defaultAbiCoder.encode(domainType, [domainData])),
ethers.utils.keccak256(Buffer.from('1901', 'hex')),
ethers.utils.keccak256(Buffer.from('This is my typed data message!')),
1,
domainData.verifyingContract
]
)
).substring(2);
// Define the permit type
const permitType = [
{ name: 'owner', type: 'address' },
{ name: 'spender', type: 'address' },
{ name: 'value', type: 'uint256' },
{ name: 'nonce', type: 'uint256' },
{ name: 'deadline', type: 'uint256' }
];
const permitData = {
owner,
spender,
value,
nonce,
deadline
};
const permitStructHash = '0x' + abi.soliditySHA3(
['bytes32', ...permitType.map(({ type }) => type)],
[ethers.utils.keccak256(Buffer.from('Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)')), ...Object.values(permitData)]
).toString('hex');
// Recover the signer from the signature
const { v, r, s } = ethers.utils.splitSignature(Buffer.from(signature, 'hex'));
const digest = ethers.utils.keccak256(
ethers.utils.defaultAbiCoder.encode(
['bytes1', 'bytes1', 'bytes32', 'bytes32'],
[
'0x19',
'0x01',
domainSeparator,
permitStructHash
]
)
);
const recoveredAddress = ethers.utils.recoverAddress(digest, { v, r, s });
// Verify that the recovered signer matches the owner
if (recoveredAddress.toLowerCase() !== owner.toLowerCase()) {
throw new Error('Invalid signature');
}
// Print the r, s, v values
console.log('r:', r.toString());
console.log('s:', s.toString());
console.log('v:', v.toString());
```
在上面的示例代码中,我们使用ethers.js和ethereumjs-abi库来计算ERC20 permit的r,s,v值。具体来说,我们首先定义了EIP712 domain separator和permit type,并将其编码为字节数组。然后,我们将这些字节数组哈希为domain separator和permit struct hash,使用签名值来恢复签名者的地址,并验证签名者是否与owner相匹配。最后,我们将r,s,v值打印到控制台上。
需要注意的是,上面的示例代码中的domainData.verifyingContract和domainData.chainId需要根据具体的ERC20代币合约进行修改。
阅读全文