国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

conflux開發(fā)NFT智能合約(ERC721 & 工廠合約 & 可升級(jí)合約)

這篇具有很好參考價(jià)值的文章主要介紹了conflux開發(fā)NFT智能合約(ERC721 & 工廠合約 & 可升級(jí)合約)。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

以下場(chǎng)景可借鑒本文內(nèi)容

  • 需要?jiǎng)?chuàng)建很多合約
  • 需要使用conflux代付機(jī)制(只需將工廠合約設(shè)置為代付,即可無限創(chuàng)建新合約)
  • 合約想要有可升級(jí)的能力(如:特殊玩法 or 代碼有bug)
  • ERC-721 NFT

基于以上場(chǎng)景,需要三個(gè)主要合約實(shí)現(xiàn)

  • 工廠合約
  • 代理合約
  • 邏輯合約

想要完全掌握本文內(nèi)容,你需要提前了解

  • Conflux交易詳解:https://juejin.cn/post/6971741780429668365
  • conflux-rpc文檔:OPEN-RPC Playground
  • NFT開發(fā)示例:https://forum.conflux.fun/t/conflux-2022-5-18-721-20-721-1155-nft/8781
  • conflux metadata: https://forum.conflux.fun/t/conflux-metadata/16083
  • "數(shù)字藏品"開發(fā)規(guī)范:https://forum.conflux.fun/t/conflux/15538
  • 合約之間互相調(diào)用:https://zhuanlan.zhihu.com/p/503497056
  • 可升級(jí)合約:https://learnblockchain.cn/article/4257
  • 工廠 + 代理:http://t.csdn.cn/aym0I
  • eip1967: https://zhuanlan.zhihu.com/p/480217161

代碼實(shí)現(xiàn)

1、工廠合約(創(chuàng)建代理合約、創(chuàng)建邏輯合約、代付)

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

import "@confluxfans/contracts/InternalContracts/InternalContractsHandler.sol";
import "./Monkey.sol";
import "./MonkeyProxy.sol";
import "./CloneFactory.sol";


interface LogicInterface {
    function initialize(string memory name, string memory symbol, string memory uri) external;
}

interface ProxyInterface {

    function mint(address to, uint256 tokenId) external;

    function transfer(address from, address to, uint256 tokenId) external;

    function burn(uint256 tokenId) external;
}

contract MonkeyFactory is CloneFactory {
    address private _admin;
    address private _logicTemplate;

    SponsorWhitelistControl constant private SPONSOR = SponsorWhitelistControl(0x0888000000000000000000000000000000000001);

    constructor(address admin, address logicTemplate) public{
        _admin = admin;
        _logicTemplate = logicTemplate;
        _addPrivilege(admin);
    }

    function _addPrivilege(address admin) private {
        address[] memory addressList = new address[](1);
        addressList[0] = admin;
        SPONSOR.addPrivilege(addressList);
    }

    function updateLogicTemplate(address logicTemplate) public {
        require(_admin == msg.sender, "MonkeyFactory: must have admin role");
        _logicTemplate = logicTemplate;
    }

    function createLogic() external returns(address){
        require(_admin == msg.sender, "MonkeyFactory: must have admin role");

        LogicInterface logic = LogicInterface(createClone(_logicTemplate));

        return address(logic); // 這里可以考慮使用event
    }

    function createProxy(address logicAddr, string memory name, string memory symbol, string memory uri) external returns(address){
        require(_admin == msg.sender, "MonkeyFactory: must have admin role");

        bytes memory initData = abi.encodeWithSignature("initialize(string,string,string)", name, symbol, uri);

        MonkeyProxy proxy = new MonkeyProxy(logicAddr, initData);

        return address(proxy);  // 這里可以考慮使用event
    }

    function upgradeLogic(address proxyAddr, address newAddress) public{
        require(_admin == msg.sender, "MonkeyFactory: must have admin role");

        (bool _ok, bytes memory ret) = proxyAddr.call(abi.encodeWithSignature(
            "upgradeVersion(address,address)", newAddress
        ));
        require(_ok, string(ret));
    }

    function mint(address proxyAddr, address to, uint256 tokenId) public{
        require(_admin == msg.sender, "MonkeyFactory: must have admin role");

        ProxyInterface proxy = ProxyInterface(proxyAddr);

        proxy.mint(to, tokenId);
        
        // 如果使用featureCode,可以在這里繼續(xù)操作,其他代碼則按需實(shí)現(xiàn)
    }

    function transfer(address proxyAddr, address from, address to, uint256 tokenId) external {
        require(_admin == msg.sender, "MonkeyFactory: must have admin role");

        ProxyInterface proxy = ProxyInterface(proxyAddr);

        proxy.transfer(from, to, tokenId);
    }

    function burn(address proxyAddr, uint256 tokenId) external {
        require(_admin == msg.sender, "MonkeyFactory: must have admin role");

        ProxyInterface proxy = ProxyInterface(proxyAddr);

        proxy.burn(tokenId);
    }
    // 考慮使用fallback調(diào)用代理合約,即使方法變更,也可以正常發(fā)起調(diào)用
}

2、代理合約

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

// 看明白這個(gè)合約,先了解下eip-1967,很多代碼是固定寫法
contract MonkeyProxy {
    // https://github.com/ethereum/EIPs/blob/master/EIPS/eip-1967.md
    bytes32 internal constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;
    bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;
    
    constructor(address logic, bytes memory initData) { 
        require(logic != address(0),"MonkeyProxy: wrong proxy contract address");
        StorageSlotUpgradeable.getAddressSlot(_ADMIN_SLOT).value = msg.sender;
        StorageSlotUpgradeable.getAddressSlot(_IMPLEMENTATION_SLOT).value = logic;
        (bool _ok, bytes memory returnData) = logic.delegatecall(initData);
        require(_ok, string(returnData));
    }
    
    // 基本是固定寫法
    fallback() external payable {
        address _impl = StorageSlotUpgradeable.getAddressSlot(_IMPLEMENTATION_SLOT).value;
        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)
                }
        }
    }

    function upgradeVersion(address newAddress) public {
        require(StorageSlotUpgradeable.getAddressSlot(_ADMIN_SLOT).value == msg.sender, "MonkeyProxy: only admin can be modified");
        StorageSlotUpgradeable.getAddressSlot(_IMPLEMENTATION_SLOT).value = newAddress;
    }
}

3、邏輯合約

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

import "@confluxfans/contracts/token/CRC721/extensions/CRC721Enumerable.sol";
import "@openzeppelin/contracts/access/AccessControlEnumerable.sol";
import "./Initializable.sol";

contract Monkey is AccessControlEnumerable, CRC721Enumerable, Initializable {
    using Strings for uint256;

    string private _name;
    string private _symbol;
    string private _uri;

    mapping(uint256 => uint256) public tokenFeatureCode;

    bytes32 public constant MINTER_ROLE = keccak256("MINTER_ROLE");

    constructor() public ERC721("", "") {}

    function initialize(string memory name, string memory symbol, string memory uri) public initializer {
        _setupRole(DEFAULT_ADMIN_ROLE, msg.sender);
        _setupRole(MINTER_ROLE, msg.sender);
        _name = name;
        _symbol  = symbol;
        setURI(uri);
    }

    function name() public view virtual override returns (string memory) {
        return _name;
    }

    function symbol() public view virtual override returns (string memory) {
        return _symbol;
    }

    function setURI(string memory newuri) public virtual {
        require(hasRole(DEFAULT_ADMIN_ROLE, _msgSender()), "Monkey: must have admin role to set URI");
        _uri = newuri;
    }

    function _baseURI() internal view virtual override returns (string memory) {
        return _uri;
    }

    function tokenURI(uint256 tokenId) public view virtual override(ERC721)  returns (string memory) {
        require(_exists(tokenId), "Monkey: nonexistent token");
        string memory baseURI = _baseURI();
        return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString(), ".json")) : "";
    }

    function mint(address to, uint256 tokenId) public virtual {
        require(hasRole(MINTER_ROLE, _msgSender()), "Monkey: must have minter role to mint");
        _mint(to, tokenId);
    }

    function burn(uint256 tokenId) public virtual {
        require(hasRole(MINTER_ROLE, _msgSender()), "Monkey: must have admin role to burn");
        _burn(tokenId);
    } 

    function transfer(address from, address to, uint256 tokenId) public virtual {
        require(hasRole(MINTER_ROLE, _msgSender()), "Monkey: must have admin role to transfer");
        _transfer(from, to, tokenId);
    }

    function setTokenFeatureCode(uint256 tokenId, uint256 featureCode) public virtual {
        require(hasRole(MINTER_ROLE, _msgSender()), "Monkey: must have minter role to mint");
        require(tokenFeatureCode[tokenId] == 0, "Monkey: token feature code is already set up");
        tokenFeatureCode[tokenId] = featureCode;
    }

    function addMinter(address minter) external {
        require(hasRole(DEFAULT_ADMIN_ROLE, _msgSender()), "Monkey: must have admin role to add minter");
        grantRole(MINTER_ROLE, minter);
    }

    function removeMinter(address minter) external {
        require(hasRole(DEFAULT_ADMIN_ROLE, _msgSender()), "Monkey: must have admin role to remove minter");
        revokeRole(MINTER_ROLE, minter);
    }

    /**
     * See {IERC165-supportsInterface}
     */
    function supportsInterface(bytes4 interfaceId) public view virtual override(AccessControlEnumerable, ERC721Enumerable) returns (bool) {
        return AccessControlEnumerable.supportsInterface(interfaceId) || ERC721Enumerable.supportsInterface(interfaceId);
    }
}

代碼中用到的工具類、庫都可以找到開源代碼,若有需要可點(diǎn)贊、留言,或私聊,小的會(huì)補(bǔ)充文章來源地址http://www.zghlxwxcb.cn/news/detail-796995.html

到了這里,關(guān)于conflux開發(fā)NFT智能合約(ERC721 & 工廠合約 & 可升級(jí)合約)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • 創(chuàng)建你自己的ERC-721代幣:一個(gè)簡單的以太坊游戲智能合約模板

    區(qū)塊鏈游戲正在成為一種新興的游戲形式,其中代幣化的游戲資產(chǎn)成為了一個(gè)重要的組成部分。今天,我們將介紹一個(gè)簡單的ERC-721智能合約模板,這個(gè)模板可以幫助你在以太坊區(qū)塊鏈上創(chuàng)建你自己的ERC-721代幣,讓你的游戲更有趣。 源碼下載 ERC-721是一種免費(fèi)的開放標(biāo)準(zhǔn),它

    2024年02月07日
    瀏覽(28)
  • 從零學(xué)習(xí)NFT(ERC721)

    文章大綱 什么是NFT. NFT有什么價(jià)值 市面上有什么NFT交易市場(chǎng) 如何實(shí)現(xiàn)自己的NFT(智能合約ERC721) NFT(Non-FungibleToken,非同質(zhì)化數(shù)字權(quán)益證明),每個(gè)NFT都是唯一不可分割,不可篡改,也不能互相替代的, 因此NFT與虛擬貨幣等同質(zhì)化代幣存在本質(zhì)不同,有數(shù)字商品的實(shí)際價(jià)值做支

    2024年02月15日
    瀏覽(21)
  • Solidity合約標(biāo)準(zhǔn)----ERC721

    Solidity合約標(biāo)準(zhǔn)----ERC721

    非同質(zhì)化token,它依賴于ERC-165 參照官方提供的案例,直接部署到remix,自動(dòng)下載依賴 https://docs.openzeppelin.com/contracts/4.x/erc721 部署成功后擁有以下功能 1. 設(shè)置待測(cè)試的4個(gè)賬戶 2. 鑄造NFT 3. 查詢NFT數(shù)量 4. 依據(jù)tokenid查詢NFT屬主 5.部分NFT委托授權(quán)第三者 6.查詢NFT是否已被授權(quán) 7.由第

    2024年02月02日
    瀏覽(53)
  • 以太坊區(qū)塊鏈ERC-721協(xié)議的實(shí)現(xiàn)(NFT代幣標(biāo)準(zhǔn))

    ERC-721是以太坊區(qū)塊鏈上用于NFT(非同質(zhì)化代幣)的一個(gè)標(biāo)準(zhǔn),是一種其他開發(fā)人員都遵守的模板或者格式,用于創(chuàng)建代表數(shù)字資產(chǎn)的獨(dú)特代幣,并且每個(gè)ERC-721代幣都是獨(dú)一無二的。使用統(tǒng)一的標(biāo)準(zhǔn)可以使合約代碼變得更簡單,復(fù)用性更強(qiáng)。ERC-721的出現(xiàn)促進(jìn)了NFT的創(chuàng)建,并在

    2024年02月04日
    瀏覽(23)
  • 以太坊數(shù)字資產(chǎn)的發(fā)行和流通:以太坊上的數(shù)字資產(chǎn)定義、ERC 20代幣合約標(biāo)準(zhǔn)、ERC 20標(biāo)準(zhǔn)接口、ERC 721代幣合約標(biāo)準(zhǔn)、

    以太坊設(shè)計(jì)的目標(biāo)就是讓各種數(shù)字資產(chǎn)能以智能合約的形式運(yùn)行在以太坊虛擬機(jī)上。目前,眾多智能合約中最廣泛應(yīng)用的是代幣合約(Token Contract)。是負(fù)責(zé)管理賬戶以及其擁有的代幣的智能合約,實(shí)質(zhì)可以理解為一張賬戶地址和對(duì)應(yīng)賬戶代幣余額的映射表。 即:代幣可以被

    2023年04月11日
    瀏覽(25)
  • 區(qū)塊鏈java開發(fā)智能合約nf(部署第一個(gè)NFT智能合約)

    手把手教你區(qū)塊鏈java開發(fā)智能合約nft-第二篇(部署第一個(gè)NFT智能合約) 剛搞區(qū)塊鏈開發(fā)真的是太累了,自己摸石頭過河,動(dòng)不動(dòng)就報(bào)錯(cuò),網(wǎng)上搜索錯(cuò)誤,一律看不出什么問題,或者報(bào)錯(cuò)的信息太少,問同事同事不鳥,問領(lǐng)導(dǎo),領(lǐng)導(dǎo)也煩,無奈,對(duì)于英文不好的我,只能被迫

    2024年02月12日
    瀏覽(30)
  • 智能合約NFT代幣系統(tǒng)的開發(fā):構(gòu)建數(shù)字資產(chǎn)生態(tài)

    智能合約NFT代幣系統(tǒng)的開發(fā):構(gòu)建數(shù)字資產(chǎn)生態(tài)

    隨著區(qū)塊鏈技術(shù)的迅速發(fā)展和數(shù)字資產(chǎn)市場(chǎng)的不斷壯大,智能合約NFT(非同質(zhì)化代幣)代幣系統(tǒng)成為了吸引眼球的焦點(diǎn)之一。本文將深入探討智能合約NFT代幣系統(tǒng)的開發(fā),以及它如何構(gòu)建數(shù)字資產(chǎn)生態(tài)。 引言 數(shù)字資產(chǎn)市場(chǎng)的迅速發(fā)展和區(qū)塊鏈技術(shù)的日益成熟,為智能合約N

    2024年04月10日
    瀏覽(22)
  • 手把手教你區(qū)塊鏈java開發(fā)智能合約nft-第五篇(鑄造第一個(gè)NFT)

    初學(xué)區(qū)塊鏈,那真叫一個(gè)痛苦并無助。如果沒有人帶你的話 今天寫的這篇是在前面文章基礎(chǔ)上寫的,初學(xué)區(qū)塊鏈的朋友建議先看我前面寫的文章 手把手教你區(qū)塊鏈java開發(fā)智能合約nft-第一篇 手把手教你區(qū)塊鏈java開發(fā)智能合約nft-第二篇(部署第一個(gè)NFT智能合約) 手把手教你

    2023年04月08日
    瀏覽(35)
  • 手把手教你區(qū)塊鏈java開發(fā)智能合約nft-第一篇

    手把手教你區(qū)塊鏈java開發(fā)智能合約nft-第一篇

    剛接觸區(qū)塊鏈開發(fā),使用java開發(fā),真的是太難了,自己一步步摸索,從新手小白一路碰壁,動(dòng)不動(dòng)就報(bào)錯(cuò),去網(wǎng)上搜索對(duì)應(yīng)錯(cuò)誤,還真什么都搜索不到,摸索了三四個(gè)月,今天終于有了一些進(jìn)展,今天開始分享出來,希望能幫助到需要的朋友 我作為一個(gè)java后端的程序員,不

    2024年01月23日
    瀏覽(27)
  • 智能合約 之 ERC-20介紹

    智能合約 之 ERC-20介紹

    ERC20 全稱為 Ethereum Request for Comment 20 ,是一種 智能合約標(biāo)準(zhǔn) ,用于以太坊網(wǎng)絡(luò)上的代幣發(fā)行 姊妹篇 - 如何部署ERC20 代幣化資產(chǎn),例如:USDT 是一種以美元為背書的ERC20代幣,每個(gè)USDT代幣都代表著1美元的價(jià)值,用戶可以隨時(shí)兌換成等值的美元 去中心化加以所,許多去中心化交

    2024年04月15日
    瀏覽(31)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包