EIP-7702

DeeLMind2025年6月19日大约 1 分钟

EIP-7702

EIP-7702open in new window 让 EOA(Externally Owned Account)在一笔交易期间,临时变成了 OA(合约账户,Contract Account),拥有合约账户的“超能力”。

  • 多签名
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;

contract EIP7702Multisig {
    uint256 public threshold;
    mapping(address => bool) public isSigner;

    event Executed(address target, uint256 value, bytes data);

    constructor(address[] memory _signers, uint256 _threshold) {
        require(_signers.length >= _threshold, "Invalid threshold");
        for (uint256 i = 0; i < _signers.length; i++) {
            isSigner[_signers[i]] = true;
        }
        threshold = _threshold;
    }

    function execute(
        address target,
        uint256 value,
        bytes calldata data,
        bytes[] calldata signatures
    ) external returns (bytes memory result) {
        bytes32 txHash = getTxHash(target, value, data);

        _validateSignatures(txHash, signatures);

        (bool success, bytes memory res) = target.call{value: value}(data);
        require(success, "Call failed");

        emit Executed(target, value, data);
        return res;
    }

    function getTxHash(
        address target,
        uint256 value,
        bytes memory data
    ) public view returns (bytes32) {
        return keccak256(abi.encodePacked(address(this), block.chainid, target, value, data));
    }

    function _validateSignatures(
        bytes32 txHash,
        bytes[] calldata signatures
    ) internal view {
        uint256 valid = 0;
        address[] memory seen = new address[](signatures.length);

        for (uint256 i = 0; i < signatures.length; i++) {
            address signer = recoverSigner(txHash, signatures[i]);
            require(isSigner[signer], "Invalid signer");

            // Ensure no duplicates
            for (uint256 j = 0; j < i; j++) {
                require(seen[j] != signer, "Duplicate signer");
            }

            seen[i] = signer;
            valid++;
        }

        require(valid >= threshold, "Not enough valid signatures");
    }

    function recoverSigner(bytes32 hash, bytes memory signature) public pure returns (address) {
        bytes32 ethSignedHash = toEthSignedMessageHash(hash);
        (bytes32 r, bytes32 s, uint8 v) = splitSignature(signature);
        return ecrecover(ethSignedHash, v, r, s);
    }

    function toEthSignedMessageHash(bytes32 hash) public pure returns (bytes32) {
        return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", hash));
    }

    function splitSignature(
        bytes memory sig
    ) public pure returns (bytes32 r, bytes32 s, uint8 v) {
        require(sig.length == 65, "Bad sig length");

        assembly {
            r := mload(add(sig, 32))
            s := mload(add(sig, 64))
            v := byte(0, mload(add(sig, 96)))
        }
    }

    receive() external payable {}
}
上次编辑于: 2025/6/18 22:48:05
贡献者: DeeLMind
重要公告(核心基础)