Solidity
創建智能合約時何時使用散列?
我正在閱讀solidity docs,並在一個契約範例中,因為我已經看到使用了keccak256。
// Perform checks to determine if transferring a token to the // `OwnedToken` contract should proceed function isTokenTransferOK(address currentOwner, address newOwner) public pure returns (bool ok) { // Check an arbitrary condition to see if transfer should proceed return keccak256(abi.encodePacked(currentOwner, newOwner))[0] == 0x7f; }
從這個影片中,我能夠理解:
散列函式是一個函式,它接受任意大小的輸入並輸出固定大小的數據。
我也明白 keccak 是一個雜湊函式。
創建智能合約時何時使用散列?它的目的是什麼?一個例子真的可以幫助我理解。
恕我直言,這不是教學的好例子。
雜湊函式對於驗證資訊非常有用,它們用於通過智能合約以及區塊鏈本身來證明事物。例如,塊交易被散列,這是一種真實塊的指紋。以前的區塊雜湊是該功能的一部分,因此它形成了一條鏈。
這不是學術描述,但它會給你這個工具的工作知識。
雜湊函式的屬性:
- 確定性:對於任何給定的輸入,輸出總是相同的。
- 固定大小:例如 32 字節
- 不相關:即使輸入的一位發生變化,輸出也會以不可預知的方式完全改變
- 防衝突:沒有兩個輸入應該產生相同的輸出,稱為雜湊衝突的“缺陷”。
- 高性能:計算雜湊的計算資源應該是合理的。
- 單向函式:散列對輸入的大小、格式或內容一無所知。
散列通常用於將密碼儲存在磁碟上,因為散列不會告訴任何人有關密碼的資訊,但使用者輸入的密碼可以快速散列,然後與表格進行比較。
它們還通常用於通過僅將文件的雜湊儲存在記錄系統(例如智能合約)中來驗證文件/文件。鑑於該記錄,任何人都可以確認他們擁有的文件與先前記錄的雜湊匹配——它必須是同一個文件。
這是一種將錢放入盒子並在有人知道秘密單詞時將其釋放的方法。
pragma solidity 0.7.6; contract Abracadabra { bytes32 public publicHash; constructor(bytes32 publicHash_) { publicHash = publicHash_; } function honeyPot(bytes32 password) public { // a little concatonation, then hash it // it can only be claimed by the intended recipient bytes32 hash = keccak256(abi.encodePacked(password, msg.sender)); // no one knows the password unless they learn about it off-chain // revert the transaction if the hash is wrong require(hash == publicHash, "That's not the magic word"); // the money only goes to msg.sender to prevent front-running msg.sender.transfer(address(this).balance); } receive () external payable {} }
請注意,雜湊從一開始就在鏈上,但它不能幫助任何人找出密碼。合約天真地儲存了密碼而不是雜湊,然後每個人都會看到密碼,這很糟糕。如果要確保這樣的事情,肯定還有更多需要考慮,但我想保持這個答案是正確的。
您需要能夠在部署時生成散列。從安全的角度來看,這並不安全,但應該可以在 Remix 中使用它。
// SPDX-License-Identifier: UNLICENSED pragma solidity 0.7.6; contract Abracadabra { bytes32 public publicHash; constructor(bytes32 publicHash_) { publicHash = publicHash_; } function honeyPot(bytes32 password) public { require(hashHelper(password, msg.sender) == publicHash, "That's not the magic word"); msg.sender.transfer(address(this).balance); } function hashHelper(bytes32 password, address receiver) public pure returns(bytes32 hash) { hash = keccak256(abi.encodePacked(password, receiver)); } receive () external payable {} }
希望能幫助到你。