0

The domain message is:

     struct Offer{
        address from;
        address to;
        uint256 nonce;
        uint256[] tokenIds;
        uint256 duration;
    }

    bytes32 constant EIP712DOMAIN_TYPEHASH = keccak256(
        "EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"
    );

    bytes32 constant OFFER_TYPEHASH = keccak256(
        "Offer(address from,address to,uint256 nonce,uint256[] memory tokenIds,uint256 duration)"
    );

    function hash(Offer memory offer) public pure returns (bytes32) {
        return keccak256(abi.encode(
            OFFER_TYPEHASH,
            offer.from,
            offer.to,
            offer.nonce,
            keccak256(abi.encodePacked(offer.tokenIds)),
            offer.duration
        ));
    }

 function verify(Offer memory offer, uint8 v, bytes32 r, bytes32 s) public view returns (bool) {
        // Note: we need to use encodePacked here instead of encode.
        bytes32 digest = keccak256(abi.encodePacked(
            "\x19\x01",
            DOMAIN_SEPARATOR,
            hash(offer)
        ));
        return ecrecover(digest, v, r, s) == ExpectedAddress;
    }

I can't resolve issue with array when doing v4 signature.

If I removed tokenIds array from Offer struct, and OfferTypeHash, and also from hash func: everything works well as expected, I can verify signature via web3 and contract.

When I put tokenIds array to struct, I can't verify signature. I googled and tried a lot of examples like:

I use this for hashing the offer:

keccak256(abi.encodePacked(array)) 
    function hash(Offer memory offer) public pure returns (bytes32) {
        return keccak256(abi.encode(
            OFFER_TYPEHASH,
            offer.from,
            offer.to,
            offer.nonce,
            keccak256(abi.encodePacked(offer.tokenIds)),
            offer.duration
        ));
    }

keccak256(abi.encode(array))
keccak256(abi.encodePacked(array)) 
    function hash(Offer memory offer) public pure returns (bytes32) {
        return keccak256(abi.encode(
            OFFER_TYPEHASH,
            offer.from,
            offer.to,
            offer.nonce,
            keccak256(abi.encode(offer.tokenIds)),
            offer.duration
        ));
    }

Even without Keccak:

 function hash(Offer memory offer) public pure returns (bytes32) {
        return keccak256(abi.encode(
            OFFER_TYPEHASH,
            offer.from,
            offer.to,
            offer.nonce,
            keccak256(abi.encode(offer.tokenIds)),
            offer.duration
        ));
    }

I can't figure out: why keccak256(abi.encode is not doing the job?

1 Answer 1

0

the issue with memory just remove

bytes32 constant OFFER_TYPEHASH = keccak256(
    "Offer(address from,address to,uint256 nonce,uint256[] memory tokenIds,uint256 duration)"
);

to

bytes32 constant OFFER_TYPEHASH = keccak256(
    "Offer(address from,address to,uint256 nonce,uint256[] tokenIds,uint256 duration)");

Just remove memory from hash ,it will work.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.