简体   繁体   English

具有提升权限的 Solidity 调用合约

[英]Solidity calling contract with elevated permissions

I have two contracts, one for handling staking and one for minting a NFT.我有两份合约,一份用于处理抵押,一份用于铸造 NFT。 The flow I want is for the user to stake in frontend react app which will invoke the staking contract.我想要的流程是让用户在前端反应应用程序中进行质押,这将调用质押合同。 The user will then be eligible to mint a NFT when staked.然后,用户将有资格在抵押时铸造 NFT。

Now the issue I am facing is that because the minting role is called from stakingExample contract, which requires the user to invoke this, but as it has a critical function (mint) of the other contract, it should be protected with permissions such that only StakingExample can call NFTExample contract.现在我面临的问题是,因为铸币角色是从 stakingExample 合约中调用的,这需要用户调用它,但由于它具有另一个合约的关键功能(铸币),所以应该用权限保护它,这样只有StakingExample 可以调用 NFTExample 合约。

Is there a way to allow the user to run NFTExample with elevated permissions temporary in smart contract?有没有办法允许用户在智能合约中临时以提升的权限运行 NFTExample?

Example of staking contract:抵押合约示例:

// 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)
        }
    }
}

Example of NFT contract: 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;
    }
}

You need to add one function in staking contract which shows amount of the staking:您需要在 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);
}

Then you need an interface of the staking contract and its address, also make an modifier in NFT contract (Following changes must be added):然后你需要一个质押合约的接口和地址,还要在 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.

相关问题 在MonoDevelop中使用提升的权限运行控制台应用程序 - Run console application with elevated permissions in MonoDevelop Visual Studio需要Windows 7中的提升权限 - Visual Studio requires elevated permissions in Windows 7 我可以在没有提升权限的情况下从visual studio运行程序吗? - Can I run a program from visual studio without elevated permissions? 如何使用 ctypes 运行具有提升的 UAC 权限的脚本? - How do I run a script with elevated UAC permissions using ctypes? Visual Studio安装程序项目将我的数据库设置为需要管理员权限才能在使用提升的权限进行安装时进行写入 - Visual Studio installer project sets my database to require admin privileges to write when installed with elevated permissions 没有任何权限的呼叫联系人 - Calling contact WITHOUT any permissions 调用createEntityType时出现权限错误 - Permissions error when calling createEntityType 如何在Laravel API和调用应用程序中使用权限 - How to use permissions with Laravel API and Calling Application 手动调用Collection.allow()以检查权限 - Calling Collection.allow() manually to check permissions 在调用EventLog.SourceExists之前检测EventLog权限 - Detect EventLog permissions before calling EventLog.SourceExists
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM