5

有没有办法让 RSK 上的智能合约不依赖于受信任的预言机来获取比特币上的链上数据?

我刚刚发现了一个名为 Open Bitcoin blockchain oracle ( RSKIP220 ) 的提案,该提案将从 IRIS 升级中实施,但在其上找不到任何资源。有人知道我在哪里可以找到它吗?

提及 RSKIP220 的博客文章:https ://blog.rsk.co/noticia/​​iris-v3-0-0-is-here-what-you-need-to-know-about-rsk-upcoming-network-upgrade/

4

2 回答 2

5

这是一个如何使用 Bridge 方法访问比特币块的工作示例。此代码已在 RSK 测试网中进行了测试。

桥接.sol:

// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.7.0 <0.9.0;

interface Bridge {
  function getBtcBlockchainBestChainHeight (  ) external view returns ( int );
  function getStateForBtcReleaseClient (  ) external view returns ( bytes memory);
  function getStateForDebugging (  ) external view returns ( bytes memory  );
  function getBtcBlockchainInitialBlockHeight (  ) external view returns ( int );
  function getBtcBlockchainBlockHashAtDepth ( int256 depth ) external view returns ( bytes memory );
  function getBtcTxHashProcessedHeight ( string calldata hash ) external view returns ( int64 );
  function isBtcTxHashAlreadyProcessed ( string calldata hash ) external view returns ( bool );
  function getFederationAddress (  ) external view returns ( string memory );
  function registerBtcTransaction ( bytes calldata atx, int256 height, bytes calldata pmt ) external;
  function addSignature ( bytes calldata pubkey, bytes[] calldata signatures, bytes calldata txhash ) external;
  function receiveHeaders ( bytes[] calldata blocks ) external;
  function receiveHeader ( bytes calldata ablock ) external returns ( int256 );
  function getFederationSize (  ) external view returns ( int256 );
  function getFederationThreshold (  ) external view returns ( int256 );
  function getFederatorPublicKey ( int256 index ) external view returns ( bytes memory);
  function getFederatorPublicKeyOfType ( int256 index, string calldata atype ) external returns ( bytes memory);
  function getFederationCreationTime (  ) external view returns ( int256 );
  function getFederationCreationBlockNumber (  ) external view returns ( int256 );
  function getRetiringFederationAddress (  ) external view returns ( string memory );
  function getRetiringFederationSize (  ) external view returns ( int256 );
  function getRetiringFederationThreshold (  ) external view returns ( int256 );
  function getRetiringFederatorPublicKey ( int256 index ) external view returns ( bytes memory);
  function getRetiringFederatorPublicKeyOfType ( int256 index,string calldata atype ) external view returns ( bytes memory);
  function getRetiringFederationCreationTime (  ) external view returns ( int256 );
  function getRetiringFederationCreationBlockNumber (  ) external view returns ( int256 );
  function createFederation (  ) external returns ( int256 );
  function addFederatorPublicKey ( bytes calldata  key ) external returns ( int256 );
  function addFederatorPublicKeyMultikey ( bytes calldata btcKey, bytes calldata rskKey, bytes calldata mstKey ) external returns ( int256 );
  function commitFederation ( bytes calldata hash ) external returns ( int256 );
  function rollbackFederation (  ) external returns ( int256 );
  function getPendingFederationHash (  ) external view returns ( bytes memory);
  function getPendingFederationSize (  ) external view  returns ( int256 );
  function getPendingFederatorPublicKey ( int256 index ) external view returns ( bytes memory);
  function getPendingFederatorPublicKeyOfType ( int256 index, string calldata atype ) external view returns ( bytes memory);
  function getLockWhitelistSize (  ) external view returns ( int256 );
  function getLockWhitelistAddress ( int256 index ) external view returns ( string memory);
  function getLockWhitelistEntryByAddress ( string calldata aaddress ) external view  returns ( int256 );
  function addLockWhitelistAddress ( string calldata aaddress, int256 maxTransferValue ) external returns ( int256 );
  function addOneOffLockWhitelistAddress ( string calldata aaddress, int256 maxTransferValue ) external returns ( int256 );
  function addUnlimitedLockWhitelistAddress ( string calldata aaddress ) external returns ( int256 ); 
  function removeLockWhitelistAddress ( string calldata aaddress ) external returns ( int256 );
  function setLockWhitelistDisableBlockDelay ( int256 disableDelay ) external returns ( int256 );
  function getFeePerKb (  ) external view returns ( int256 );
  function voteFeePerKbChange ( int256 feePerKb ) external returns ( int256 );
  function updateCollections (  ) external;
  function getMinimumLockTxValue (  ) external view returns ( int256 );
  function getBtcTransactionConfirmations ( bytes32  txHash, bytes32 blockHash, uint256 merkleBranchPath, bytes32[] calldata merkleBranchHashes ) external view returns ( int256 );
  function getLockingCap (  ) external view returns ( int256 );
  function increaseLockingCap ( int256 newLockingCap ) external returns ( bool );
  function registerBtcCoinbaseTransaction ( bytes calldata btcTxSerialized, bytes32 blockHash, bytes calldata pmtSerialized, bytes32 witnessMerkleRoot, bytes32 witnessReservedValue ) external;
  function hasBtcBlockCoinbaseTransactionInformation ( bytes32 blockHash ) external returns ( bool );
  function registerFastBridgeBtcTransaction ( bytes calldata btcTxSerialized, uint256 height, bytes calldata pmtSerialized, bytes32 derivationArgumentsHash, bytes calldata userRefundBtcAddress, address liquidityBridgeContractAddress, bytes calldata liquidityProviderBtcAddress, bool shouldTransferToContract ) external returns ( int256 );
  function getActiveFederationCreationBlockHeight (  ) external view  returns ( uint256 );
  function getBtcBlockchainBestBlockHeader (  ) external view  returns ( bytes memory );
  function getBtcBlockchainBlockHeaderByHash ( bytes32 btcBlockHash ) external view returns ( bytes memory );
  function getBtcBlockchainBlockHeaderByHeight ( uint256 btcBlockHeight ) external view  returns ( bytes memory );
  function getBtcBlockchainParentBlockHeaderByHash ( bytes32 btcBlockHash ) external view  returns ( bytes memory);
}

查询演示.sol:

// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.7.0 <0.9.0;

import "./Bridge.sol";

contract QueryDemo {
    int public bestChainHeight;
    bytes public returned;
    bytes32 public headerHash;
    
    function reverse(uint256 input) internal pure returns (uint256 v) {
        v = input;
    
        // swap bytes
        v = ((v & 0xFF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00) >> 8) |
            ((v & 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) << 8);
    
        // swap 2-byte long pairs
        v = ((v & 0xFFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000) >> 16) |
            ((v & 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) << 16);
    
        // swap 4-byte long pairs
        v = ((v & 0xFFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000) >> 32) |
            ((v & 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) << 32);
    
        // swap 8-byte long pairs
        v = ((v & 0xFFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF0000000000000000) >> 64) |
            ((v & 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) << 64);
    
        // swap 16-byte long pairs
        v = (v >> 128) | (v << 128);
    }

    function clear() public   {
        headerHash =0;
        returned = "";
    } 
    
    function getBridge() private pure returns (Bridge) {
        return Bridge(address(0x01000006));
    }
    
    function getBtcBlockchainBestChainHeight() public {
        bestChainHeight = getBridge().getBtcBlockchainBestChainHeight();
    }
    
    // getBtcBlockchainBlockHashAtDepth:
    // This method throws an OOG because getBtcBlockchainBlockHashAtDepth() cannot be called
    // from a contract. Use getBtcBlockchainBestChainHeigh() and getBtcBlockchainBlockHeaderByHeight()
    // 
    function storeBtcBlockchainBlockHashAtDepth(int256 depth) public  {
      returned  = getBridge().getBtcBlockchainBlockHashAtDepth(depth); 
    }
    
    function getHeaderHash(bytes memory x) private pure returns(bytes32) {
        bytes32 h = sha256(x);
        bytes32 h2 = sha256(abi.encodePacked(h));
        return bytes32(reverse(uint256(h2))); // to show it like Bitcoin does on the debugger 
    }
    
    function computeHeaderHash() private {
        headerHash = getHeaderHash(returned);
    }
    
    function storeBtcBlockchainBestBlockHeader (  ) external {
        returned = getBridge().getBtcBlockchainBestBlockHeader();
        computeHeaderHash();
    }
    
    function getBtcBlockchainBestBlockHeader (  ) external view returns (bytes memory) {
        return getBridge().getBtcBlockchainBestBlockHeader();
   
    }
    
    function storeBtcBlockchainBlockHeaderByHash ( bytes32 btcBlockHash ) external {
        returned = getBridge().getBtcBlockchainBlockHeaderByHash ( btcBlockHash );
        computeHeaderHash();
    }
    
    function getBtcBlockchainBlockHeaderByHash ( bytes32 btcBlockHash ) external view returns (bytes memory) {
        return  getBridge().getBtcBlockchainBlockHeaderByHash ( btcBlockHash );
    }
    
    function storeBtcBlockchainBlockHeaderByHeight ( uint256 btcBlockHeight ) external {
        returned = getBridge().getBtcBlockchainBlockHeaderByHeight (btcBlockHeight);
        computeHeaderHash();
    }
    
    function getBtcBlockchainBlockHeaderByHeight ( uint256 btcBlockHeight ) external view returns(bytes memory ret) {
        return getBridge().getBtcBlockchainBlockHeaderByHeight (btcBlockHeight);
    }
    
    function storeBtcBlockchainParentBlockHeaderByHash ( bytes32 btcBlockHash ) external {
        returned = getBridge().getBtcBlockchainParentBlockHeaderByHash ( btcBlockHash);
        computeHeaderHash();
    }
    
    function getBtcBlockchainParentBlockHeaderByHash ( bytes32 btcBlockHash ) external view returns(bytes memory ret) {
        return  getBridge().getBtcBlockchainParentBlockHeaderByHash ( btcBlockHash);
    }
    
    function testGetParentParentHeader() public view returns(bytes memory ret) {
        bytes memory x = getBridge().getBtcBlockchainBlockHeaderByHeight (2064695);
        bytes32  h =getHeaderHash(x);    
        
        // now the has has been computed. Use the has to get the parent block header
        ret=getBridge().getBtcBlockchainParentBlockHeaderByHash ( h);
    }
    
    function testStoreGetParentHeader() public {
        returned = getBridge().getBtcBlockchainBlockHeaderByHeight (2064695);
        computeHeaderHash();    
        
        // now the has has been computed. Use the has to get the parent block header
        returned = getBridge().getBtcBlockchainParentBlockHeaderByHash ( headerHash);
        computeHeaderHash();
    }
}
于 2021-08-14T02:35:01.710 回答
4

RSKIP220确实已包含在 RSKj 的 IRIS 3.0.0 版本中,您可以看到部分实现:

在此处RepositoryBtcBlockStoreWithCache

    public StoredBlock getStoredBlockAtMainChainHeight(int height) throws BlockStoreException {

...在这里BridgeMethods

    GET_BTC_BLOCKCHAIN_PARENT_BLOCK_HEADER_BY_HASH(
            CallTransaction.Function.fromSignature(
                    "getBtcBlockchainParentBlockHeaderByHash",
                    new String[]{"bytes32"},
                    new String[]{"bytes"}

请注意,这些方法不会通过特殊的 RPC 或类似的东西暴露在外部。相反,它们可通过预编译函数在 RSK Bridge 上使用。预编译函数是包含在 RSK 节点本身的实现中的函数,但它们就像智能合约一样公开。

这意味着您可以与他们互动

  • 链下,例如在 DApp 中,使用 web3.js、ethers.js 等
  • 链上,例如在您自己的智能合约中

为此,您可以将ABI 用于 RSK 桥

  {
    "name": "getBtcBlockchainParentBlockHeaderByHash",
    "type": "function",
    "constant": true,
    "inputs": [
      {
        "name": "btcBlockHash", 
        "type": "bytes32" 
      }
    ],
    "outputs": [
      {
        "name": "",
        "type": "bytes"
      }
    ]
  },
于 2021-08-13T13:56:24.333 回答