Web3js

Truffle js 的簽名測試失敗

  • June 18, 2020

我正在嘗試從我的契約ValidationUser 中測試validAddress 函式,使用松露並使用JS 進行測試。我檢查了簽名中的 V 值及其 27,28,所以這不是問題。此外,我在 Unity 端的程式碼可以正常使用此功能!但是在測試中它失敗了:addressCheck != 到發件人地址 - 所有者。任何建議如何修復測試?

驗證使用者.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;
   }
}

驗證使用者.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]
       });

});

我自己解決了!!

驗證使用者.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;
}

驗證使用者.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]
   });
});

有些事情要檢查

  • 消息的雜湊值是否與簽名的雜湊值匹配?緩衝區中的連接看起來是錯誤的。
  • 簽名消息是否包含“乙太坊簽名..”前綴?ECRecover 不會預先設置它。
  • 確保v參數是 27 或 28,有些庫會返回 0 或 1。

引用自:https://ethereum.stackexchange.com/questions/84258