IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 区块链 -> 从 sCrypt 智能合约中访问区块链数据(无需预言机) -> 正文阅读

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

智能合约对外部世界一无所知,一般必须依靠预言机来导入外部数据。我们之前已经展示了两种基于 Rabin 签名和 ECDSA 从预言机导入数据的方法。在本文中,我们将展示如何在没有预言机的情况下访问特定类型的外部数据,即区块链上的数据(例如区块头和交易),同时仍然保持数据完整性。通过允许智能合约以最少信任原则访问链上数据,将为所有新的比特币智能合约提供无限的机会。

访问区块头

顾名思义,比特币区块链由很多个区块链接而成。一个区块有两部分数据:区块头和交易。

在这里插入图片描述

一个块和它的头

区块头包含区块的元数据,有六个字段,如下所示。

在这里插入图片描述

比特币区块头

值得注意的是,比特币区块头是比特币工作量证明共识算法的一部分。更具体地说,区块头序列化后的哈希值不应超过难度目标(即前导零的数量)。由于工作量证明无需信任的性质,生成一个有效的区块头的成本非常高,尤其是在难度(difficulty)要求很高的情况下。但是却很容易检查给定的区块头是否有效。这正是我们在不依赖任何预言机的情况下将区块头导入如下所示智能合约的理论前提。

import "util.scrypt";
import "merklePath.scrypt";

struct BlockHeader {
    bytes version;
    Sha256 prevBlockHash;
    Sha256 merkleRoot;
    int time;
    // difficulty target
    bytes bits;
    int nonce;
}

// a library to trustlessly access the blockchain: including blockheaders and transactions
library Blockchain {

    // SPV: is a txid in a block
    static function txInBlock(Sha256 txid, BlockHeader bh, MerkleProof merkleproof) : bool {
        return MerklePath.calMerkleRoot(txid, merkleproof) == bh.merkleRoot;
    }

    // is block header valid with difficulty meeting target
    static function isBlockHeaderValid(BlockHeader bh, int blockchainTarget) : bool {
        int bhHash = blockHeaderHashAsInt(bh);
        int target = bits2Target(bh.bits);
        // block hash below target and target below blockchain difficulty target
        return bhHash <= target && target <= blockchainTarget;
    }

    // convert difficulty from bits to target
    static function bits2Target(bytes bits) : int {
        int exponent = Util.fromLEUnsigned(bits[3 :]);
        int coefficient = Util.fromLEUnsigned(bits[: 3]);
        int n = 8 * (exponent - 3);
        bytes target = num2bin(coefficient, 32) >> n;
        return  Util.fromLEUnsigned(target);
    }

    // serialize a block header
    static function serialize(BlockHeader bh) : bytes {
        return bh.version + bh.prevBlockHash + bh.merkleRoot + Util.toLEUnsigned(bh.time, 4) + bh.bits + Util.toLEUnsigned(bh.nonce, 4);
    }

    // block header hash
    static function blockHeaderHash(BlockHeader bh) : Sha256 {
        return hash256(serialize(bh));
    }

    // block header hash, but converted to a positive number
    static function blockHeaderHashAsInt(BlockHeader bh) : int {
        return Util.fromLEUnsigned(blockHeaderHash(bh));
    }
}

在函数 isBlockHeaderValid() 中检查区块头是否有效:函数 bits2Target() 从紧凑形式(通常称为 nBits 的 4 字节字段)计算难度目标;我们需要确保计算出的区块头哈希值满足其中声明的难度目标要求( bhHash <= target)。

假区块头

另外,我们还检查了难度目标不大于 blockchainTarget 参数( target <= blockchainTarget),以控制产生假区块头的难度(blockchainTarget 越小伪造难度越高)。否则,攻击者可以轻松创建一个区块头,其哈希满足其中声明的难度目标(例如,只有 2 个前导零)。与比特币的许多其他方面(例如零确认)一样,以这种方式导入区块头的安全性是通过经济手段来保障的,而不仅仅是技术性保障。这意味着在实践中,依赖真实区块头的智能合约中锁定的比特币数量,不应超过产生虚假区块头的成本。

访问交易

一旦区块头可用,我们就可以轻松访问区块中的任何交易。这是因为区块头包含所有交易的 Merkle 树根。与 SPV 类似,我们将交易及其 Merkle 路径传递到智能合约中,并验证它与区块头中的根哈希匹配。函数 txInBlock() 演示了这一点。

在这里插入图片描述

案例:使用区块链生成随机数

一般来说,在区块链中安全公平地生成伪随机数被认为是一个难题,因为区块链既是确定性的又是透明的。但我们可以利用区块头的 nonce 字段,作为熵的来源。

Alice 和 Bob 都将相同数量的比特币锁定到以下合约中。一旦包含合约的交易被广播,它将被处理并包含在一个未来的区块中。根据区块的 nonce 值(很难预测并且可以被视为随机),确定赢家并拿走所有锁定的比特币。

import "blockchain.scrypt";

/*
  A trustless pesudo-random number generator using the block containing the deployed contract tx as an entropy source
*/
contract BlockchainPRNG {

    // maximal target for any block to be considered valid
    int blockchainTarget;
    PubKey alice;
    PubKey bob;

    /*
      @bh: header of the block containing the contract tx/UTXO
      @merkleproof: Merkle proof for the tx
      @sig: winner signature
     */
    public function bet(BlockHeader bh, MerkleProof merkleproof, Sig sig,  SigHashPreimage txPreimage) {
        require(Tx.checkPreimage(txPreimage));

        // get id of previous tx
        Sha256 prevTxid = Sha256(Util.outpoint(txPreimage)[:32]);

        // validate block header
        require(Blockchain.isBlockHeaderValid(bh, this.blockchainTarget));

        // verify previous tx is in the block
        require(Blockchain.txInBlock(prevTxid, bh, merkleproof));

        // use block header's nonce's last bit as a pesudo-random number
        PubKey winner = bh.nonce % 2 ? this.alice : this.bob;
        require(checkSig(sig, winner));
    }
}

函数的前两行使用 OP_PUSH_TX 技术获取包含合约的交易的 txid; 第3行 require(Blockchain.isBlockHeaderValid(bh, this.blockchainTarget)) 验证区块头是否合法;第4行 require(Blockchain.txInBlock(prevTxid, bh, merkleproof)) 验证前一个交易是否在该区块中。最后如果 nonce 字段为奇数,则 Alice 获胜;否则,Bob 获胜。

总结

我们已经展示了应用最小信任原则在 sCrypt 智能合约中访问区块链数据。由于序列化的区块头头只有 80 字节长,并且 Merkle 证明按对数缩放,因此该技术非常高效(与 SPV 相同)。我们还展示了一个使用区块链数据生成伪随机数的示例。这只是可能的开始,我们将在以后的文章中探讨。敬请关注。

  区块链 最新文章
盘点具备盈利潜力的几大加密板块,以及潜在
阅读笔记|让区块空间成为商品,打造Web3云
区块链1.0-比特币的数据结构
Team Finance被黑分析|黑客自建Token“瞒天
区块链≠绿色?波卡或成 Web3“生态环保”标
期货从入门到高深之手动交易系列D1课
以太坊基础---区块验证
进入以太坊合并的五个数字
经典同态加密算法Paillier解读 - 原理、实现
IPFS/Filecoin学习知识科普(四)
上一篇文章      下一篇文章      查看所有文章
加:2021-11-30 15:40:15  更:2021-11-30 15:40:36 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/25 22:37:52-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码