Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to make smart contract trustlessly know addresses of RSK pegnatories in real-time?

Is there any way to use a smart contract on RSK to query the addresses of all current pegnatories? And to do so without relying on 3rd party oracles on RSK?

For context: The intention here is to make smart contract allocate a part of incomes generated from fees to the pegnatories to contribute to the RSK chain's sustainability and security.

Note that this is a follow up question to this prior one about the RSK Bridge.

like image 226
Jack Avatar asked Aug 13 '21 17:08

Jack


2 Answers

Using web3.js you should be able to do the following:

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)));

To initialise the bridge object, you'll need to use the ABI for RSK Bridge precompile, as described in this earlier answer.

like image 76
bguiz Avatar answered Oct 17 '22 04:10

bguiz


// 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;
    }
}

To do this on-chain (in a smart contract), you can create a Solidity function (getFederatorKeys() in the code above) that does the same thing as the web3.js answer from @bguiz which is to call getFederationSize, and then getFederatorPublicKeyOfType within a loop.

Note that you will need to modify Bridge.sol interface, such that the signature of getFederatorPublicKeyOfType has view

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

Later this function may be called from web3.js like this

const fedPubKeys = await federation.methods.getFederatorKeys().call()
like image 21
Aleks Shenshin Avatar answered Oct 17 '22 03:10

Aleks Shenshin