Ethereum 带有EIP712的坚固性标志

Ethereum 带有EIP712的坚固性标志,ethereum,solidity,Ethereum,Solidity,我读了智能合同,感到困惑。正如课程告诉我们的ABI---- bytes32公共常量域_TYPEHASH=keccak256(“EIP712Domain(字符串名称,uint256链ID,地址验证契约)”; ... 函数delegateBySig(地址被委派者、uint nonce、uint到期、uint8 v、字节32 r、字节32 s)公共{ bytes32 domainSeparator=keccak256(abi.encode(DOMAIN_TYPEHASH,keccak256(bytes

我读了智能合同,感到困惑。正如课程告诉我们的ABI----

bytes32公共常量域_TYPEHASH=keccak256(“EIP712Domain(字符串名称,uint256链ID,地址验证契约)”;
...
函数delegateBySig(地址被委派者、uint nonce、uint到期、uint8 v、字节32 r、字节32 s)公共{
bytes32 domainSeparator=keccak256(abi.encode(DOMAIN_TYPEHASH,keccak256(bytes(name)),getChainId(),address(this));
bytes32 structHash=keccak256(abi.encode(DELEGATION_TYPEHASH,delegatee,nonce,expiry));
bytes32 digest=keccak256(abi.encodePacked(“\x19\x01”,域分隔符,structHash));
签字人地址=电子副本(摘要,v,r,s);
要求(签名人!=地址(0),“公司::授权人签名:无效签名”);
要求(nonce==nonce[签字人]+,“Comp::delegateBySig:无效nonce”);

require(现在在您已经展示的上下文中,
EIP712Domain
不是函数或公共属性。它也不是一个Solidity全局变量

它只是在
delegateBySig()
函数中签名的字符串消息的一部分


ABI代表“应用程序二进制接口”,它是一个包含参数(根据规范)的规范,以及表示您可能熟悉的函数定义的JSON

这个函数的作用是:

string DOMAIN_TYPEHASH = keccak256("EIP712Domain(string name,uint256 chainId,address verifyingContract)");
abi.encode(DOMAIN_TYPEHASH, keccak256(bytes(name)), getChainId(), address(this))

如果使用参数
keccak256(字节(名称))
getChainId()
地址(this)调用
EIP712Domain()
函数,它将生成与事务数据相同的二进制输出

问题是abi.encode使用这个包含EIP712域函数签名的字符串。abi是一个二进制接口。但它是如何在Internet上工作的?我现在很困惑。更新了我的答案,希望它有帮助。是的。但它仍然很奇怪,对吗?abi.encode的第一个参数是DOMAIN_TYPEHASH。如果我们没有看到它的字符串类型。它是一个函数,接收abi.encode其他参数为param。但是在整个文件中找不到此函数中的EIP712Domain。那么EIP712Domain定义在哪里?EVM如何知道它有此函数?整个代码段不调用
EIP712Domain()
函数-它只生成一个签名。因此该函数不必实现。它在第一个参数定义中定义了数据类型就足够了(对于
abi.encode
)。好的,非常感谢。我将花一些时间来理解这一点
 bytes32 public constant DOMAIN_TYPEHASH = keccak256("EIP712Domain(string name,uint256 chainId,address verifyingContract)");

...

    function delegateBySig(address delegatee, uint nonce, uint expiry, uint8 v, bytes32 r, bytes32 s) public {
        bytes32 domainSeparator = keccak256(abi.encode(DOMAIN_TYPEHASH, keccak256(bytes(name)), getChainId(), address(this)));
        bytes32 structHash = keccak256(abi.encode(DELEGATION_TYPEHASH, delegatee, nonce, expiry));
        bytes32 digest = keccak256(abi.encodePacked("\x19\x01", domainSeparator, structHash));
        address signatory = ecrecover(digest, v, r, s);
        require(signatory != address(0), "Comp::delegateBySig: invalid signature");
        require(nonce == nonces[signatory]++, "Comp::delegateBySig: invalid nonce");
        require(now <= expiry, "Comp::delegateBySig: signature expired");
        return _delegate(signatory, delegatee);
    }
string DOMAIN_TYPEHASH = keccak256("EIP712Domain(string name,uint256 chainId,address verifyingContract)");
abi.encode(DOMAIN_TYPEHASH, keccak256(bytes(name)), getChainId(), address(this))