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

Solidity ERC777標(biāo)準(zhǔn)

這篇具有很好參考價值的文章主要介紹了Solidity ERC777標(biāo)準(zhǔn)。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點(diǎn)擊"舉報違法"按鈕提交疑問。

Openzeppelin ERC777標(biāo)準(zhǔn)實(shí)現(xiàn)

ERC777是一種能夠向后兼容ERC20的代幣標(biāo)準(zhǔn),與ERC20的區(qū)別在于其新功能:openrater和hooks。


一、Operator

operator可以代理用戶進(jìn)行transfer、mint、burn操作,并且沒有allowance的限制。應(yīng)用場景舉例:
1.有些朋友有多個以太坊錢包地址,不管是用于薅空投還是分批管理自己的代幣資產(chǎn);這樣的情況下有時候會遇到這樣的情況,即多個地址中只有一個地址具有ETH,別的地址都沒有ETH,當(dāng)需要對沒有ETH的錢包地址進(jìn)行代幣交易或者轉(zhuǎn)賬時候,一般情況下只能通過向這些地址發(fā)送一些ETH作為手續(xù)費(fèi),然后進(jìn)行轉(zhuǎn)賬操作,這樣的過程相對而言繁瑣,且會耗費(fèi)一定的手續(xù)費(fèi)。而ERC777的運(yùn)營商功能允許某個地址充作其它地址的運(yùn)營商,即多個地址的持有人可以將自己唯一一個有ETH 的地址作為其它地址的運(yùn)營商,當(dāng)其它地址需要轉(zhuǎn)移代幣時,可以直接由有ETH的地址代為操作,及由運(yùn)營商地址控制,且手續(xù)費(fèi)由運(yùn)營商地址出,實(shí)際轉(zhuǎn)移代幣的地址無需支付手續(xù)費(fèi),這樣的情況大大降低了重復(fù)多個錢包地址之間切換的冗余操作。

2.又如,某區(qū)塊鏈公司的老板使用某種基于ERC777的A代幣作為工資發(fā)放,公司賬戶一共有500萬的A代幣,而經(jīng)過人事的計算,本月共應(yīng)發(fā)總工資為200萬代幣A,那么公司老板就可以將財務(wù)的以太坊錢包地址作為運(yùn)營商,并授權(quán)200萬 A代幣的使用權(quán)限,那么財務(wù)便有權(quán)限使用公司地址500萬中的200萬 A代幣,并且對于公司來說,其余的金額是安全的。

operator包括兩種類型:defaultOperators和operators,即合約初始默認(rèn)添加的operator和自定義的operator,defaultOperators在合約構(gòu)建時必須定義,而operators可以通過調(diào)用函數(shù)來授權(quán)。

二、Hooks

hooks是與ERC777的sender和receipient綁定的函數(shù),發(fā)送和接收ERC777資產(chǎn)需分別調(diào)用IERC777Sender接口的tokensToSend的函數(shù),以及IERC777Recipient接口的tokensReceived函數(shù)。而IERC777Sender和IERC777Recipient接口不需要發(fā)送方和接收方地址本身實(shí)現(xiàn),而可以通過ERC1820注冊表來調(diào)用實(shí)現(xiàn)了接口的合約。也就是說無論外部地址和合約地址,都可以通過ERC1820標(biāo)準(zhǔn)來注冊想要調(diào)用的hooks函數(shù)。文章來源地址http://www.zghlxwxcb.cn/news/detail-566522.html


三、接口

FUNCTIONS
name()

symbol()

granularity()//代幣的粒度,當(dāng)設(shè)為1時和ERC20代幣相同

totalSupply()

balanceOf(owner)

send(recipient, amount, data)

burn(amount, data)

isOperatorFor(operator, tokenHolder)//判斷operator地址是否是tokenHolder的operator

authorizeOperator(operator)//授權(quán)operator地址為當(dāng)前msg.sender的operator

revokeOperator(operator)//取消operator授權(quán)

defaultOperators()//輸出defaultOperators的地址列表

operatorSend(sender, recipient, amount, data, operatorData)//operator代理sender調(diào)用send函數(shù),同時可以傳入operator想要傳入的數(shù)據(jù)operatorData

operatorBurn(account, amount, data, operatorData)//operator代理account調(diào)用burn函數(shù),同時可以傳入operator想要傳入的數(shù)據(jù)operatorData

四、實(shí)現(xiàn)

//繼承了Context合約,context合約提供了_msgSender()和_msgData()函數(shù),在metatransaction中,往往需要找到最初始的調(diào)用者地址,而不是代理的地址,所以可以通過_msgSender()實(shí)現(xiàn)而不是簡單調(diào)用msg.sender
contract ERC777 is Context, IERC777, IERC20 {
    using Address for address;
	//IERC1820Registry合約地址
    IERC1820Registry internal constant _ERC1820_REGISTRY = IERC1820Registry(0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24);

    mapping(address => uint256) private _balances;

    uint256 private _totalSupply;

    string private _name;
    string private _symbol;

	//得到合約名的哈希,通過keccak256哈希來查詢該接口
    bytes32 private constant _TOKENS_SENDER_INTERFACE_HASH = keccak256("ERC777TokensSender");
    bytes32 private constant _TOKENS_RECIPIENT_INTERFACE_HASH = keccak256("ERC777TokensRecipient");

    // This isn't ever read from - it's only used to respond to the defaultOperators query.
    address[] private _defaultOperatorsArray;

    // Immutable, but accounts may revoke them (tracked in __revokedDefaultOperators).
    mapping(address => bool) private _defaultOperators;

    // For each account, a mapping of its operators and revoked default operators.
    mapping(address => mapping(address => bool)) private _operators;
    mapping(address => mapping(address => bool)) private _revokedDefaultOperators;

    // ERC20-allowances
    mapping(address => mapping(address => uint256)) private _allowances;

    /**
     * @dev `defaultOperators` may be an empty array.
     */
    constructor(
        string memory name_,
        string memory symbol_,
        address[] memory defaultOperators_
    ) {
        _name = name_;
        _symbol = symbol_;

        _defaultOperatorsArray = defaultOperators_;
        for (uint256 i = 0; i < defaultOperators_.length; i++) {
            _defaultOperators[defaultOperators_[i]] = true;
        }

        // register interfaces
        _ERC1820_REGISTRY.setInterfaceImplementer(address(this), keccak256("ERC777Token"), address(this));
        _ERC1820_REGISTRY.setInterfaceImplementer(address(this), keccak256("ERC20Token"), address(this));
    }

    /**
     * @dev See {IERC777-name}.
     */
    function name() public view virtual override returns (string memory) {
        return _name;
    }

    /**
     * @dev See {IERC777-symbol}.
     */
    function symbol() public view virtual override returns (string memory) {
        return _symbol;
    }

    /**
     * @dev See {ERC20-decimals}.
     *
     * Always returns 18, as per the
     * [ERC777 EIP](https://eips.ethereum.org/EIPS/eip-777#backward-compatibility).
     */
    function decimals() public pure virtual returns (uint8) {
        return 18;
    }

    /**
     * @dev See {IERC777-granularity}.
     *
     * This implementation always returns `1`.
     */
    function granularity() public view virtual override returns (uint256) {
        return 1;
    }

    /**
     * @dev See {IERC777-totalSupply}.
     */
    function totalSupply() public view virtual override(IERC20, IERC777) returns (uint256) {
        return _totalSupply;
    }

    /**
     * @dev Returns the amount of tokens owned by an account (`tokenHolder`).
     */
    function balanceOf(address tokenHolder) public view virtual override(IERC20, IERC777) returns (uint256) {
        return _balances[tokenHolder];
    }

    /**
     * @dev See {IERC777-send}.
     *
     * Also emits a {IERC20-Transfer} event for ERC20 compatibility.
     */
    function send(
        address recipient,
        uint256 amount,
        bytes memory data
    ) public virtual override {
        _send(_msgSender(), recipient, amount, data, "", true);
    }

    /**
     * @dev See {IERC20-transfer}.
     *
     * Unlike `send`, `recipient` is _not_ required to implement the {IERC777Recipient}
     * interface if it is a contract.
     *
     * Also emits a {Sent} event.
     */
    function transfer(address recipient, uint256 amount) public virtual override returns (bool) {
        _send(_msgSender(), recipient, amount, "", "", false);
        return true;
    }

    /**
     * @dev See {IERC777-burn}.
     *
     * Also emits a {IERC20-Transfer} event for ERC20 compatibility.
     */
    function burn(uint256 amount, bytes memory data) public virtual override {
        _burn(_msgSender(), amount, data, "");
    }

    /**
     * @dev See {IERC777-isOperatorFor}.
     */
    function isOperatorFor(address operator, address tokenHolder) public view virtual override returns (bool) {
        return
            operator == tokenHolder ||
            (_defaultOperators[operator] && !_revokedDefaultOperators[tokenHolder][operator]) ||
            _operators[tokenHolder][operator];
    }

    /**
     * @dev See {IERC777-authorizeOperator}.
     */
    function authorizeOperator(address operator) public virtual override {
        require(_msgSender() != operator, "ERC777: authorizing self as operator");

        if (_defaultOperators[operator]) {
            delete _revokedDefaultOperators[_msgSender()][operator];
        } else {
            _operators[_msgSender()][operator] = true;
        }

        emit AuthorizedOperator(operator, _msgSender());
    }

    /**
     * @dev See {IERC777-revokeOperator}.
     */
    function revokeOperator(address operator) public virtual override {
        require(operator != _msgSender(), "ERC777: revoking self as operator");

        if (_defaultOperators[operator]) {
            _revokedDefaultOperators[_msgSender()][operator] = true;
        } else {
            delete _operators[_msgSender()][operator];
        }

        emit RevokedOperator(operator, _msgSender());
    }

    /**
     * @dev See {IERC777-defaultOperators}.
     */
    function defaultOperators() public view virtual override returns (address[] memory) {
        return _defaultOperatorsArray;
    }

    /**
     * @dev See {IERC777-operatorSend}.
     *
     * Emits {Sent} and {IERC20-Transfer} events.
     */
    function operatorSend(
        address sender,
        address recipient,
        uint256 amount,
        bytes memory data,
        bytes memory operatorData
    ) public virtual override {
        require(isOperatorFor(_msgSender(), sender), "ERC777: caller is not an operator for holder");
        _send(sender, recipient, amount, data, operatorData, true);
    }

    /**
     * @dev See {IERC777-operatorBurn}.
     *
     * Emits {Burned} and {IERC20-Transfer} events.
     */
    function operatorBurn(
        address account,
        uint256 amount,
        bytes memory data,
        bytes memory operatorData
    ) public virtual override {
        require(isOperatorFor(_msgSender(), account), "ERC777: caller is not an operator for holder");
        _burn(account, amount, data, operatorData);
    }

    /**
     * @dev See {IERC20-allowance}.
     *
     * Note that operator and allowance concepts are orthogonal: operators may
     * not have allowance, and accounts with allowance may not be operators
     * themselves.
     */
    function allowance(address holder, address spender) public view virtual override returns (uint256) {
        return _allowances[holder][spender];
    }

    /**
     * @dev See {IERC20-approve}.
     *
     * NOTE: If `value` is the maximum `uint256`, the allowance is not updated on
     * `transferFrom`. This is semantically equivalent to an infinite approval.
     *
     * Note that accounts cannot have allowance issued by their operators.
     */
    function approve(address spender, uint256 value) public virtual override returns (bool) {
        address holder = _msgSender();
        _approve(holder, spender, value);
        return true;
    }

    /**
     * @dev See {IERC20-transferFrom}.
     *
     * NOTE: Does not update the allowance if the current allowance
     * is the maximum `uint256`.
     *
     * Note that operator and allowance concepts are orthogonal: operators cannot
     * call `transferFrom` (unless they have allowance), and accounts with
     * allowance cannot call `operatorSend` (unless they are operators).
     *
     * Emits {Sent}, {IERC20-Transfer} and {IERC20-Approval} events.
     */
    function transferFrom(
        address holder,
        address recipient,
        uint256 amount
    ) public virtual override returns (bool) {
        address spender = _msgSender();
        _spendAllowance(holder, spender, amount);
        _send(holder, recipient, amount, "", "", false);
        return true;
    }

    /**
     * @dev Creates `amount` tokens and assigns them to `account`, increasing
     * the total supply.
     *
     * If a send hook is registered for `account`, the corresponding function
     * will be called with the caller address as the `operator` and with
     * `userData` and `operatorData`.
     *
     * See {IERC777Sender} and {IERC777Recipient}.
     *
     * Emits {Minted} and {IERC20-Transfer} events.
     *
     * Requirements
     *
     * - `account` cannot be the zero address.
     * - if `account` is a contract, it must implement the {IERC777Recipient}
     * interface.
     */
    function _mint(
        address account,
        uint256 amount,
        bytes memory userData,
        bytes memory operatorData
    ) internal virtual {
        _mint(account, amount, userData, operatorData, true);
    }

    /**
     * @dev Creates `amount` tokens and assigns them to `account`, increasing
     * the total supply.
     *
     * If `requireReceptionAck` is set to true, and if a send hook is
     * registered for `account`, the corresponding function will be called with
     * `operator`, `data` and `operatorData`.
     *
     * See {IERC777Sender} and {IERC777Recipient}.
     *
     * Emits {Minted} and {IERC20-Transfer} events.
     *
     * Requirements
     *
     * - `account` cannot be the zero address.
     * - if `account` is a contract, it must implement the {IERC777Recipient}
     * interface.
     */
    function _mint(
        address account,
        uint256 amount,
        bytes memory userData,
        bytes memory operatorData,
        bool requireReceptionAck
    ) internal virtual {
        require(account != address(0), "ERC777: mint to the zero address");

        address operator = _msgSender();

        _beforeTokenTransfer(operator, address(0), account, amount);

        // Update state variables
        _totalSupply += amount;
        _balances[account] += amount;

        _callTokensReceived(operator, address(0), account, amount, userData, operatorData, requireReceptionAck);

        emit Minted(operator, account, amount, userData, operatorData);
        emit Transfer(address(0), account, amount);
    }

    /**
     * @dev Send tokens
     * @param from address token holder address
     * @param to address recipient address
     * @param amount uint256 amount of tokens to transfer
     * @param userData bytes extra information provided by the token holder (if any)
     * @param operatorData bytes extra information provided by the operator (if any)
     * @param requireReceptionAck if true, contract recipients are required to implement ERC777TokensRecipient
     */
    function _send(
        address from,
        address to,
        uint256 amount,
        bytes memory userData,
        bytes memory operatorData,
        bool requireReceptionAck
    ) internal virtual {
        require(from != address(0), "ERC777: transfer from the zero address");
        require(to != address(0), "ERC777: transfer to the zero address");

        address operator = _msgSender();

        _callTokensToSend(operator, from, to, amount, userData, operatorData);

        _move(operator, from, to, amount, userData, operatorData);

        _callTokensReceived(operator, from, to, amount, userData, operatorData, requireReceptionAck);
    }

    /**
     * @dev Burn tokens
     * @param from address token holder address
     * @param amount uint256 amount of tokens to burn
     * @param data bytes extra information provided by the token holder
     * @param operatorData bytes extra information provided by the operator (if any)
     */
    function _burn(
        address from,
        uint256 amount,
        bytes memory data,
        bytes memory operatorData
    ) internal virtual {
        require(from != address(0), "ERC777: burn from the zero address");

        address operator = _msgSender();

        _callTokensToSend(operator, from, address(0), amount, data, operatorData);

        _beforeTokenTransfer(operator, from, address(0), amount);

        // Update state variables
        uint256 fromBalance = _balances[from];
        require(fromBalance >= amount, "ERC777: burn amount exceeds balance");
        unchecked {
            _balances[from] = fromBalance - amount;
        }
        _totalSupply -= amount;

        emit Burned(operator, from, amount, data, operatorData);
        emit Transfer(from, address(0), amount);
    }

    function _move(
        address operator,
        address from,
        address to,
        uint256 amount,
        bytes memory userData,
        bytes memory operatorData
    ) private {
        _beforeTokenTransfer(operator, from, to, amount);

        uint256 fromBalance = _balances[from];
        require(fromBalance >= amount, "ERC777: transfer amount exceeds balance");
        //unchecked用來減少gas消耗,因?yàn)?.8.0版本以后的solidity默認(rèn)檢查over/underflow,
        //而如果能保證計算不會over/underflow或者已經(jīng)添加過檢查的邏輯,則可以使用unchecked關(guān)鍵字包裹跳過溢出check
        unchecked {
            _balances[from] = fromBalance - amount;
        }
        _balances[to] += amount;

        emit Sent(operator, from, to, amount, userData, operatorData);
        emit Transfer(from, to, amount);
    }

    /**
     * @dev See {ERC20-_approve}.
     *
     * Note that accounts cannot have allowance issued by their operators.
     */
    function _approve(
        address holder,
        address spender,
        uint256 value
    ) internal virtual {
        require(holder != address(0), "ERC777: approve from the zero address");
        require(spender != address(0), "ERC777: approve to the zero address");

        _allowances[holder][spender] = value;
        emit Approval(holder, spender, value);
    }

    /**
     * @dev Call from.tokensToSend() if the interface is registered
     * @param operator address operator requesting the transfer
     * @param from address token holder address
     * @param to address recipient address
     * @param amount uint256 amount of tokens to transfer
     * @param userData bytes extra information provided by the token holder (if any)
     * @param operatorData bytes extra information provided by the operator (if any)
     */
    function _callTokensToSend(
        address operator,
        address from,
        address to,
        uint256 amount,
        bytes memory userData,
        bytes memory operatorData
    ) private {
        address implementer = _ERC1820_REGISTRY.getInterfaceImplementer(from, _TOKENS_SENDER_INTERFACE_HASH);
        if (implementer != address(0)) {
            IERC777Sender(implementer).tokensToSend(operator, from, to, amount, userData, operatorData);
        }
    }

    /**
     * @dev Call to.tokensReceived() if the interface is registered. Reverts if the recipient is a contract but
     * tokensReceived() was not registered for the recipient
     * @param operator address operator requesting the transfer
     * @param from address token holder address
     * @param to address recipient address
     * @param amount uint256 amount of tokens to transfer
     * @param userData bytes extra information provided by the token holder (if any)
     * @param operatorData bytes extra information provided by the operator (if any)
     * @param requireReceptionAck if true, contract recipients are required to implement ERC777TokensRecipient
     */
    function _callTokensReceived(
        address operator,
        address from,
        address to,
        uint256 amount,
        bytes memory userData,
        bytes memory operatorData,
        bool requireReceptionAck
    ) private {
        address implementer = _ERC1820_REGISTRY.getInterfaceImplementer(to, _TOKENS_RECIPIENT_INTERFACE_HASH);
        if (implementer != address(0)) {
            IERC777Recipient(implementer).tokensReceived(operator, from, to, amount, userData, operatorData);
        } else if (requireReceptionAck) {
            require(!to.isContract(), "ERC777: token recipient contract has no implementer for ERC777TokensRecipient");
        }
    }

    /**
     * @dev Updates `owner` s allowance for `spender` based on spent `amount`.
     *
     * Does not update the allowance amount in case of infinite allowance.
     * Revert if not enough allowance is available.
     *
     * Might emit an {IERC20-Approval} event.
     */
    function _spendAllowance(
        address owner,
        address spender,
        uint256 amount
    ) internal virtual {
        uint256 currentAllowance = allowance(owner, spender);
        if (currentAllowance != type(uint256).max) {
            require(currentAllowance >= amount, "ERC777: insufficient allowance");
            unchecked {
                _approve(owner, spender, currentAllowance - amount);
            }
        }
    }

    /**
     * @dev Hook that is called before any token transfer. This includes
     * calls to {send}, {transfer}, {operatorSend}, minting and burning.
     *
     * Calling conditions:
     *
     * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens
     * will be to transferred to `to`.
     * - when `from` is zero, `amount` tokens will be minted for `to`.
     * - when `to` is zero, `amount` of ``from``'s tokens will be burned.
     * - `from` and `to` are never both zero.
     *
     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
     */
    function _beforeTokenTransfer(
        address operator,
        address from,
        address to,
        uint256 amount
    ) internal virtual {}
}

到了這里,關(guān)于Solidity ERC777標(biāo)準(zhǔn)的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

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

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

相關(guān)文章

  • 智能合約安全分析,針對 ERC777 任意調(diào)用合約 Hook 攻擊

    智能合約安全分析,針對 ERC777 任意調(diào)用合約 Hook 攻擊

    Safful發(fā)現(xiàn)了一個有趣的錯誤,有可能成為一些 DeFi 項(xiàng)目的攻擊媒介。這個錯誤尤其與著名的 ERC777 代幣標(biāo)準(zhǔn)有關(guān)。此外,它不僅僅是眾所周知的黑客中常見的簡單的重入問題。 這篇文章對 ERC777 進(jìn)行了全面的解釋,涵蓋了所有必要的細(xì)節(jié)。深入研究 ERC777 代幣的具體細(xì)節(jié)的資源

    2024年02月04日
    瀏覽(26)
  • 基于openzeppelin編寫solidity可升級的智能合約

    基于openzeppelin編寫solidity可升級的智能合約

    ????????現(xiàn)代軟件的設(shè)計原則是“敏捷開發(fā),迅速迭代”,功能升級或bug修復(fù)是所有軟件系統(tǒng)都要面對的問題。甚至可以說軟件質(zhì)量在很大程度上依賴于升級和修補(bǔ)源代碼的能力。當(dāng)然Dapp(去中心化應(yīng)用)也不例外,尤其Dapp一切都是透明的,這使得任何級別的bug都會被成

    2024年01月18日
    瀏覽(26)
  • 使用VSCode引用OpenZeppelin庫編寫solidity合約時報錯解決辦法

    使用VSCode引用OpenZeppelin庫編寫solidity合約時報錯解決辦法

    本文針對的 調(diào)試 Solidity 代碼的插件為 最近在使用 VS Code 編寫 solidity 合約的時候,引用 OpenZeppelin 庫之后出現(xiàn)了如下錯誤: 報錯為: Expected string literal (path), \\\"*\\\" or alias list. 或者還有可能會出現(xiàn)這樣的錯誤: 報錯為: Source \\\"@openzeppelin/contracts/token/ERC721/ERC721.sol\\\" not found: File i

    2024年02月02日
    瀏覽(30)
  • web3 solidity 基礎(chǔ) ERC20 大白話搞懂

    web3 solidity 基礎(chǔ) ERC20 大白話搞懂

    ERC20 是 eth 的一個標(biāo)準(zhǔn),怎么理解標(biāo)準(zhǔn)一詞呢? 標(biāo)準(zhǔn)是大家遵循的一個協(xié)議,根據(jù)這個協(xié)議大家都知道該怎么去做,例如去吃飯的時候人多,你就需要排隊(duì),然后去窗口跟阿姨說你要吃什么,阿姨就會幫你打;若你不準(zhǔn)守這個標(biāo)準(zhǔn),直接沖進(jìn)后廚,翻開泔水,大喊著我要吃飯

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

    2023年04月11日
    瀏覽(26)
  • 區(qū)塊鏈 | ERC721 標(biāo)準(zhǔn)

    目錄 正文 1? ERC721 接口 事件 方法 2? ERC165 接口 3? 可選實(shí)現(xiàn)接口:ERC721Metadata 4? 可選實(shí)現(xiàn)接口:ERC721Enumerable 補(bǔ)充說明 1? NTF IDs 2? 與 ERC-20 的兼容性 3? 交易、挖礦、銷毀 ?? 原文: 剖析非同質(zhì)化代幣 ERC721 標(biāo)準(zhǔn) ?? 寫在前面: 本文屬搬運(yùn)博客,自己留存學(xué)習(xí)。 ERC721 作為

    2024年04月28日
    瀏覽(22)
  • ERC721標(biāo)準(zhǔn)與加密貓

    2017 年 11 月 28 日,“加密貓”游戲出現(xiàn)在互聯(lián)網(wǎng)上。這是基于以太坊的 ERC721 標(biāo)準(zhǔn)(不可互換通證)發(fā)行的加密數(shù)字寵物,每一只貓咪各不相同。 加密貓的正式中文名叫“謎戀貓”,游戲的官網(wǎng)稱這些加密貓是“可收藏、可繁殖、討人喜歡的”。用戶可以用以太幣換購這種貓

    2024年01月16日
    瀏覽(21)
  • 以太坊的演變:EIP、ERC 概念以及革命性的 ERC20、ERC721 和 ERC115 標(biāo)準(zhǔn)

    以太坊改進(jìn)提案(EIP)代表了以太坊區(qū)塊鏈內(nèi)協(xié)作進(jìn)步的頂峰。它們是技術(shù)文章或提案,描述對以太坊網(wǎng)絡(luò)的建議更改或增強(qiáng)。 這些文檔經(jīng)過精心制作,呈現(xiàn)了新的功能、流程或環(huán)境,在任何形式的采用或?qū)嵤┲岸夹枰鐓^(qū)的審查。 至關(guān)重要的是要認(rèn)識到改進(jìn)提案的概念

    2024年04月11日
    瀏覽(28)
  • 代幣標(biāo)準(zhǔn)--ERC1155協(xié)議源碼解析

    ERC1155結(jié)合了ERC20和ERC721的能力,這是一個標(biāo)準(zhǔn)接口,支持開發(fā)同質(zhì)化的、半同質(zhì)化的、非同質(zhì)化的代幣和其他配置的通用智能合約。 TransferSingle事件 TransferBatch事件 ApprovalForAll事件 URI事件 balanceOf函數(shù) balanceOfBatch函數(shù) setApprovalForAll函數(shù) isApprovedForAll函數(shù) safeTransferFrom函數(shù) safeBa

    2023年04月11日
    瀏覽(24)
  • 探索 ERC721A:下一代NFT智能合約標(biāo)準(zhǔn)

    項(xiàng)目地址:https://gitcode.com/chiru-labs/ERC721A 在區(qū)塊鏈?zhǔn)澜缰?,非同質(zhì)化代幣(NFT)已經(jīng)成為了一種創(chuàng)新的藝術(shù)形式和數(shù)字資產(chǎn)所有權(quán)的代表。隨著市場的發(fā)展,對于更高效、更安全的NFT發(fā)行協(xié)議的需求日益增長。這就是我們今天要介紹的 ERC721A 出現(xiàn)的原因。這是一個針對以太坊網(wǎng)

    2024年03月27日
    瀏覽(19)

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

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

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

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包