是否可以让智能合约无需信任地实时了解 RSK pegnatories 的地址?

Posted

技术标签:

【中文标题】是否可以让智能合约无需信任地实时了解 RSK pegnatories 的地址?【英文标题】:Is it possible to make smart contract trustlessly know addresses of RSK pegnatories in real-time? 【发布时间】:2021-10-16 22:34:30 【问题描述】:

有没有办法使用 RSK 上的智能合约来查询当前所有 pegnatories 的地址?并且在不依赖 RSK 上的第 3 方预言机的情况下这样做?

对于上下文:这里的目的是让智能合约将部分费用产生的收入分配给 pegnatories,以促进 RSK 链的可持续性和安全性。

请注意,这是一个后续问题to this prior one about the RSK Bridge。

【问题讨论】:

注意到这个问题恰好有一个密切的投票。我的观点是,这是一个关于 API 的合法问题,可能在 javascript 或 Solidity 中给出答案。 【参考方案1】:
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.7.0 <0.9.0;

import "./Bridge.sol";

contract Federation 
    function getBridge() private pure returns (Bridge) 
        return Bridge(address(0x01000006));
    
    function getFederationSize() private view returns ( int256 ) 
        return getBridge().getFederationSize();
    
    function getFederatorPublicKeyOfType ( int256 index, string memory atype ) private view returns ( bytes memory ) 
        return getBridge().getFederatorPublicKeyOfType(index, atype);
    
    function getFederatorKeys() public view returns( bytes[] memory ) 
        int256 fedSize = getFederationSize();
        bytes[] memory keys = new bytes[](uint(fedSize));
        for (int256 i = 0; i < fedSize; i += 1) 
            keys[uint(i)] = getFederatorPublicKeyOfType(i, 'rsk');
        
        return keys;
    

要在链上(在智能合约中)执行此操作,您可以创建一个 Solidity 函数(上面代码中的getFederatorKeys()),它与 the web3.js answer from @bguiz 也就是调用getFederationSize,然后在循环中调用getFederatorPublicKeyOfType

注意,你需要修改Bridge.sol接口, 这样getFederatorPublicKeyOfType 的签名就有view

-  function getFederatorPublicKeyOfType ( int256 index, string calldata atype ) external returns ( bytes memory);
+  function getFederatorPublicKeyOfType ( int256 index, string calldata atype ) external view returns ( bytes memory);

以后可以像这样从 web3.js 调用这个函数

const fedPubKeys = await federation.methods.getFederatorKeys().call()

【讨论】:

【参考方案2】:

使用 web3.js 你应该能够做到以下几点:

let fedSize = await bridge.methods
    .getFederationSize().call();
let pks = [];
for (let i = 0; i < fedSize; i++) 
    let pk = await bridge.methods
        .getFederatorPublicKeyOfType(i, 'rsk').call();
    pks.push(pk);

let addresses = pks.map((pk) => (keccak256(pk).substr(12)));

要初始化 bridge 对象,您需要使用 ABI 进行 RSK Bridge 预编译,如 this earlier answer 中所述。

【讨论】:

以上是关于是否可以让智能合约无需信任地实时了解 RSK pegnatories 的地址?的主要内容,如果未能解决你的问题,请参考以下文章

为啥 web3.js 拒绝有效的 RSK 智能合约地址?

当我在 RSK Regtest 上开发时,如何提高块号?

你如何估计智能合约调用所需的 gas 量?

从 sCrypt 智能合约中访问区块链数据(无需预言机)

从 sCrypt 智能合约中访问区块链数据

智能合约与DAPPS