Without Oracles, Access Blockchain Data Through Bitcoin Smart Contracts

Because smart contracts have no knowledge of the outside world, they must rely on oracles to import external data in general. We previo...


Because smart contracts have no knowledge of the outside world, they must rely on oracles to import external data in general. We previously shown two methods for importing data from Oracles, based on the Rabin signature and ECDSA. In this article, we demonstrate how to access a certain form of external data, namely blockchain data (such as block headers and transactions), in the absence of oracles while retaining data integrity. Allowing smart contracts to access on-chain data with minimum trust opens the door to a plethora of different types of smart contracts on Bitcoin.

Headers of Access Blocks

As the name implies, the Bitcoin blockchain is made up of a series of blocks. A block is made up of two components: a block header and transactions.

A Block and Its Header

A block header contains the metadata of the block, with six fields as shown below.

The Bitcoin Block Header

It should be noted that bitcoin headers are a component of Bitcoin's proof-of-work consensus algorithm. In particular, the hash of a serialised block header should not be more than the difficulty target (i.e., the number of leading zeros). Producing a valid block header is extremely expensive due to the trustless nature of proof of work, especially when the difficulty is high. However, it is quite simple to determine whether a given block header is genuine. This is exactly how we import a block header into a smart contract without using any oracles, as seen below.


[import "Util.scrypt"; import "mast.scrypt"; struct BlockHeader { bytes version; Sha256 prevBlockHash; Sha256 merkleRoot; int time; // difficulty target bytes bits; bytes 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, MerklePath merklePath) : bool { return MAST.calMerkleRoot(txid, merklePath) == bh.merkleRoot; } // is block header valid with difficulty meeting target static function isBlockHeaderValid(BlockHeader bh, int blockchainTarget) : bool { int bhHash = blockHeaderHash(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 = unpack(bits[3 :]); bytes coefficient = bits[: 3]; int leadingZeroBytes = exponent - 3; bytes targetBytes = num2bin(0, leadingZeroBytes) + coefficient; return Util.fromLEUnsigned(targetBytes); } // serialize a block header static function serialize(BlockHeader bh) : bytes { return bh.version + bh.prevBlockHash + bh.merkleRoot + num2bin(bh.time, 4) + bh.bits + bh.nonce; } // block header hash static function blockHeaderHash(BlockHeader bh) : int { bytes bhSerialized = serialize(bh); // hash is reversed return unpack(reverseBytes(hash256(bhSerialized), 32)); } }]

Blockchain Contract 

isBlockHeaderValid() at Line 22 checks if a block header is valid. bits2Target() at Line 31 calculates the difficulty target from a compact form (a 4-byte field typically referred to as nBits). We simply hash the block header at Line 23 and make sure it meets the difficulty target at Line 27.

Fake Block Headers

To manage the difficulty of constructing a false block header, we also verify at Line 27 that the difficulty target is no greater than the blockchainTarget parameter. Otherwise, an attacker can easily generate a block header whose hash fulfils the difficulty target within a short period of time (e.g., only has 2 leading zeros). As with many other features of Bitcoin, such as 0-conf, the security of importing block headers in this manner is both economic and technological. In reality, this means that a smart contract that relies on a real block header must not lock more bitcoin than it costs to construct a false header.

Access Transactions

Once a block header is available, we can easily access any transaction in the block. This is because the block header contains the root of the Merkle tree of all the transactions. Similar to SPV, we pass the transaction and its Merkle path into a smart contract and verify it matches the root hash in the block header. txInBlock() at Line 17 demonstrates this.

A Merkle Tree and Merkle Proof

A Case Study: Using Blockchain To Generate Random Numbers

Because the blockchain is both deterministic and visible, it is regarded a difficult problem to create pseudo-random numbers in a secure and fair manner. As a source of entropy, we use blockchain data, notably the nonce field of a block header.

Alice and Bob each put the identical amount of bitcoins into the contract below. Once the contract transaction has been published, it will be mined into a future block. A winner is decided and all locked bitcoins are taken based on the nonce of the block, which is difficult to anticipate and can be viewed as random.

[import "blockchain.scrypt"; /* A trustless psuedo-random number generator using the block containing the deployed contract tx as an entropy source */ contract BlockchainPRNG { PubKey alice; PubKey bob; /* @bh: header of the block containing the contract tx/UTXO @merklePath: Merkle proof for the tx @sig: winner signature @blockchainTarget: difficulty target on mainnet */ public function bet(BlockHeader bh, MerklePath merklePath, Sig sig, int blockchainTarget, 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, blockchainTarget)); // verify previous tx is in the block require(Blockchain.txInBlock(prevTxid, bh, merklePath)); // use block header's nonce's last bit as a psuedo-random number PubKey winner = unpack(bh.nonce) % 2 ? this.alice : this.bob; require(checkSig(sig, winner)); } }]

BlockchainPRNG Contract

Lines 17 and 20 employ the OP PUSH TX method to obtain the transaction txid holding the contract. Line 23 validates the block header, and Line 26 validates that the prior transaction is present. Alice wins if the nonce field is odd; else, Bob wins.

Summary

We demonstrated how to access blockchain data in Bitcoin smart contracts while requiring little trust. This technique is incredibly efficient because a serialised bitcoin header is only 80 bytes long and Merkle proof scales logarithmically (same as SPV).

COMMENTS

Name

2023,2,Ai,2,AlmaLinux 9,3,Amazon Linux,5,Apache Web Server,1,AppImage,1,Arduino IDE,1,Artificial Intelligence,2,BalenaEtcher,1,Bitcoin,1,Blockchain Data,1,Bookworm,2,Bootable USB,1,C++,1,centos,1,CentOS 8,1,CentOS Stream,1,CMake,1,CockroachDB,2,cuDNN,1,Database Security,1,Debian,2,Debian 10,2,Debian 11,2,Debian 12,9,DNS,1,Docker,1,E-commerce,1,Fail2ban,1,Fedora Linux,1,Firefox 118,1,FreeIPA Server,1,Function,1,Game Projects,1,Git,3,Google PageSpeed,1,How to,5,How to Install,9,HTTPS,1,Introduction,1,Iptables,1,ISO Image,1,KVM,1,Laravel,1,Let's Encrypt SSL,1,Linux,4,Linux 6.4,1,Linux Kernel 6.5,1,Linux Mint,1,Linux Server,1,Linux-Based Systems,1,Mageia 9,1,Magento,1,MariaDB,1,Media Server,1,ModSecurity,1,New Features,1,Nextcloud,2,NGINX,2,Nvidia CUDA,1,odoo,1,Oracles,1,Performance,1,PHP Zip Module,1,pip,1,Plex,1,Port Forwarding,1,postgresql,2,Privacy,1,Programming,1,Pylint,1,python,5,Python 3.10,2,Quantum,1,Quantum Computers,1,Remote Branch,1,Renew,1,RHEL,1,Rocky Linux 9,2,Rufus,1,Shadow Password,1,SQLite,1,SSH,1,SSH key,1,SSH Keys,1,Step-by-Step,4,SuiteCRM,1,SUSE Linux,1,Syslog,1,System,1,Testing,1,Top 10,1,Translation,1,Ubuntu,1,Ubuntu 18.04,1,Ubuntu 20.04,5,Ubuntu 22.10,1,Ubuntu 23.04,1,Ubuntu Server,1,Ubuntu Upgrade,1,unsupported,1,Up-to-Date,1,Upgrade,1,Visual Studio Code,1,Vivaldi 6.2,1,Web 3.0,1,Web Hosting Security,1,Web Security,1,Webmin,1,What's New,1,Windows 11,1,
ltr
item
Linux code EDU: Without Oracles, Access Blockchain Data Through Bitcoin Smart Contracts
Without Oracles, Access Blockchain Data Through Bitcoin Smart Contracts
https://blogger.googleusercontent.com/img/a/AVvXsEjoCen6meqEPtjO8dXVdB7Im3PMH5mQxURBTn8kLBhPqx-Sjtt5ZIgyAA7oN4cJ9L0FSEQbO1Ef-GMB6t1q4g_MphwewJIFmbQuMJsHfhUJKWnWKIdQXxbjVOb1HdnpXWzovxp6sHrxa4rWoERe_7cxsGWhkiJF1Z_jjwKCZfh7IjY-eJTULCmy6kySjA=w640-h398
https://blogger.googleusercontent.com/img/a/AVvXsEjoCen6meqEPtjO8dXVdB7Im3PMH5mQxURBTn8kLBhPqx-Sjtt5ZIgyAA7oN4cJ9L0FSEQbO1Ef-GMB6t1q4g_MphwewJIFmbQuMJsHfhUJKWnWKIdQXxbjVOb1HdnpXWzovxp6sHrxa4rWoERe_7cxsGWhkiJF1Z_jjwKCZfh7IjY-eJTULCmy6kySjA=s72-w640-c-h398
Linux code EDU
https://linuxcodeedu.blogspot.com/2021/11/without-oracles-access-blockchain-data.html
https://linuxcodeedu.blogspot.com/
https://linuxcodeedu.blogspot.com/
https://linuxcodeedu.blogspot.com/2021/11/without-oracles-access-blockchain-data.html
true
6096992636254302192
UTF-8
Loaded All Posts Not found any posts VIEW ALL Readmore Reply Cancel reply Delete By Home PAGES POSTS View All RECOMMENDED FOR YOU LABEL ARCHIVE SEARCH ALL POSTS Not found any post match with your request Back Home Sunday Monday Tuesday Wednesday Thursday Friday Saturday Sun Mon Tue Wed Thu Fri Sat January February March April May June July August September October November December Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec just now 1 minute ago $$1$$ minutes ago 1 hour ago $$1$$ hours ago Yesterday $$1$$ days ago $$1$$ weeks ago more than 5 weeks ago Followers Follow THIS PREMIUM CONTENT IS LOCKED STEP 1: Share to a social network STEP 2: Click the link on your social network Copy All Code Select All Code All codes were copied to your clipboard Can not copy the codes / texts, please press [CTRL]+[C] (or CMD+C with Mac) to copy Table of Content