No matter how confused and complex blockchains get, one thing is sacrosanct: we must never compromise on decentralization.
Sounds simple enough, when you think about it. You’ve read about the Byzantine Generals Problem (and if you haven’t, please give it a look; it’s fun, and the bedrock of the decentralized blockchain we merrily speculate on today), which begets Consensus Algorithms, which begets a Fault-tolerant ecosystem of validator nodes ensuring the blockchain chugs along with one true state without depending on middlemen to achieve this harmony.
Since then, multiple blockchains have been created, with their own flavor of consensus algorithms (proof of work, proof of stake, proof of history - which Solana uses - fun fact, and so on).
Centralized blockchains exist (see what the CBN is doing with the eNaira), but we don’t talk about that.
If we’re agreed that the blockchain is only worth its salt because it isn’t beholden to any central agent, no matter how benign, and if we agree that the blockchain ensures its survival by incentivizing active participation of multiple players with very little chance of malicious entities hijacking the entire chain, then we’ve fully appreciated the philosophy that the only blockchain worth its salt is a decentralized one.
This is not immediately obvious, but arriving at consensus also implies deterministic state across smart contracts. This is one reason why it’s technically impossible to create randomness on the blockchain. As a thought experiment, let’s imagine what would happen if we created a truly random variable in a smart contract that is used to calculate something, anything.
//SPDX-Licence: Unlicensed;
pragma solidity ^0.8.2;
Contract TrueRandom {
uint randomNumber = randomNumberGenerator();
string eyeColor;
function createRandomEyeColor() public returns(string storage) {
if (randomNumber > 5) {
return eyeColor = 'red';
}
else return eyeColor = 'green';
}
}
// This contract was written directly into the Substack editor. It's prone to be flawed, and only intended for illustrative purposes
In the above example Smart Contract, we’re simulating a contract powered by true randomness (this is actually not possible in Solidity). Imagine we have a `randomNumberGenerator()` function that randomly generates a number between 1 and 10.
Now, imagine an Externally Owned Account ( that is, a wallet) calls the createRandomEyeColor() method on the contract, and they get the color ‘red’. Blockchain miners will need to verify this transaction, so they’ll trigger it to verify that the given input yields the expected output (color ‘red’).
And here’s the issue: due to the randomness of the generator, each node validator will either get ‘red’ or ‘green’ (depending on what the randomNumberGenerator outputs), so they’ll never be able to arrive at consensus about the status of that transaction, and things will fall apart very quickly.
That’s a small illustration of why the blockchain being deterministic is an important feature. State (and local, for that matter) variables held in Smart Contracts are deterministic (fancy word that means that given a particular input, the function or procedure will produce the same output, every time - something that’s demonstrably impossible with random number generators).
But what if we wanted something non-deterministic? Say, we wanted to fetch the price of $MANA and use that price to do something in our contract? Why, based on what I’ve just described, that’s a disaster! The price of $MANA changes every second, so node validators/miners will never reach a consensus!
That’s where Oracles come in. An Oracle is middleware that allows you deterministically interact with non-deterministic things (like the price of $MANA) as well as with things that are not embedded in the world of the blockchain itself.
As an example, what if we wanted to create a smart contract that deploys Ether to countries that have been affected by a natural disaster? The EVM and the blockchain has no way to ‘see’, or ‘read’ the news, but Oracles do. What’s more, they can do this deterministically, something that’s not possible if we allowed Smart contracts to read external APIs.
How do Oracles solve this problem? By being smart contracts themselves. Without going too deep into the technicals, here’s how it works:
Your Smart Contract wants to know which countries need disaster relief so it can deploy crowd-funded Ether to the dedicated wallet addresses of the distressed country.
So it sends a query to an Oracle contract, along with a callback and some gas (it costs money to use an Oracle).
The Oracle sends a query to the relevant third-party API or data provider with the information you requested (here, a list of affected nations). When it receives a response, it uses the callback you supplied to send the response to the Contract method that needed that data, which effectively executes the contract.
All is well
The Oracle has now stood between you and an API, bringing the data via a deterministic contract that node validators can verify without inconsistent state. That’s the magic, in a nutshell.
However, with this affordance comes the loss of something very crucial to the blockchain: decentralization.
The Problem with Oracles
It’s in the name, really. Oracles are ‘single sources of truth’, which is antithetical to the philosophy of the blockchain. They can be hacked, which in turn will compromise the smart contracts that depend on them. They can be wrong, or they can simply go offline. Yikes.
Mercifully, Oracles are becoming just as decentralized as the blockchains that depend on them (Provable, formerly Oraclize, has an interesting document on its methodology. Worth a read)
This makes for a great segue into Chainlink, which I’ve been reading a little about lately. It’s advertised as the ‘industry standard Oracle Network’:
“Chainlink greatly expands the capabilities of smart contracts by enabling access to real-world data and off-chain computation while maintaining the security and reliability guarantees inherent to blockchain technology.”
This is why you should look into Chainlink: it ostensibly solves the problems with Oracles by making them share more DNA with blockchain technology.
I’ve not yet found use for Oracles in my personal smart contracts. I hope to soon, and if I do, I’ll write about it.
I’ve used the poor man’s random number generator - which is clearly deterministic - the block.timestamp (used to be called now, but it’s now deprecated), but you can generate true randomness using an Oracle (infact, Provable can tap directly into Wolfram Alpha’s API to pull a random number and send it directly to your smart contract, where it becomes deterministic).
That said, if you’re feeling adventurous, here’s something you can use ChainLink for: building a truly randomly-generated Dungeons & Dragons NFT project.
Good morning, and wagmi.