Becoming an Oracle Provider for StarkEx
StarkEx for perpetual trading uses external price feeds, which are given to the system in the Oracle price tick transaction. StarkEx for Perpetual supports combining many prices from many Oracles/providers into one single quorum.
This page describes the technical steps that you are required to perform in order to be able to be an Oracle provider for StarkEx for Perpetual.
The documentation here refers to a python script, referred to as public_cli in the below pseudo code, that would be open-sourced by StarkWare soon. In the meantime, if you would like to have it, please contact us.

Step 1: Derive your Stark Key Pair From an Ethereum Key Pair

As detailed in the crypto section, STARK proofs use different hash functions and signatures from Ethereum, and therefore in order to sign on prices for the system you will need to create your private starkKey. A recommended and easy yet secure method to create your starkKeywith your Ethereum key is demonstrated here:
  1. 1.
    Create an Ethereum signature on the constant string "StarkKeyDerivation" (or 0x537461726b4b657944657269766174696f6e)
  2. 2.
    Hash (using keccak) r and s signature components to one 256-bit word
  3. 3.
    Remove the last 5 bits of the resulted number to get the 251-bit stark private key
  4. 4.
    Derive the stark public key from the stark private key with the relevant CLI function

Example

1
Using Ganache's default Eth account:
2
eth_key = 0x4f3edf983ac636a65a842ce7c78d9aa706d3b113bce9c46f30d7d21715b23b1d
3
eth_address = 0x90F8bf6A479f320ead074411a4B0e7944Ea8c9C1
4
eth_signature =
5
fd85e77f5bb436eb90a4c3324a02fea6ef766e6ac85bffccb6e1cdc03479e9ac
6
058e6fb13916131dd4df1911098e2df71d582ab86281bf2553e55571aa99064b
7
1c
8
eth_signature_hash = keccak256(r, s) =
9
0x2f008fa70d291380abafd4a98029ff706940d392b2a30d57c09d49a2447407f2
10
stark_private_key = last251Bits(ethSignatureHash) =
11
178047D3869489C055D7EA54C014FFB834A069C9595186ABE04EA4D1223A03F
12
stark_key = public_cli(starkPrivateKey) =
13
0x1895a6a77ae14e7987b9cb51329a5adfb17bd8e7c638f92d6892d76e51cebcf
Copied!

Step 2: Public StarkKey Added to the On-Chain Configuration

For each assetId, the on-chain contract saves as part of its syntheticConfiguration a list of trusted public keys that are allowed to sign this asset. The Oracle's public key must be included in the configuration. Otherwise, the STARK proof will not be able to use its signature.
Since the application is the only party allowed to update the on-chain configuration, this step requires the application's consent.
For security reasons, adding a new public key to the on-chain configuration after the system is already deployed, can happen only after a timelock period (usually a few weeks), to allow users that disapprove of the change to exit.

Step 3: Start Signing Prices

Calculate the hash to sign on

Call the hash function in the CLI with the following fields:
  1. 1.
    timestamp - 32 bit number (seconds since epoch)
  2. 2.
    price - 120 bit number, with 18 decimal digits after the decimal point
  3. 3.
    asset_name (of your choice, per asset. for example "BTCUSD") - 128 bit number
  4. 4.
    oracle_name (your identity. e.g. "Chain") - 40 bit number
Parameters 3 and 4 should be consistent among all the providers of every Oracle entity (i.e., Chainlink, Maker, etc.) that sign on a specific asset.
The CLI function combines and hashes the parameters as shown here:
1
timestamp = January 1st, 2020 = hex(1577836800) = 0x5e0be100
2
price = $11512.34 = hex(11512.34 * (10**18)) = 0x27015cfcb0230820000
3
asset_name = 128bits(hex("BTCUSD")) = 0x42544355534400000000000000000000
4
oracle_name = hex("Maker") = 0x4d616b6572
5
first_number = 0(84-bit) || AssetName (128-bit) || oracleName (40-bit) =
6
425443555344000000000000000000004d616b6572
7
second_number = 0(100-bit) || Price(120-bit) || Timestamp (32-bit) =
8
27015cfcb02308200005e0be100
9
data_hash = pedersen(first_number, second_number) =
10
3e4113feb6c403cb0c954e5c09d239bf88fedb075220270f44173ac3cd41858
Copied!

Sign the hashed message with the sign function

Example

1
signature = StarkSign(key=stark_private_key, data=data_hash) =
2
r: 0x6a7a118a6fa508c4f0eb77ea0efbc8d48a64d4a570d93f5c61cd886877cb920
3
s: 0x6de9006a7bbf610d583d514951c98d15b1a0f6c78846986491d2c8ca049fd55
Copied!
Last modified 27d ago