在以太坊中签名和验证消息

时间:2018-08-30 19:55:39

标签: ethereum solidity truffle

我正在尝试遵循此tutorial here

但是在本教程中,他没有指定如何执行合同。因此,我尝试使用松露和ganache-cli做到这一点。在松露测试中,我尝试使用以下代码:

const amount = web3.toWei(5, 'ether');
const Contract = await GmsPay.new({from : Sender, value : web3.toWei(10, 'ether')});
const hash = Web3Beta.utils.soliditySha3(
    {t : 'address', v : Recipient},
    {t : 'uint256', v : amount},
    {t : 'uint256', v : 1},
    {t : 'address', v : Contract.address}
);
const sig = await Web3Beta.eth.sign(hash, Sender);
const res = await Contract.claimPayment(amount, 1, sig, {from : Recipient});

但是我一直得到“错误:处理事务时虚拟机异常:还原”。使用调试器,我看到我的代码执行到:

require(recoverSigner(message, sig) == owner);

即使我把那行拿出来,最后一行仍然不起作用。我究竟做错了什么?任何帮助将不胜感激。

1 个答案:

答案 0 :(得分:1)

在我的松露测试中,使用“ recoverSigner(message,sig)== owner”检查遇到类似的挑战。比较了solidrecoverSigner()函数中生成的R,S,V值与使用ethereumjs-util的fromRpcSig()函数在测试端生成的相同值之后,我意识到recoverSigner将V返回为0,而fromRpcSig的值为27。This line提供了有效的答案。

如果遇到类似问题,请在下面提供最终的splitSignature()函数。

function splitSignature(bytes memory sig)
        internal
        pure
        returns (uint8, bytes32, bytes32)
    {
        require(sig.length == 65);

        bytes32 r;
        bytes32 s;
        uint8 v;

        assembly {
            // first 32 bytes, after the length prefix
            r := mload(add(sig, 32))
            // second 32 bytes
            s := mload(add(sig, 64))
            // final byte (first byte of the next 32 bytes)
            v := byte(0, mload(add(sig, 96)))
        }

        // support both versions of `eth_sign` responses
        if (v < 27) 
            v += 27;

        return (v, r, s);
    }