OpenZeppelin 提供很多好用的工具使用

這章節說到**Cryptography(密碼)**相關:

搬磚進階:

在一些交易體系中,存在著只有單向交易,意思就是帳戶A向B發送付款,而B無法向A發送付款

(有心人就知道改怎麼做了 😈 ,所以我們最好是多了解一點。)

參考來源:https://learnblockchain.cn/article/3566 講得非常詳細例如為什麼這樣做省gas。

這裡有修正0.8.0 版本的執行

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import "<https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v4.5.0/contracts/utils/cryptography/ECDSA.sol>";
import "<https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v4.5.0/contracts/security/ReentrancyGuard.sol>";

contract UniDirectionalPaymentChannel is ReentrancyGuard {
    using ECDSA for bytes32;
    address payable public sender;
    address payable public receiver;

    constructor(address payable _receiver) payable {
        require(_receiver != address(0), "receiver = zero address");
        sender = payable(msg.sender);
        receiver = _receiver;
    }

    function _getHash(uint _amount) private view returns (bytes32) {
        return keccak256(abi.encodePacked(address(this), _amount));
    }

    function getHash(uint _amount) external view returns (bytes32) {
        return _getHash(_amount);
    }

    function _getEthSignedHash(uint _amount) private view returns (bytes32) {
        return _getHash(_amount).toEthSignedMessageHash();
    }

    function getEthSignedHash(uint _amount) external view returns (bytes32) {
        return _getEthSignedHash(_amount);
    }

    function _verify(uint _amount, bytes memory _sig) private view returns (bool) {
        return _getEthSignedHash(_amount).recover(_sig) == sender;
    }
		// 驗證
    function verify(uint _amount, bytes memory _sig) external view returns (bool) {
        return _verify(_amount, _sig);
    }
		// 一旦我們聲明了這些函數,以便從一邊到另一邊簽署和恢復信息,我們就可以安全地進行交易了。
    function send(uint _amount, bytes memory _sig) external nonReentrant {
        //  verifing signature and sender != receiver
        require(msg.sender == receiver, "sender must be different than receiver");
        require(_verify(_amount, _sig), "invalid signature");
        
        (bool sent, ) = receiver.call{value: _amount}("");
        require(sent, "Failed to send Ether");
        selfdestruct(sender);
    }
}

其實我們理解之後,會發現其實就是一個加密解密的過程(回到大學的時候 瑟瑟發抖 🙀 )

還可以看到這裡引用了 ReentrancyGuard 這個套件,主要是解決重入攻擊這個我們要開一個章節解釋,所以其實我們用好OpenZeppeline 套件,就算不懂用下去也就比較安全。

10.Utils-Math

有任何問題可反饋: [email protected]