1

enter image description here

these are the parameters, included in function sendMultiSig() from contract multiSigWallet{}.

how can I input expireTime and signature? and who will be the toAddress? A msg.sender? a signer? or a non signer?

function sendMultiSig(
    address toAddress, 
    uint value, 
    uint expireTime, 
    uint sequenceId, 
    bytes signature
) 
    onlysigner 
    payable 
{
    // Verify the other signer
    var operationHash = sha3("ETHER", toAddress, value, expireTime, sequenceId);

    var otherSigner = verifyMultiSig(toAddress, operationHash, signature, expireTime, sequenceId);
}

function verifyMultiSig(
    address toAddress, 
    bytes32 operationHash, 
    bytes signature, 
    uint expireTime, 
    uint sequenceId
) 
    private 
    returns (address) 
{

    var otherSigner = recoverAddressFromSignature(operationHash, signature);

    // Verify if we are in safe mode. In safe mode, the wallet can only send to signers
    if (safeMode && !isSigner(toAddress)) {
        // We are in safe mode and the toAddress is not a signer. Disallow!
        revert();
    }
    // Verify that the transaction has not expired
    if (expireTime < block.timestamp) {
        // Transaction expired
        revert();
    }

    // Try to insert the sequence ID. Will throw if the sequence id was invalid
    tryInsertSequenceId(sequenceId);

    if (!isSigner(otherSigner)) {
    // Other signer not on this wallet or operation does not match arguments
        revert();
    }
    if (otherSigner == msg.sender) {
        // Cannot approve own transaction
        revert();
    }
    return otherSigner;
}

function recoverAddressFromSignature(
    bytes32 operationHash, 
    bytes signature
) 
    private 
    returns (address) 
{
    if (signature.length != 65) {
        revert();
    }
    // We need to unpack the signature, which is given as an array of 65 bytes (from eth.sign)
    bytes32 r;
    bytes32 s;
    uint8 v;
    assembly {
        r := mload(add(signature, 32))
        s := mload(add(signature, 64))
        v := and(mload(add(signature, 65)), 255)
    }
    if (v < 27) {
        v += 27; // Ethereum versions are 27 or 28 as opposed to 0 or 1 which is submitted by some signing libs
    }
    return ecrecover(operationHash, v, r, s);
}
5
  • Could you also add your contract code to see what is expected from the input? Jan 24, 2019 at 12:02
  • Yes, I've edited my question with code snippet...!
    – Rudrika
    Jan 25, 2019 at 6:24
  • Could you also add the "verifyMultiSig()"? There is the logic of how to compute the signature. Jan 25, 2019 at 11:54
  • The expireTime shall be the unix time stamp (see: unixtimestamp.com) Jan 25, 2019 at 11:55
  • @ChenchenYo yes I've edited
    – Rudrika
    Jan 25, 2019 at 13:37

2 Answers 2

3

From the information you gave, this contract shall be a multi-sig wallet that needs to collect approvals from multiple signers to send some token/ether to the recipient account. It is most likely to be an "ether" transaction due to the prefix. The account that could call the sendMultiSig() function is a signer.

Let's break down the required inputs.

  • toAddress: A field that expects to receive address type. It should be the recipient of the token/ether transaction. This address could be the msg.sender, a signer or a non-signer. However, when the contract goes to the 'safeMode', only acceptable address is a signer.
  • value: The amount to be transacted.
  • expireTime: The deadline of collecting all necessary signatures to validate the transaction. After this time spot, the transaction is considered as "expired". expireTime is in form of "unix time stamp". To convert natural time to unix time stamp, you could use this website.
  • sequenceId: unclear from the code snippet that you provided. I guess it's a unique ID of the transaction.
  • signature: The previously-signed message from another signer. This signature is provided by another signer (different from the account that is going to call the sendMultiSig() function) and is calculated with web3.eth.sign(dataToSign, addressWithPrivateKey) more info about this function. Here the dataToSign is a hash (of sha3, more specifically keccak256) of some value. These value contains:
    • "ETHER"
    • toAddress
    • value
    • expireTime
    • sequenceId
0
1

Just to add to ChenchenYo's answer, sequenceId is sequential numbering used to guard against replay attacks. You can get this off the deployed contract. For example, you can see it here pulled up on Parity after you make a query to the contract: Parity getNextSequenceId query

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.