Pelajaran 1

管理和升级合成资产合约

欢迎来到使用Remix IDE探索合成资产领域的第二部分!在第一部分中打下了坚实的基础后,我们现在将深入研究合成资产合约的更高级方面。本课程的这一部分旨在让您掌握管理、升级和优化合成资产合约的技能。

在我们开始本课程的高级部分之前,让我们花一点时间回顾一下我们在第一部分中开发的合成资产合约。这个合约将成为我们建立对智能合约管理和升级的理解的基础。

合成资产合约回顾

以下是我们之前实施的合成资产合约。该合约在区块链上实现了合成资产的创建、管理和交互功能。

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

contract SyntheticAsset {
    uint256 public underlyingAssetPrice;
    uint256 public collateral;
    address public owner;
    mapping(address => uint256) public syntheticBalance;
    uint256 public totalSyntheticSupply;

    constructor() {
        owner = msg.sender;
    }

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

    function updatePrice(uint256 _price) public onlyOwner {
        underlyingAssetPrice = _price;
    }

    function depositCollateral(uint256 _amount) public {
        collateral += _amount;
    }

    function withdrawCollateral(uint256 _amount) public {
        require(collateral >= _amount, "Insufficient collateral");
        collateral -= _amount;
    }

    function getSyntheticAssetPrice() public view returns (uint256) {
        return underlyingAssetPrice;
    }

    function mintSyntheticAsset(uint256 _amount) public {
        require(collateral >= _amount, "Insufficient collateral");
        syntheticBalance[msg.sender] += _amount;
        totalSyntheticSupply += _amount;
        collateral -= _amount;
    }

    function redeemSyntheticAsset(uint256 _amount) public {
        require(syntheticBalance[msg.sender] >= _amount, "Insufficient synthetic balance");
        syntheticBalance[msg.sender] -= _amount;
        totalSyntheticSupply -= _amount;
        collateral += _amount;
    }
}

现在,我们对基础合约有了一个全新的认识,让我们深入探讨管理和升级合成资产合约的各个方面。

合同所有权

  • 建立合同所有权,确保只有授权的实体可以修改合同。
  • 实施像onlyOwner这样的修饰符来限制对某些函数的访问是一种常见做法。

升级模式

  • 了解不同的升级模式,如代理(Proxy)、永久存储(Eternal Storage)和委托调用(DelegateCall)。
  • 探索每种模式的优缺点,选择最合适的模式用于您的合同。

代理合同

  • 深入研究代理合同,它允许在保持数据完整性的同时更新合同的逻辑。
  • 实施一个简单的代理合同来演示升级过程。
Solidity
contract Proxy {
    address public implementation;

    function upgradeImplementation(address _newImplementation) public onlyOwner {
        implementation = _newImplementation;
    }

    fallback() external payable {
        address impl = implementation;
        assembly {
            let ptr := mload(0x40)
            calldatacopy(ptr, 0, calldatasize())
            let result := delegatecall(gas(), impl, ptr, calldatasize(), 0, 0)
            let size := returndatasize()
            returndatacopy(ptr, 0, size)
            switch result
            case 0 { revert(ptr, size) }
            default { return(ptr, size) }
        }
    }
}

版本管控

  • 实施版本管控以跟踪合约升级。
  • 使用语义版本控制来显示每次升级中的变更类型。

升级测试

  • 确保升级不会引入错误或更改预期的功能。
  • 在控制环境中测试升级,然后再将其部署到主网络上。
    在引入代理合约进行升级后,我们的系统将如下所示:
Solidity
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

contract Proxy {
    address public implementation;
    address public owner;

    constructor() {
        owner = msg.sender;
    }

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

    function upgradeImplementation(address _newImplementation) public onlyOwner {
        implementation = _newImplementation;
    }

    fallback() external payable {
        address impl = implementation;
        assembly {
            let ptr := mload(0x40)
            calldatacopy(ptr, 0, calldatasize())
            let result := delegatecall(gas(), impl, ptr, calldatasize(), 0, 0)
            let size := returndatasize()
            returndatacopy(ptr, 0, size)
            switch result
            case 0 { revert(ptr, size) }
            default { return(ptr, size) }
        }
    }
}

contract SyntheticAsset {
    uint256 public underlyingAssetPrice;
    uint256 public collateral;
    address public owner;
    mapping(address => uint256) public syntheticBalance;
    uint256 public totalSyntheticSupply;

    constructor() {
        owner = msg.sender;
    }

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

    function updatePrice(uint256 _price) public onlyOwner {
        underlyingAssetPrice = _price;
    }

    function depositCollateral(uint256 _amount) public {
        collateral += _amount;
    }

    function withdrawCollateral(uint256 _amount) public {
        require(collateral >= _amount, "Insufficient collateral");
        collateral -= _amount;
    }

    function getSyntheticAssetPrice() public view returns (uint256) {
        return underlyingAssetPrice;
    }

    function mintSyntheticAsset(uint256 _amount) public {
        require(collateral >= _amount, "Insufficient collateral");
        syntheticBalance[msg.sender] += _amount;
        totalSyntheticSupply += _amount;
        collateral -= _amount;
    }

    function redeemSyntheticAsset(uint256 _amount) public {
        require(syntheticBalance[msg.sender] >= _amount, "Insufficient synthetic balance");
        syntheticBalance[msg.sender] -= _amount;
        totalSyntheticSupply -= _amount;
        collateral += _amount;
    }
}

在这个设置中,Proxy 合约充当SyntheticAsset合约的网关,允许对SyntheticAsset的实现(即逻辑)进行升级,而不会丢失合约的状态(即数据)。这是通过Proxy中的fallback函数实现的,该函数将调用委托给当前SyntheticAsset的实现,并通过upgradeImplementation函数允许所有者将实现地址更改为指向新版本的SyntheticAsset。

通过本课程,您将获得管理和升级合成资产合约所需的专业知识,确保它们能够适应不断变化的要求,同时保持合约的完整性和安全性。在接下来的课程中,我们将深入探讨更进阶的合成资产管理部分。敬请保持关注!

Pernyataan Formal
* Investasi Kripto melibatkan risiko besar. Lanjutkan dengan hati-hati. Kursus ini tidak dimaksudkan sebagai nasihat investasi.
* Kursus ini dibuat oleh penulis yang telah bergabung dengan Gate Learn. Setiap opini yang dibagikan oleh penulis tidak mewakili Gate Learn.
Katalog
Pelajaran 1

管理和升级合成资产合约

欢迎来到使用Remix IDE探索合成资产领域的第二部分!在第一部分中打下了坚实的基础后,我们现在将深入研究合成资产合约的更高级方面。本课程的这一部分旨在让您掌握管理、升级和优化合成资产合约的技能。

在我们开始本课程的高级部分之前,让我们花一点时间回顾一下我们在第一部分中开发的合成资产合约。这个合约将成为我们建立对智能合约管理和升级的理解的基础。

合成资产合约回顾

以下是我们之前实施的合成资产合约。该合约在区块链上实现了合成资产的创建、管理和交互功能。

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

contract SyntheticAsset {
    uint256 public underlyingAssetPrice;
    uint256 public collateral;
    address public owner;
    mapping(address => uint256) public syntheticBalance;
    uint256 public totalSyntheticSupply;

    constructor() {
        owner = msg.sender;
    }

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

    function updatePrice(uint256 _price) public onlyOwner {
        underlyingAssetPrice = _price;
    }

    function depositCollateral(uint256 _amount) public {
        collateral += _amount;
    }

    function withdrawCollateral(uint256 _amount) public {
        require(collateral >= _amount, "Insufficient collateral");
        collateral -= _amount;
    }

    function getSyntheticAssetPrice() public view returns (uint256) {
        return underlyingAssetPrice;
    }

    function mintSyntheticAsset(uint256 _amount) public {
        require(collateral >= _amount, "Insufficient collateral");
        syntheticBalance[msg.sender] += _amount;
        totalSyntheticSupply += _amount;
        collateral -= _amount;
    }

    function redeemSyntheticAsset(uint256 _amount) public {
        require(syntheticBalance[msg.sender] >= _amount, "Insufficient synthetic balance");
        syntheticBalance[msg.sender] -= _amount;
        totalSyntheticSupply -= _amount;
        collateral += _amount;
    }
}

现在,我们对基础合约有了一个全新的认识,让我们深入探讨管理和升级合成资产合约的各个方面。

合同所有权

  • 建立合同所有权,确保只有授权的实体可以修改合同。
  • 实施像onlyOwner这样的修饰符来限制对某些函数的访问是一种常见做法。

升级模式

  • 了解不同的升级模式,如代理(Proxy)、永久存储(Eternal Storage)和委托调用(DelegateCall)。
  • 探索每种模式的优缺点,选择最合适的模式用于您的合同。

代理合同

  • 深入研究代理合同,它允许在保持数据完整性的同时更新合同的逻辑。
  • 实施一个简单的代理合同来演示升级过程。
Solidity
contract Proxy {
    address public implementation;

    function upgradeImplementation(address _newImplementation) public onlyOwner {
        implementation = _newImplementation;
    }

    fallback() external payable {
        address impl = implementation;
        assembly {
            let ptr := mload(0x40)
            calldatacopy(ptr, 0, calldatasize())
            let result := delegatecall(gas(), impl, ptr, calldatasize(), 0, 0)
            let size := returndatasize()
            returndatacopy(ptr, 0, size)
            switch result
            case 0 { revert(ptr, size) }
            default { return(ptr, size) }
        }
    }
}

版本管控

  • 实施版本管控以跟踪合约升级。
  • 使用语义版本控制来显示每次升级中的变更类型。

升级测试

  • 确保升级不会引入错误或更改预期的功能。
  • 在控制环境中测试升级,然后再将其部署到主网络上。
    在引入代理合约进行升级后,我们的系统将如下所示:
Solidity
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

contract Proxy {
    address public implementation;
    address public owner;

    constructor() {
        owner = msg.sender;
    }

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

    function upgradeImplementation(address _newImplementation) public onlyOwner {
        implementation = _newImplementation;
    }

    fallback() external payable {
        address impl = implementation;
        assembly {
            let ptr := mload(0x40)
            calldatacopy(ptr, 0, calldatasize())
            let result := delegatecall(gas(), impl, ptr, calldatasize(), 0, 0)
            let size := returndatasize()
            returndatacopy(ptr, 0, size)
            switch result
            case 0 { revert(ptr, size) }
            default { return(ptr, size) }
        }
    }
}

contract SyntheticAsset {
    uint256 public underlyingAssetPrice;
    uint256 public collateral;
    address public owner;
    mapping(address => uint256) public syntheticBalance;
    uint256 public totalSyntheticSupply;

    constructor() {
        owner = msg.sender;
    }

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

    function updatePrice(uint256 _price) public onlyOwner {
        underlyingAssetPrice = _price;
    }

    function depositCollateral(uint256 _amount) public {
        collateral += _amount;
    }

    function withdrawCollateral(uint256 _amount) public {
        require(collateral >= _amount, "Insufficient collateral");
        collateral -= _amount;
    }

    function getSyntheticAssetPrice() public view returns (uint256) {
        return underlyingAssetPrice;
    }

    function mintSyntheticAsset(uint256 _amount) public {
        require(collateral >= _amount, "Insufficient collateral");
        syntheticBalance[msg.sender] += _amount;
        totalSyntheticSupply += _amount;
        collateral -= _amount;
    }

    function redeemSyntheticAsset(uint256 _amount) public {
        require(syntheticBalance[msg.sender] >= _amount, "Insufficient synthetic balance");
        syntheticBalance[msg.sender] -= _amount;
        totalSyntheticSupply -= _amount;
        collateral += _amount;
    }
}

在这个设置中,Proxy 合约充当SyntheticAsset合约的网关,允许对SyntheticAsset的实现(即逻辑)进行升级,而不会丢失合约的状态(即数据)。这是通过Proxy中的fallback函数实现的,该函数将调用委托给当前SyntheticAsset的实现,并通过upgradeImplementation函数允许所有者将实现地址更改为指向新版本的SyntheticAsset。

通过本课程,您将获得管理和升级合成资产合约所需的专业知识,确保它们能够适应不断变化的要求,同时保持合约的完整性和安全性。在接下来的课程中,我们将深入探讨更进阶的合成资产管理部分。敬请保持关注!

Pernyataan Formal
* Investasi Kripto melibatkan risiko besar. Lanjutkan dengan hati-hati. Kursus ini tidak dimaksudkan sebagai nasihat investasi.
* Kursus ini dibuat oleh penulis yang telah bergabung dengan Gate Learn. Setiap opini yang dibagikan oleh penulis tidak mewakili Gate Learn.