Contract-Development
如果我將消息的 sha256() 雜湊放在智能合約上,任何人都可以恢復該消息嗎?
如果沒有人可以恢復該消息,我可以將此消息用作智能合約中某些功能的“密碼”嗎?喜歡:
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. }
這只是一個想法。您可以考慮其他方法。