Skip to content

RFC: Signed Transfers - allowing third parties to transfer on behalf of user signature #28

@tunnckoCore

Description

@tunnckoCore

Few weeks ago i've came up with that, and we discussed with @RogerPodacter, seems like forgot to publish it here.

The ability a user to sign a message, and someone else to execute the transaction - allowing Agents or third parties to move Ethcriptions on behalf of a user.

The way it would work is that someone submits the signature and the recipient to a contract call. That contract method verify the signature, finds the signer, and triggers and ethscriptions_protocol_SignedTransfer(ethscriptionId, recipient, signer, signature); event. The indexer on other hand ALSO verify a few things:

  1. finds the signer foundSigner,
  2. compares that foundSigner is equal to the passed signer,
  3. checks if ethscriptionId is owned by the currentOwner and it matches the foundSigner/signer, and
  4. if all is fine, assign the ethscription to the new owner.

We can even use EIP-712 typed structs so we can even use all that for trading - eg. user signs a listing, then buyer comes and posts a the listing, the method makes all the checks like price, signer, and etc, then emits SignedTranfer event and the indexer can assign to the buyer. Now, of course it would be turned into "pending payment", so that the indexer or someone else (provers, verifiers, relayers, community, whatever we call it) could submit that the indexers verifications pass too (the indexer could do that on its own but that adds cost to indexers, so.. why not the community), so the submitter/verifier would "release the funds" to the correct buyer, and the submitter could even get rewards for the job.

That's kind of similar to "oracles" - i came up with that in the last few days too. Why not have a Oracles for Ethscriptions, but that's another topic.

Pseudo contract that does signed transfers:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.26;

contract EthcriptionSignedTransfer {
    error InvalidSignature();
    error InvalidSignatureLength();

    event ethscriptions_protocol_SignedTransfer(
        bytes32 ethscriptionId,
        address recipient,
        address signer,
        bytes signature
    );

    function signedTransferEthscription(
        bytes32 ethscriptionId,
        address recipient,
        bytes memory signature
    ) external {
        if (signature.length != 65) {
            revert InvalidSignatureLength();
        }

        bytes32 r;
        bytes32 s;
        uint8 v;

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

        bytes32 messageHash = keccak256(
            abi.encodePacked(ethscriptionId, recipient)
        );
        bytes32 ethSignedMessageHash = keccak256(
            abi.encodePacked("\x19Ethereum Signed Message:\n32", messageHash)
        );

        address signer = ecrecover(ethSignedMessageHash, v, r, s);

        if (signer == address(0)) {
            revert InvalidSignature();
        }
        
        emit ethscriptions_protocol_SignedTransfer(
            ethscriptionId,
            recipient,
            signer,
            signature
        );
    }
}

Image

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions