Clarity smart contracts and TypeScript library to facilitate the use RedStone oracles on Stacks.
Most oracle solutions will post data points to a blockchain at a set interval. It means that an oracle provider has a constant cost in maintaining up to date information. Next to that, the oracle also has to make a choice in which data points to provide. RedStone is different in that it follows a "pull" model. The RedStone oracle API provides a large and ever growing dataset that consumers can pull from. These messages are signed by the oracle and meant to be posted to a blockchain only at the time they are needed. In fact, the end-user submits a RedStone data package together with the contract call that uses the data. The main advantages of this approach are:
- Oracle providers do not need to constantly submit data to the chain themselves.
- A much larger dataset is available and it is almost costless to introduce new data points.
- Applications that consume RedStone oracle messages can get the latest data points and process them immediately.
- An application can more easily depend on multiple oracles without running into any race conditions. The dapp can require a valid data package with the same timestamp signed by multiple oracles, all submitted in one transaction.
For more information and a more thorough explanation of RedStone, head over to their website website.
This repository contains an initial working implementation of the RedStone protocol for the Stacks blockchain. It makes use of "Lite Signatures" as they are cheaper to verify on-chain. (Signatures are ordered RSV.)
stacks-redstone.ts is a minimal library that facilitates the use of RedStone messages on Stacks. It currently depends on micro-stacks. It can be used to convert Redstone PricePackage objects to the proper formats for use in Clarity.
The basic functions most dapps will use are:
-
pricePackageToCV()takes aPricePackageand turns it in to an object containing auintCVfor the timestamp and alistCVwithtupleCVs of all the price points. (With symbols encoded asbufferCVand the values encoded asuintCV.) -
liteSignatureToBufferCV()takes a RedStoneliteSignatureand converts it to abufferCV. It will also subtract27from the signature recovery byte as required by Stacks, if it detects that the byte is larger than3.
Advanced use functions:
-
liteSignatureToStacksSignature()takes a RedStoneliteSignatureand only subtracts27from the recovery byte and returns the converted signature. -
compressRedstonePubkey()takes a 64 byte or 65 byte RedStone pubkey and compresses it, returning the 33 byte compressed pubkey. -
liteDataHash()takes aliteByteString(created by theredstone-nodepackage) and returns itskeccak256hash. -
liteDataHashPersonalSign()takes aliteByteString(created by theredstone-nodepackage) and returns the hash used by Ethereum'spersonalSign. (It hashes the byte string, prepends thepersonalSignprefix, and then hashes it again.)
A few Clarity contracts are included in this repository.
Canonical RedStone implementation:
redstone-verify.claris the main smart contract. It is a stateless library contract that can be called into by external contracts to verify RedStone messages and to recover public keys of signing oracles.
Example projects:
redstone-receiver.claris a minimal RedStone message receiving contract that uses theredstone-verifycontract to verify messages. The contract deployer can define trusted oracles by their compressed public keys. Messages can be submitted to the contract, which are then verified, and signed by trusted oracles, printed using theprintbuilt-in.usd-nft.claris a more comprehensive example that implements a SIP009 NFT. Tokens are minted in STX but priced in USD. The mint function receives RedStone STXUSD price data and uses that to determine the final price. It also stores the exchange and will always use the latest data to mint.
The example contracts are commented every step of the way.
Although this is an initial working release, there is more work left to be done. Here are the main points (PRs welcome):
- Comprehensive unit tests for the smart contracts. The current tests cover the core functionality but not all code branches are currently covered.
- Remove
micro-stacksdependency ofstacks-redstone.tsso that it can be used with bothmicro-stacksandstacks.js. - An end to end example project that contains a basic UI, Stacks wallet connection, data retrieval via the RedStone API, and supporting smart contract.
- Deploying the stateless
redstone-verifylibrary contract to mainnet and testnet. We will do this once we reach the first stable release. This readme will be updated with the contract addresses when that happens.
MIT license.