Contract-Development

如果我將消息的 sha256() 雜湊放在智能合約上,任何人都可以恢復該消息嗎?

  • August 31, 2022

如果沒有人可以恢復該消息,我可以將此消息用作智能合約中某些功能的“密碼”嗎?喜歡:

contract Test {
   bytes32 hash;

   constructor(bytes32 _hash) {
       hash = _hash;
   }

   function getReward(string calldata password) public  {
       require(
           keccak256(abi.encodePacked(password)) == hash,
           "wrong password!"
       );
       ...
   }

沒有人可以根據雜湊值恢復原始消息,這是不可能的。攻擊者需要嘗試許多隨機消息來檢查一個是否產生相同的雜湊,這是不可行的。

但是,您不能在智能合約中使用雜湊作為“密碼”,因為當使用者將“密碼”發送到您的智能合約時,交易將位於記憶體池中,並且每個人都可以看到“密碼”,這不是一個好主意。在這種情況下,可以發起搶先攻擊,礦工在記憶體池中看到帶有“密碼”的交易,並決定使用“密碼”創建他自己的另一筆交易,並提供比您的交易更高的 gas 價格,所以他的交易比你的更先被探勘,並破解你的合約。

在智能合約或區塊鏈中實際上並沒有什麼是私有的,即使你private在智能合約中聲明變數,也可以通過web3.eth.getStorageAt直接看到它:

web3.eth.getStorageAt(yourSmartContractAddress, theIndexOfYourStateVariable);

例如,像這樣:

// SPDX-License-Identifier: MIT
pragma solidity 0.8.16;

contract Rewards_v1 {

   address public owner;

   constructor() {
       owner = msg.sender;
   }

   modifier onlyOwner() {
       require(msg.sender == owner, "Not owner");
       _;
   }

   // Only the owner is able to get the reward
   function getReward() public onlyOwner {
       //...
   }

}

或者像這樣:

contract Rewards {

   address public owner;
   mapping(address => bool) public whitelist;
   mapping(address => Reward) public rewards;

   struct Reward {
       address recipient;
       uint256 amount;
       //...
   }

   constructor() {
       owner = msg.sender;
   }

   modifier onlyOwner() {
       require(msg.sender == owner, "Not owner");
       _;
   }

   modifier whitelisted() {
       require(whitelist[msg.sender], "Not whitelisted");
       _;
   }

   function getReward() public whitelisted view returns(Reward memory) {
       //... more logic
       return rewards[msg.sender];
   }

   function addToWhitelist(address recipient) public onlyOwner {
       whitelist[recipient] = true;
   }

   function removeFromWhitelist(address recipient) public onlyOwner {
       delete whitelist[recipient];
   }

   function addReward(address recipient, uint256 amount /*, more properties */) public onlyOwner {
       rewards[recipient] = Reward(recipient, amount);
   }

   //... more logic related to the reward issuing, transfering, etc.

}

這只是一個想法。您可以考慮其他方法。

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