【问题标题】:how can we get token holders from token?我们如何从代币中获得代币持有者?
【发布时间】:2021-08-20 09:59:51
【问题描述】:

我已经创建了自己的 ERC-20 代币 (AJR) 并部署在以太坊私有节点上,现在我想按代币名称列出所有交易。

另外,我需要使用合约地址或代币名称列出所有代币持有者。

我尝试使用 web3 获取,但我只得到符号、名称、总供应量等,而不是代币持有者或交易

下面是我的示例代码:

从 web3 导入 web3

Web3 = Web3(Web3.HTTPProvider('http://127.0.0.1:8545'))

contract_instance = Web3.eth.contract(contract_address, abi=abi)

打印(contract_instance.functions.name().call())

【问题讨论】:

    标签: smartcontracts web3 go-ethereum erc20 web3py


    【解决方案1】:

    代币持有者不能通过 RPC 协议和 RPC 包装器(例如 Web3)直接获得。

    关于代币持有者的信息存储在代币合约(或其一些依赖项)中的区块链上,通常以映射的形式。这意味着您不能只遍历所有持有人,而是需要知道地址并询问他们的余额。

    // the key is the holder address, the value is their token amount
    mapping (address => uint256) public balanceOf;
    

    但是 - ERC-20 标准定义了在发生转移时令牌合约应该发出的 Transfer() 事件。

    mapping (address => uint256) public balanceOf;
    
    event Transfer(address indexed _from, address indexed _to, uint256 _amount);
    
    function transfer(address _to, uint256 _amount) external returns (bool) {
        balanceOf[msg.sender] -= _amount;
        balanceOf[_to] += _amount;
        emit Transfer(msg.sender, _to, _amount);
        return true;
    }
    

    因此,您需要根据此代币合约发出的所有Transfer() 事件日志来构建和维护持有人数据库。收集过去的事件日志以构建历史数据,并订阅新发出的日志以使其保持最新。然后,您可以将所有这些原始转账数据汇总为“地址 => 当前余额”的形式,并仅过滤可搜索数据库中余额为非零的地址。

    文档:

    • 在 Web3 中获取过去的事件日志 - link
    • 订阅 Web3 中的新事件日志 - link

    区块链浏览器实际上使用了相同的方式。他们扫描每笔交易以查找Transfer() 事件,如果发射器是代币合约,他们会更新其单独数据库中的代币余额。所有持有者的列表(来自这个单独的数据库)然后显示在令牌详细信息页面上。

    【讨论】:

    • 感谢@Petr Hejda 的回复,但我有一个疑问,我正在使用 MetaMask 转移代币,那么如何跟踪通过特定合约地址完成的交易?
    • @TrimantraSoftwareSolution 您可以通过 MetaMask 实现的 Ethereum 提供程序 API 获取用户地址。然后就像我回答的后半部分一样:获取令牌发出的过去事件日志。由于您不需要所有转移,而只需要来自/到特定地址,因此您可以仅过滤包含 Transfer() 事件 (topics[0]) 的主题,并且具有发件人 (topics[1]) 或收件人 (topics[2])用户地址。然后,您可以从这些事件日志中构建单独的(可搜索和可聚合的)数据库。
    猜你喜欢
    • 2021-01-04
    • 2019-03-07
    • 2023-02-03
    • 1970-01-01
    • 2021-07-30
    • 2019-11-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多