0

I'm trying to test validAddress function from my contract ValidationUser, using truffle and test with JS. I checked the V value from the signature and its 27,28 so it is not the problem. Also, I have the code inside Unity side that works ok with this function! But inside the test it's failed on: addressCheck != to the sender address - the owner. Any suggestions how to fix the test?

ValidationUser.sol:

constructor() public {
    owner = msg.sender;
}

function validAddress(
    int256 theMsg,
    uint8 v,
    bytes32 r,
    bytes32 s
) public payable returns (uint8) {
    bytes32 hash = keccak256(abi.encodePacked(msg.sender, owner, theMsg));
    address addressCheck = ecrecover(hash, v, r, s);
    if (addressCheck != owner) {
        revert(addressToString(addressCheck));
        //  return v;
    }
}

ValidationUser.js:

it('should return valid result from validAddress function', async function () {

    var EthUtil = require('ethereumjs-util');
    const messageToSign = web3.utils.toBN(12);
    //privateKey ot the owner - accounts[0]:
    const privateKey = "b25421d6dabd6e9119c45c4daf4ca4f8f86bd6761cc20c095906073da7c02471";
    var hash = EthUtil.hashPersonalMessage(new Buffer(accounts[2] + accounts[0] + EthUtil.intToHex(messageToSign)));
    var signature = EthUtil.ecsign(hash, new Buffer(privateKey, 'hex'));
    var signatureRPC = EthUtil.toRpcSig(signature.v, signature.r, signature.s)
    console.log(signatureRPC);

    const contract = await ValidationUserContract.deployed();
    const owner = await contract.getOwner();
    const theMsg = await contract.validAddress.call(messageToSign,
        signature.v,
        signature.r,
        signature.s, {
            from: accounts[2]
        });

});
0

Some things to check

  • Does the message's hash match the signed one? The concatenation in a buffer looks wrong.
  • Does signed message include "Ethereum signed.." prefix? ECRecover doesn't prepend it.
  • Make sure v parameter is either 27 or 28, some libraries return 0 or 1 instead.
| improve this answer | |
  • what "Ethereum signed.." prefix means? do you have example? V value from the signature and its 27,28 so it is not the problem.. how you suggest to concatenation? – Dorel Jun 15 at 7:33
  • @Dorel Some api's like eth.sign will prepend a prefix before signing, other like personal.sign will not. If ecsign used the prefix take a look at OpenZeppelin contracts how to prepend it. I'd guess that accounts[] starts with 0x you should not include those when hashing. Also the result should be hexadecimal and have to use 'hex' parameter with Buffer after concatenation. – Ismael Jun 15 at 16:28
0

I solved it myself!!

ValidationUser.sol:

function validAddress(
    int256 theMsg,
    uint8 v,
    bytes32 r,
    bytes32 s
) public payable returns (bool) {
    bytes32 hash = keccak256(abi.encodePacked(msg.sender, owner, theMsg));
    return isSigned(owner, hash, v, r, s);
}


function isSigned(
    address _addr,
    bytes32 msgHash,
    uint8 v,
    bytes32 r,
    bytes32 s
) public pure returns (bool) {
    return ecrecover(msgHash, v, r, s) == _addr;
}

ValidationUser.js:

beforeEach(async () => {
    contract = await ValidationUserContract.deployed();
});

function toHex(str) {
    var hex = ''
    for (var i = 0; i < str.length; i++) {
        hex += '' + str.charCodeAt(i).toString(16)
    }
    return hex;
}

it('should return valid result from isSigned function', async function () {
    var str = 'msg';
    let signature = await web3.eth.sign('0x' + toHex(str), accounts[2])
    signature = signature.substr(2); //remove 0x
    const r = '0x' + signature.slice(0, 64);
    const s = '0x' + signature.slice(64, 128);
    const v = '0x' + signature.slice(128, 130);
    const v_decimal = web3.utils.toDecimal(v)
    let fixed_msg = `\x19Ethereum Signed Message:\n${3}${str}`
    let fixed_msg_sha = web3.utils.sha3(fixed_msg)
    const theMsg = await contract.isSigned.call(accounts[0], fixed_msg_sha, v_decimal, r, s, {
        from: accounts[0]
    });
});


it('should return valid result from validAddress function', async function () {
    var str = 12;
    let signature = await web3.eth.sign(str, accounts[2])
    signature = signature.substr(2); //remove 0x
    const r = '0x' + signature.slice(0, 64);
    const s = '0x' + signature.slice(64, 128);
    const v = '0x' + signature.slice(128, 130);
    const v_decimal = web3.utils.toDecimal(v)
    let fixed_msg = `\x19Ethereum Signed Message:\n${2}${str}`
    let fixed_msg_sha = web3.utils.sha3(fixed_msg)
    const theMsg = await contract.validAddress.call(fixed_msg_sha, v_decimal, r, s, {
        from: accounts[0]
    });
});
| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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