为啥这个 Solidity 函数在断言后返回 0?

Posted

技术标签:

【中文标题】为啥这个 Solidity 函数在断言后返回 0?【英文标题】:Why does this Solidity function return a 0 after assert?为什么这个 Solidity 函数在断言后返回 0? 【发布时间】:2018-09-24 21:58:09 【问题描述】:

我写了这个函数:

// Function to get an owned token's id by referencing the index of the user's owned tokens.
// ex: user has 5 tokens, tokenOfOwnerByIndex(owner,3) will give the id of the 4th token.
function tokenOfOwnerByIndex(address _owner, uint256 _index) public view returns (uint _tokenId) 
    // TODO: Make sure this works. Does not appear to throw when _index<balanceOf(_owner), which violates
    //       ERC721 compatibility.
    assert(_index<balanceOf(_owner)); // throw if outside range
    return ownedTokenIds[_owner][_index];

当 _index 为 2 且 _owner 使 balanceOf(_owner) 为 0 时,该函数在 Remix IDE 中返回 0。我的假设是它不会返回任何东西。我的问题是:

A) 为什么断言失败后返回 0?

B) 当我使用上述参数运行它时,如何让它不返回 0?

谢谢, 沃恩

【问题讨论】:

【参考方案1】:

删除我的另一个答案,因为它不正确。

view 函数中的错误处理条件不会冒泡到客户端。它们仅用于恢复区块链上的状态更改交易。对于 view 函数,处理将停止并返回指定返回类型的初始 0 值(uint 为 0,bool 为 false 等)。

因此,view 函数的错误处理必须在客户端进行。如果您需要能够区分有效的 0 返回值和错误,您可以执行以下操作:

function tokenOfOwnerByIndex(address _owner, uint256 _index) public view returns (uint, bool) 
    bool success = _index < balanceOf(_owner);
    return (ownedTokenIds[_owner][_index], success);

【讨论】:

如果您使用 tokenOfOwnerByIndex() 的自定义定义,那么它将与已发布的 ERC-721 标准不兼容。

以上是关于为啥这个 Solidity 函数在断言后返回 0?的主要内容,如果未能解决你的问题,请参考以下文章

为啥我的 Solidity 构造函数需要两个未在参数中指定的变量?

Solidity - 为啥公共 Struct 变量的默认 getter 不会返回 Struct 中的每个变量

为啥我在构造函数中填充的这个数组在构造函数返回后没有填充?

为啥这个函数总是返回0

以太坊python中不直观的solidity合约返回值

以太坊 Solidity 函数返回(returns)多个值 和 接收方式