Web3js
Truffle js 的簽名測試失敗
我正在嘗試從我的契約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。