[英]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.