🔑 关键词:合约钱包EOA vs 合约账户EIP-1271isValidSignaturesignMessage兼容性、Safe Wallet、合约签名校验


不是所有钱包都能直接签名

传统钱包(MetaMask)属于 EOA(Externally Owned Account),可以用私钥直接签名;

合约钱包(如 Gnosis Safe)没有私钥,不支持标准签名接口,不能使用 signMessage / signTypedData

为了让 DApp 正确支持这类钱包,我们需要:

合约钱包,在我看来就是合约账户。 那为什么叫“合约钱包”而不是“合约账户”?


识别合约钱包:获取地址字节码

✅ 方法:调用 eth_getCode 检查地址是否为合约

const bytecode = await publicClient.getBytecode({ address })

const isContract = !!bytecode && bytecode !== '0x'

📌 原理:EOA 地址没有部署代码,返回 '0x';合约钱包返回实际字节码。


EIP-1271 签名验证标准

EIP-1271 为合约账户提供了一个合约级签名验证接口

/**
isValidSignature 是 EIP-1271 标准定义的接口函数
*/
function isValidSignature(bytes32 hash, bytes memory signature) external view returns (bytes4 magicValue);