簡體   English   中英

具有提升權限的 Solidity 調用合約

[英]Solidity calling contract with elevated permissions

我有兩份合約,一份用於處理抵押,一份用於鑄造 NFT。 我想要的流程是讓用戶在前端反應應用程序中進行質押,這將調用質押合同。 然后,用戶將有資格在抵押時鑄造 NFT。

現在我面臨的問題是,因為鑄幣角色是從 stakingExample 合約中調用的,這需要用戶調用它,但由於它具有另一個合約的關鍵功能(鑄幣),所以應該用權限保護它,這樣只有StakingExample 可以調用 NFTExample 合約。

有沒有辦法允許用戶在智能合約中臨時以提升的權限運行 NFTExample?

抵押合約示例:

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

import "@openzeppelin/contracts/access/AccessControl.sol";
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";

contract StakingExample is AccessControl {

    bytes32 public constant CONTRACT_ROLE = keccak256("CONTRACT_ROLE");
    NFTExample public _NFTExample;

    ...

    function someStakingFunction() {
        // code that stakes and 
        // set some variable that tracks if user have minted
    }

    function claimNFT(uint256 _pid, string memory _tokenURI) public onlyRole(CONTRACT_ROLE) {
        // checks if user have unclaimed NFT
        if (haveUnclaimed) {
            _NFTExample.mintItem(msg.sender, _tokenURI)
        }
    }
}

NFT合約示例:

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

import "@openzeppelin/contracts/access/AccessControl.sol";
import "@openzeppelin/contracts/token/ERC721/extensions/ERC721URIStorage.sol";
import "@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol";
import "@openzeppelin/contracts/utils/Counters.sol";

contract CMRGachaSeedNFT is ERC721URIStorage, AccessControl, ERC721Enumerable {
    bytes32 public constant CONTRACT_ROLE = keccak256("CONTRACT_ROLE");

    using Counters for Counters.Counter;
    Counters.Counter private _tokenIds;

    ...
    
    // Only Contract Role can call mint item, which mint item and transfers it to user's address
    function mintItem(address _address, string memory _tokenURI)
        public
        onlyRole(CONTRACT_ROLE)
        returns (uint256)
    {
        // Do some checks

        // Mint
        _tokenIds.increment();

        uint256 newItemId = _tokenIds.current();
        _mint(_address, newItemId);
        _setTokenURI(newItemId, _tokenURI);

        return newItemId;
    }
}

您需要在 staking 合約中添加一個函數來顯示 staking 的數量:

function showStakeAmount() external view returns(uint256){
    //I don't know your codes about this but you need a mapping to store
    //the stake amount of each user and here you return it but something like this:
    return StakingAmountOfUsers(msg.sender);
}

然后你需要一個質押合約的接口和地址,還要在 NFT 合約中做一個修飾符(必須添加以下更改):

interface StakingInterface{
    function showStakeAmount() external view returns(uint256);
}

contract CMRGachaSeedNFT is ERC721URIStorage, AccessControl, ERC721Enumerable {
    uint256 AmountThatShouldBeStaked;

    StakingInterface StakingContract;

    constructor(address STAKING_CONTRACT_ADDRESS){
        StakingContract = StakingInterface(STAKING_CONTRACT_ADDRESS);
    }
    
    modifier isStaked(){
        require(StakingContract.showStakeAmount() > AmountThatShouldBeStaked, "You did not stake enough amount of X token");
        _;
    }

    function mintItem(address _address, string memory _tokenURI)
        public
        onlyRole(CONTRACT_ROLE)
        returns (uint256)
        isStaked()
    {
        //Continue coding...
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM