当前位置:   article > 正文

Signature Replay_function tokeccak256() public view returns(bytes32

function tokeccak256() public view returns(bytes32) { return keccak256(abi.e

Signing messages off-chain and having a contract that requires that signature before executing a function is a useful technique.

For example this technique is used to:

  • reduce number of transaction on chain
  • gas-less transaction, called meta transaction

Vulnerability

Same signature can be used multiple times to execute a function. This can be harmful if the signer's intention was to approve a transaction once.

  1. // SPDX-License-Identifier: MIT
  2. pragma solidity ^0.8.10;
  3. pragma experimental ABIEncoderV2;
  4. import "github.com/OpenZeppelin/openzeppelin-contracts/blob/release-v3.3/contracts/cryptography/ECDSA.sol";
  5. contract MultiSigWallet {
  6. using ECDSA for bytes32;
  7. address[2] public owners;
  8. constructor(address[2] memory _owners) payable {
  9. owners = _owners;
  10. }
  11. function deposit() external payable {}
  12. function transfer(
  13. address _to,
  14. uint _amount,
  15. bytes[2] memory _sigs
  16. ) external {
  17. bytes32 txHash = getTxHash(_to, _amount);
  18. require(_checkSigs(_sigs, txHash), "invalid sig");
  19. (bool sent, ) = _to.call{value: _amount}("");
  20. require(sent, "Failed to send Ether");
  21. }
  22. function getTxHash(address _to, uint _amount) public view returns (bytes32) {
  23. return keccak256(abi.encodePacked(_to, _amount));
  24. }
  25. function _checkSigs(bytes[2] memory _sigs, bytes32 _txHash)
  26. private
  27. view
  28. returns (bool)
  29. {
  30. bytes32 ethSignedHash = _txHash.toEthSignedMessageHash();
  31. for (uint i = 0; i < _sigs.length; i++) {
  32. address signer = ethSignedHash.recover(_sigs[i]);
  33. bool valid = signer == owners[i];
  34. if (!valid) {
  35. return false;
  36. }
  37. }
  38. return true;
  39. }
  40. }

Preventative Techniques

Sign messages with nonce and address of the contract.

  1. // SPDX-License-Identifier: MIT
  2. pragma solidity ^0.8.10;
  3. pragma experimental ABIEncoderV2;
  4. import "github.com/OpenZeppelin/openzeppelin-contracts/blob/release-v3.3/contracts/cryptography/ECDSA.sol";
  5. contract MultiSigWallet {
  6. using ECDSA for bytes32;
  7. address[2] public owners;
  8. mapping(bytes32 => bool) public executed;
  9. constructor(address[2] memory _owners) payable {
  10. owners = _owners;
  11. }
  12. function deposit() external payable {}
  13. function transfer(
  14. address _to,
  15. uint _amount,
  16. uint _nonce,
  17. bytes[2] memory _sigs
  18. ) external {
  19. bytes32 txHash = getTxHash(_to, _amount, _nonce);
  20. require(!executed[txHash], "tx executed");
  21. require(_checkSigs(_sigs, txHash), "invalid sig");
  22. executed[txHash] = true;
  23. (bool sent, ) = _to.call{value: _amount}("");
  24. require(sent, "Failed to send Ether");
  25. }
  26. function getTxHash(
  27. address _to,
  28. uint _amount,
  29. uint _nonce
  30. ) public view returns (bytes32) {
  31. return keccak256(abi.encodePacked(address(this), _to, _amount, _nonce));
  32. }
  33. function _checkSigs(bytes[2] memory _sigs, bytes32 _txHash)
  34. private
  35. view
  36. returns (bool)
  37. {
  38. bytes32 ethSignedHash = _txHash.toEthSignedMessageHash();
  39. for (uint i = 0; i < _sigs.length; i++) {
  40. address signer = ethSignedHash.recover(_sigs[i]);
  41. bool valid = signer == owners[i];
  42. if (!valid) {
  43. return false;
  44. }
  45. }
  46. return true;
  47. }
  48. }
  49. /*
  50. // owners
  51. 0xe19aea93F6C1dBef6A3776848bE099A7c3253ac8
  52. 0xfa854FE5339843b3e9Bfd8554B38BD042A42e340
  53. // to
  54. 0xe10422cc61030C8B3dBCD36c7e7e8EC3B527E0Ac
  55. // amount
  56. 100
  57. // nonce
  58. 0
  59. // tx hash
  60. 0x12a095462ebfca27dc4d99feef885bfe58344fb6bb42c3c52a7c0d6836d11448
  61. // signatures
  62. 0x120f8ed8f2fa55498f2ef0a22f26e39b9b51ed29cc93fe0ef3ed1756f58fad0c6eb5a1d6f3671f8d5163639fdc40bb8720de6d8f2523077ad6d1138a60923b801c
  63. 0xa240a487de1eb5bb971e920cb0677a47ddc6421e38f7b048f8aa88266b2c884a10455a52dc76a203a1a9a953418469f9eec2c59e87201bbc8db0e4d9796935cb1b
  64. */

Try on Remix

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/花生_TL007/article/detail/141791
推荐阅读
相关标签
  

闽ICP备14008679号