7*24快訊怎樣開發智...

怎樣開發智能合約中的時間鎖

這篇文章在時間上介紹智能合約中是什麼,講解如何開發請求。並且你可以按一個智能合約來開發,這個合約可能會導致ERC-20 通證的時間排序。

本教程使用到:

教程的代碼可以在這個 GitHub 回購 中找。

什麼是智能合約的時間鎖

複本,代碼鎖是使用鎖鏈的時間函數就可以鎖定在智能裡面的。 “如果”:

if (block.timestamp < _timelockTime) {

    revert ErrorNotReady(block.timestamp, _timelockTime);

}

時間鎖的應用場景

智能合約中有很多潛在的場景,它們通常會在公開發行中使用通證功能​​,用於實現通證銷售一些。時間鎖也可以被用於按照使用時間的收益投資的投資用途使用,即用戶只有在以後才可以使用資金。

可能的情況就是通過契約去實現遺囑。使用Chainlink Keepers,你可以單獨檢查這個遺囑主人是否已經死亡,有可能證明被遺囑遺囑的智能發布契約可以促成。

以上只是很少的一些應用案例,智能合約鎖有很多去場景使用。在這個案例中,我們會聚焦在一個 ERC-20 合同,用時間鎖實現一個結果來製造它。

怎樣創建一個智能時間鎖

在這個教程中,我們會使用Foundry 來開發和測試Solidity 合約。關於Foundry 這個框架,你可以是它的 GitHub 中查找更多信息。

初始化項目

你可以使用`forge init`初始化問題初始化項目。項目完成後,`forge test`命令會進行一次檢查確保項目初始化的過程沒有。

❯ forge init timelocked-contract

Initializing /Users/rg/Development/timelocked-contract...

Installing ds-test in "/Users/rg/Development/timelocked-contract/lib/ds-test", (url: https://github.com/dapphub/ds-test, tag: None)

    Installed ds-test

    Initialized forge project.

cd timelocked-contract 

❯ forge test

[⠒] Compiling...

[⠰] Compiling 3 files with 0.8.10

[⠔] Solc finished in 143.06ms

Compiler run successful




Running 1 test for src/test/Contract.t.sol:ContractTest

[PASS] testExample() (gas: 190)

Test result: ok. 1 passed; 0 failed; finished in 469.71µs

創建測試

 

你需要創建一些測試來確保智能合約可以實現時間鎖定的所有要求。需要測試的主要功能如下:

  • 讓通證的操作要素參與
  • 時間到來就進行鑄造
  • 取消早在中的操作

除了這些功能之外,您還需要保證智能合約沒有重複入列或入列之前生成這些錯誤操作。

當項目被初始化這些之後,你需要去運行這些測試,因為你需要這些來保證你的項目的實際執行和預測的測試,不需要你用例。測試在`src/test/Contract.t.sol`中。在Foundry 中,使用會測試的名字表示這些應該是成功還是失敗了。 `testThisShouldWork` 表示應該通過,而`testFailShouldNotWork` 表示只有來測試恢復這個時候才會被測試通過。

一些其他的使用情況。時間鎖會基於一個時段,這個節目會使用`_toress`、`_地址`和`_參數的哈希值`,而`keccak256`會計算它們的時間`的哈希值。

// Create hash of transaction data for use in the queue

function generateTxnHash(

    address _to,

    uint256 _amount,

    uint256 _timestamp

) public pure returns (bytes32) {

    return keccak256(abi.encode(_to, _amount, _timestamp));

}

另外,你需要自己設置測試環境中的時間來模擬有多少時間過去。這點可以通過Foundry 的`CheatCode` 實現。

interface CheatCodes {

    function warp(uint256) external;

}

wrap 設置當前的這個函數可以讓你使用這個函數。可以讓這個函數接受一個參數來生成新的時間指示。我們需要它給來“增加時間”,模擬時間的流。可以讓我們在測試中按照預期時間提供鎖定功能所需要的變量。

把`src/test/Contract.t.sol`中的內容替換為下面的代碼:

// SPDX-License-Identifier: UNLICENSED

pragma solidity 0.8.10;




import "ds-test/test.sol";

import "../Contract.sol";




interface CheatCodes {

    function warp(uint256) external;

}




contract ContractTest is DSTest {

    // HEVM_ADDRESS is the pre-defined contract that contains the cheatcodes

    CheatCodes constant cheats = CheatCodes(HEVM_ADDRESS);




    Contract public c;

    address toAddr = 0x1234567890123456789012345678901234567890;

    function setUp() public {

        c = new Contract();

        c.queueMint(

            toAddr,

            100,

            block.timestamp + 600

        );

    }




    // Ensure you can't double queue

    function testFailDoubleQueue() public {

        c.queueMint(

            toAddr,

            100,

            block.timestamp + 600

        );

    }




    // Ensure you can't queue in the past

    function testFailPastQueue() public {

        c.queueMint(

            toAddr,

            100,

            block.timestamp - 600

        );

    }




    // Minting should work after the time has passed

    function testMintAfterTen() public {

        uint256 targetTime = block.timestamp + 600;

        cheats.warp(targetTime);

        c.executeMint(

            toAddr,

            100,

            targetTime

        );

    }




    // Minting should fail if you mint too soon

    function testFailMintNow() public {

        c.executeMint(

            toAddr,

            100,

            block.timestamp + 600

        );

    }




    // Minting should fail if you didn't queue

    function testFailMintNonQueued() public {

        c.executeMint(

            toAddr,

            999,

            block.timestamp + 600

        );

    }




    // Minting should fail if try to mint twice

    function testFailDoubleMint() public {

        uint256 targetTime = block.timestamp + 600;

        cheats.warp(block.timestamp + 600);

        c.executeMint(

            toAddr,

            100,

            targetTime

        );

        c.executeMint(

            toAddr,

            100,

            block.timestamp + 600

        );

    }




    // Minting should fail if you try to mint too late

    function testFailLateMint() public {

        uint256 targetTime = block.timestamp + 600;

        cheats.warp(block.timestamp + 600 + 1801);

        emit log_uint(block.timestamp);

        c.executeMint(

            toAddr,

            100,

            targetTime

        );

    }




    // you should be able to cancel a mint

    function testCancelMint() public {

        bytes32 txnHash = c.generateTxnHash(

            toAddr,

            100,

            block.timestamp + 600

        );

        c.cancelMint(txnHash);

    }




    // you should be able to cancel a mint once but not twice

    function testFailCancelMint() public {

        bytes32 txnHash = c.generateTxnHash(

            toAddr,

            999,

            block.timestamp + 600

        );

        c.cancelMint(txnHash);

        c.cancelMint(txnHash);

    }




    // you shouldn't be able to cancel a mint that doesn't exist

    function testFailCancelMintNonQueued() public {

        bytes32 txnHash = c.generateTxnHash(

            toAddr,

            999,

            block.timestamp + 600

        );

        c.cancelMint(txnHash);

    }

}

開發合同

你現在應該可以執行命令偽造測試,然後看到許多錯誤,就讓我們使這些測試可以被通過。我們現在從一個最基礎的ERC-20 合約開始,所有的代碼都存儲在`src/Contract.sol `中。

// SPDX-License-Identifier: MIT

pragma solidity ^0.8.10;




import "@openzeppelin/contracts/token/ERC20/ERC20.sol";

import "@openzeppelin/contracts/access/Ownable.sol";




contract Contract is ERC20, Ownable {

    constructor() ERC20("TimeLock Token", "TLT") {}

}

這裡在使用OpenZeppelin 合約之前,你需要先安裝它,並且將Foundry 指向它們。

運行以下命令,這些安裝合約:

❯ forge install openzeppelin/openzeppelin-contracts

創建`remappings.txt` 來映射這些導入

@openzeppelin/=lib/openzeppelin-contracts/

ds-test/=lib/ds-test/src/

重新映射文​​件讓你像在Hardhat 中使用類似OpenZeppelin 契約的外部文件,或者將這個文件安裝到OpenZeppelin 類似的外部文件庫中,因為這個文件可以重新映射到我他們所在的文件夾。通過`forge install openzeppelin/openzeppelin-contracts` `OpenZeppelin合同,他們會被用來創建ERC-721 合同。

如果一切順利的話,你可以運行`forge build`來編譯合約。

完成操作以後,窗口就可以讓你將一個創建操作加入執行,然後在這個操作的時候,這個窗口就可以編寫這個操作。

// SPDX-License-Identifier: UNLICENSED

pragma solidity 0.8.10;




import "@openzeppelin/contracts/token/ERC20/ERC20.sol";

import "@openzeppelin/contracts/access/Ownable.sol";




contract Contract is ERC20, Ownable {

    // Error Messages for the contract

    error ErrorAlreadyQueued(bytes32 txnHash);

    error ErrorNotQueued(bytes32 txnHash);

    error ErrorTimeNotInRange(uint256 blockTimestmap, uint256 timestamp);

    error ErrorNotReady(uint256 blockTimestmap, uint256 timestamp);

    error ErrorTimeExpired(uint256 blockTimestamp, uint256 expiresAt);




    // Queue Minting Event

    event QueueMint(

        bytes32 indexed txnHash,

        address indexed to,

        uint256 amount,

        uint256 timestamp

    );

    // Mint Event

    event ExecuteMint(

        bytes32 indexed txnHash,

        address indexed to,

        uint256 amount,

        uint256 timestamp

    );

    // Cancel Mint Event

    event CancelMint(bytes32 indexed txnHash);




    // Constants for minting window

    uint256 public constant MIN_DELAY = 60; // 1 minute

    uint256 public constant MAX_DELAY = 3600; // 1 hour

    uint256 public constant GRACE_PERIOD = 1800; // 30 minutes




    // Minting Queue

    mapping(bytes32 => bool) public mintQueue;




    constructor() ERC20("TimeLock Token", "TLT") {}




    // Create hash of transaction data for use in the queue

    function generateTxnHash(

        address _to,

        uint256 _amount,

        uint256 _timestamp

    ) public pure returns (bytes32) {

        return keccak256(abi.encode(_to, _amount, _timestamp));

    }




    // Queue a mint for a given address amount, and timestamp

    function queueMint(

        address _to,

        uint256 _amount,

        uint256 _timestamp

    ) public onlyOwner {

        // Generate the transaction hash

        bytes32 txnHash = generateTxnHash(_to, _amount, _timestamp);

        // Check if the transaction is already in the queue

        if (mintQueue[txnHash]) {

            revert ErrorAlreadyQueued(txnHash);

        }

        // Check if the time is in the range

        if (

            _timestamp < block.timestamp + MIN_DELAY ||

            _timestamp > block.timestamp + MAX_DELAY

        ) {

            revert ErrorTimeNotInRange(_timestamp, block.timestamp);

        }

        // Queue the transaction

        mintQueue[txnHash] = true;

        // Emit the QueueMint event

        emit QueueMint(txnHash, _to, _amount, _timestamp);

    }




    // Execute a mint for a given address, amount, and timestamp

    function executeMint(

        address _to,

        uint256 _amount,

        uint256 _timestamp

    ) external onlyOwner {

        // Generate the transaction hash

        bytes32 txnHash = generateTxnHash(_to, _amount, _timestamp);

        // Check if the transaction is in the queue

        if (!mintQueue[txnHash]) {

            revert ErrorNotQueued(txnHash);

        }

        // Check if the time has passed

        if (block.timestamp < _timestamp) {

            revert ErrorNotReady(block.timestamp, _timestamp);

        }

        // Check if the window has expired

        if (block.timestamp > _timestamp + GRACE_PERIOD) {

            revert ErrorTimeExpired(block.timestamp, _timestamp);

        }

        // Remove the transaction from the queue

        mintQueue[txnHash] = false;

        // Execute the mint

        mint(_to, _amount);

        // Emit the ExecuteMint event

        emit ExecuteMint(txnHash, _to, _amount, _timestamp);

    }




    // Cancel a mint for a given transaction hash

    function cancelMint(bytes32 _txnHash) external onlyOwner {

        // Check if the transaction is in the queue

        if (!mintQueue[_txnHash]) {

            revert ErrorNotQueued(_txnHash);

        }

        // Remove the transaction from the queue

        mintQueue[_txnHash] = false;

        // Emit the CancelMint event

        emit CancelMint(_txnHash);

    }




    // Mint tokens to a given address

    function mint(address to, uint256 amount) internal {

        _mint(to, amount);

    }

}

可以做什麼直播

智能合約的時間鎖非常有用,它們可以讓合約內的交易安全和透明。但是時間無法觸發非常的話,所以你需要在某個時間自動執行這個函數。 ,就需要自動化你的合同。

鏈環守護者 可以讓你自動化智能合約中的函數。通過使用Chainlink Keepers,你可以在某些提前定義好的時間節點,讓你智能合約中的函數執行。想要了解更多關於Chainlink Keepers 的信息,請查看 守護者文檔

您可以關注鏈家禽機資料和私信加入者社區,有大量關於智能合約開發的學習以及關於區塊鏈的話題!

帖子 怎樣開發智能合約中的時間鎖 首先出現在 Chainlink 博客.

Source Link

最受歡迎

繼續閱讀

長期持有者持有的比特幣(BTC)供應量達到最高水平

根據Glassnode 的估計,比特幣的長期持有者(LTH)目前擁有1452 萬枚BTC,創歷史新高,只剩下25% 留給短期持...

抓住Web3 遊戲的先發優勢:成功策略

Web3和區塊鏈技術的出現徹底改變了遊戲行業,為開發者和企業家提供了前所未有的機遇。 Web3 遊戲的去中心化性質為創新遊戲貨幣化模式、玩家所有權和社區參與打...

現在讀

$COOKIE, the Cookie3 Mark...

Tallinn, Estonia, March 26th, 2024...

長期持有者持有的比特幣(BTC)供應量達到最高水平...

根據Glassnode 的估計,比特幣的長期持有者(LTH)目前擁有1452 萬枚BTC,創歷史新高,只剩下25% 留給短期持有者和投機者。 儘管BTC 的價格在過去一個月中保持相對平穩,範圍在約29,000 美元至31,000 美元之間,但人們還是開始瘋狂囤積。 ...

Caldera 宣布與Espresso Syste...

Caldera 開發人員可以利用Espresso Sequence...

抓住Web3 遊戲的先發優勢:成功策略

Web3和區塊鏈技術的出現徹底改變了遊戲行業,為開發者和企業家提供了前所未有的機遇。 Web3 遊戲的去中心化性質為創新遊戲貨幣化模式、玩家所有權和社區參與打開了大門。對於那些尋求利用Web3 遊戲巨大潛力的人來說,確保先發優勢至關重要。 了解Web3 遊戲生態系統在深入研究Web3 遊戲之前,有...

Taapsee Pannu 推出NFT 平台,介紹...

企業家貢獻者表達的意見是他們自己的。 您正在閱讀《企業家印度》,這是企業家媒體的國際特許經營刊物。 女演員Taapsee Pannu 最近推出了“taapseeclub.com”,這是她自己的非同質代...

比特幣(BTC) 地址休眠超過11 年,轉移310...

經過11 年多的閒置之後,一個包含3100 萬美元BTC 的休眠比特幣地址最近突然活躍起來。 2023年7月22日,地址 轉入 將其全部餘額轉移到新地址。 早期BTC 地址復活 比特幣自2009 年以來就已經存在,因此存在多年來不活躍的休眠地址,其中包含大量BTC。這種加密貨幣的一些早期採用者能夠...

加密貨幣死了嗎?當今加密貨幣的現狀

您之前可能聽說過加密貨幣正在消亡(或比特幣已消亡)。在這篇文章中,我們將研究加密貨幣的狀態,並嘗試回答這個問題:加密貨幣現在已經死了嗎? 在我們開始之前,我們想澄清一下,本文指的是最廣泛意義上的“加密貨幣行業”; 在裡面 網絡3 感覺。該定義包括加密資產市場; 但它還包括其他非財務用例。 隨著近來加...

Chancer 可能成為體育和社交博彩領域的下一個...

加密貨幣 隨著企業財報季節的繼續,本週股市表現好壞參半。在Ne...

以太坊(ETH) 創下兩個月來CEX 流入最高紀錄...

過去一周,以太坊(ETH)流入中心化交易所(CEX)的資金量創下了過去兩個月來的最高水平。這些重大的資產變動表明ETH 的價格可能會下跌。 CoinGecko 數據顯示,第二大加密貨幣的價格一直在小幅下跌,過去一周價值下跌了2.5%。截至撰寫本文時,以太幣易手價格為1,892.65 美元,過去24...

新的DeFi 法案有“不可行的義務”

加密貨幣創新委員會表示,新的反洗錢法案沒有為DeFi 中的非法金融...

幣安大幅削減成本,瑞波幣為美國銀行和加密貨幣風險投...

美國證券交易委員會(SEC)對加密貨幣公司的打擊似乎嚴重影響了幣安的業務。據報導,在過去幾週內,該加密貨幣交易所解雇了1,000 多名員工,並削減了一些福利。 幣安表示,“當前的市場環境和監管環境”導致利潤下降,這表明可能正在進行更多削減。一位發言人告訴Cointelegraph,該公司將考慮縮減“...

Automata 雙週更新:第48 期| 通過自動...

迎接新的季度意味著設定我們的意圖並為團隊規劃下一步的行動。幕後醞釀的一切——合作、產品功能和營銷發布——很難抑制我們的興奮。我們一開始就在1RPC(2 個備受期待的第2 層主網)上添加了對Linea 和Base 的支持。科技載體更新頁腳以顯示界面版本平滑的用戶體驗 USDC CCTP 支持 關於仲裁...