mirror of
https://github.com/aljazceru/dlcspecs.git
synced 2026-01-31 19:54:25 +01:00
oracle proposal (#55)
This commit is contained in:
committed by
GitHub
parent
0b69c3ed78
commit
3df71667e9
76
Messaging.md
76
Messaging.md
@@ -56,6 +56,7 @@ Various fundamental types are referred to in the message specifications:
|
||||
* `u32`: a 4 byte unsigned integer
|
||||
* `u64`: an 8 byte unsigned integer
|
||||
* `int32`: a 4 byte signed integer
|
||||
* `bool`: a boolean value represented as a `byte` which can have only two value, `0x01` to represent `true` and `0x00` to represent false (any other value should be considered invalid).
|
||||
|
||||
Inside TLV records which contain a single value, leading zeros in
|
||||
integers can be omitted:
|
||||
@@ -77,7 +78,8 @@ The following convenience types are also defined:
|
||||
* `spk`: A bitcoin script public key encoded as ASM prefixed with a `u16` value indicating its length.
|
||||
* `short_contract_id`: an 8 byte value identifying a contract funding transaction on-chain (see [BOLT #7](https://github.com/lightningnetwork/lightning-rfc/blob/master/07-routing-gossip.md#definition-of-short-channel-id))
|
||||
* `bigsize`: a variable-length, unsigned integer similar to Bitcoin's CompactSize encoding, but big-endian. Described in [BigSize](https://github.com/lightningnetwork/lightning-rfc/blob/master/01-messaging.md#appendix-a-bigsize-test-vectors).
|
||||
* `string`: a UTF-8 encoded string using [NFC for normalization](https://github.com/discreetlogcontracts/dlcspecs/issues/89)
|
||||
* `string`: a UTF-8 encoded string using [NFC for normalization](https://github.com/discreetlogcontracts/dlcspecs/issues/89), prefixed by a `bigsize` value indicating its length in bytes.
|
||||
|
||||
|
||||
## DLC Specific Types
|
||||
|
||||
@@ -178,78 +180,6 @@ This type contains signatures of the funding transaction and any necessary infor
|
||||
`witness` is the data for a witness element in a witness stack. An empty `witness_stack` is an error,
|
||||
as every input must be Segwit. Witness elements should *not* include their length as part of the witness data.
|
||||
|
||||
### The `event_descriptor` Type
|
||||
|
||||
This type contains information about the *exact* and fully specified outcomes in an event for which an oracle plans on releasing a signature over.
|
||||
|
||||
#### Version 0 `external_event_descriptor`
|
||||
|
||||
1. type: 55300 (`external_event_descriptor_v0`)
|
||||
2. data:
|
||||
* [`string`:`external_name`]
|
||||
|
||||
`external_name` can refer to anything here and it is up to the oracle and user to agree on how to interpret it.
|
||||
|
||||
#### Version 0 `enum_event_descriptor`
|
||||
|
||||
1. type: 55302 (`enum_event_descriptor_v0`)
|
||||
2. data:
|
||||
* [`u16`:`num_outcomes`]
|
||||
* [`u16`:`outcome_1_len`]
|
||||
* [`string`:`outcome_1`]
|
||||
* ...
|
||||
* [`u16`:`outcome_n_len`]
|
||||
* [`string`:`outcome_n`]
|
||||
|
||||
This type of event descriptor is a simple enumeration where the value `n` is the number of outcomes in the event.
|
||||
|
||||
Each `outcome_i` corresponds to the pre-image of a possible outcome that the oracle could sign.
|
||||
|
||||
#### Version 0 `range_event_descriptor`
|
||||
|
||||
1. type: 55304 (`range_event_descriptor_v0`)
|
||||
2. data:
|
||||
* [`int32`:`start`]
|
||||
* [`int32`:`stop`]
|
||||
* [`u16`:`step`]
|
||||
|
||||
`start` refers to the first possible outcome number
|
||||
|
||||
`end` refers to the last possible outcome number
|
||||
|
||||
`step` refers to the increment between each outcome
|
||||
|
||||
### The `oracle_event` Type
|
||||
|
||||
This type contains information about an event for which an oracle plans on releasing a signature over.
|
||||
|
||||
#### Version 0 `oracle_event`
|
||||
|
||||
1. type: 55330 (`oracle_event_v0`)
|
||||
2. data:
|
||||
* [`x_point`:`oracle_public_key`]
|
||||
* [`x_point`:`oracle_nonce`]
|
||||
* [`u32`:`event_maturity_epoch`]
|
||||
* [`event_descriptor`:`event_descriptor`]
|
||||
* [`string`:`event_uri`]
|
||||
|
||||
`event_maturity_epoch` refers to the earliest time this event (UTC) is expected to be signed, in epoch seconds.
|
||||
|
||||
`event_uri` is a name and/or categorization of this event given by the oracle.
|
||||
|
||||
### The `oracle_announcement` Type
|
||||
|
||||
This type contains information about an announcement of an oracle to attest to an event in the future.
|
||||
|
||||
#### Version 0 `oracle_announcement`
|
||||
|
||||
1. type: 55332 (`oracle_announcement`)
|
||||
2. data:
|
||||
* [`signature`:`annoucement_signature`]
|
||||
* [`oracle_event`:`oracle_event`]
|
||||
|
||||
The `annoucement_signature` is a signature of the hash of the serialized `oracle_event` that is valid with respect to `oracle_public_key`. This can be shared with peers that have already verified this oracle's public key.
|
||||
|
||||
## Authors
|
||||
|
||||
Nadav Kohen <nadavk25@gmail.com>
|
||||
|
||||
197
Oracle.md
Normal file
197
Oracle.md
Normal file
@@ -0,0 +1,197 @@
|
||||
# Oracle specifications
|
||||
|
||||
## Introduction
|
||||
|
||||
For the purpose of these specifications, an event is a digital representation of a real world fact.
|
||||
An [oracle](./Introduction.md#Oracle) is an entity that commits to publishing one or more signatures over a (number of) event outcome(s) ahead of time by releasing one or more [R-values](./Introduction.md#R-value) as well as necessary information for two parties to build a set of [CETs](./Introduction.md#Contract-Execution-Transaction-(CET)).
|
||||
This necessary information is committed to in a so-called [_event descriptor_](#Event-descriptor) that will be further detailed in this document.
|
||||
|
||||
## Table of Contents
|
||||
|
||||
- [Event descriptor](#event-descriptor)
|
||||
- [Simple enumeration](#simple-enumeration)
|
||||
- [Example: Weather tomorrow](#example-weather-tomorrow)
|
||||
- [Range](#range)
|
||||
- [Example: tomorrow's temperature](#example-tomorrows-temperature)
|
||||
- [Digit decomposition](#digit-decomposition)
|
||||
- [Example: BTC/USD rate](#example-btcusd-rate)
|
||||
- [Serialization and signing of outcome values](#serialization-and-signing-of-outcome-values)
|
||||
- [Serialization of event descriptors](#serialization-of-event-descriptors)
|
||||
- [Version 0 `enum_event_descriptor`](#version-0-enum_event_descriptor)
|
||||
- [Version 0 `range_event_descriptor`](#version-0-range_event_descriptor)
|
||||
- [Version 0 `digit_decomposition_event_descriptor`](#version-0-digit_decomposition_event_descriptor)
|
||||
- [Oracle events](#oracle-events)
|
||||
- [Version 0 `oracle_event`](#version-0-oracle_event)
|
||||
- [Oracle announcements](#oracle-announcements)
|
||||
- [Version 0 `oracle_announcement`](#version-0-oracle_announcement)
|
||||
|
||||
## Event descriptor
|
||||
|
||||
An event descriptor provides information to clients about an event for which an oracle plans on releasing a signature over its outcome.
|
||||
The provided information should be sufficient for a client to create a set of adaptors signatures for some CETs that will cover all possible outcomes of the event.
|
||||
|
||||
Here we assume that an event outcome can be represented either as a set of strings or numbers.
|
||||
Three kinds of event outcomes are defined (note that a single event can be composed of several types).
|
||||
|
||||
### Simple enumeration
|
||||
|
||||
For events that have a narrow range of possible outcomes, the outcomes can simply be enumerated.
|
||||
|
||||
#### Example: Weather tomorrow
|
||||
|
||||
Tomorrow's weather can be represented as the set of strings `[sunny, cloudy, rainy]`.
|
||||
|
||||
### Range
|
||||
|
||||
When an event has numerical outcomes that cannot be easily enumerated, they can be represented as a series with:
|
||||
|
||||
- start: the first possible outcome number
|
||||
- count: the number of possible outcomes
|
||||
- step: the increment
|
||||
- unit: the unit of the outcome value
|
||||
- precision: the precision of the outcome representing the base 10 exponent by which to multiply the signed number to obtain the actual outcome value.
|
||||
|
||||
#### Example: tomorrow's temperature
|
||||
|
||||
```
|
||||
start: -100
|
||||
count: 201
|
||||
step: 1
|
||||
unit: °C
|
||||
precision: 0
|
||||
```
|
||||
|
||||
### Digit decomposition
|
||||
|
||||
When a range of a numerical outcomes is large or unbounded, the oracle can represent the outcome using digit decomposition.
|
||||
|
||||
The event descriptor should include:
|
||||
|
||||
- base: a number representing the base in which the outcome value is decomposed and which will indicate the possible range of each digit that will be signed (e.g. 2 for binary, 10 for decimal, 16 for hex-decimal).
|
||||
- is-signed: a boolean value indicating whether the outcomes can be negative.
|
||||
- unit: the unit of the outcome value
|
||||
- precision: the precision of the outcome representing the base exponent by which to multiply the number represented by the composition of the digits to obtain the actual outcome value.
|
||||
- number of digits: the number of digits that the oracle will sign (if `is-signed` is set to true, the number of R-values for the event will be `number of digits + 1`).
|
||||
|
||||
In the case where the number of digits that make up the outcome value exceeds the number of r-values that the oracle committed to, the oracle should sign the maximal possible value that it can attest to.
|
||||
In the case where the outcome value became negative but the oracle did not provide an extra R-value, it should sign the value 0.
|
||||
The minimum and maximum values that can be attested to by an oracle should thus be interpreted as `max_value or more` and `min_value or less`.
|
||||
This enables contracting party to specify payouts for the overflow and underflow cases, and avoid having to use the refund path which in most cases would be unfair.
|
||||
More complex constructions where considered to handle these, but the simplicity of the currently specified approach is the reason that it was chosen.
|
||||
|
||||
The oracle must separately provide an array of R values, one for each of the digit that will be signed, with the first value of the array being used for signing the leftmost digit. If the is-signed value is true, an additional R-value must be provided as the first element in this array, which will be used to sign the string "+" in case of an outcome with a positive value or zero value and the string "-" in case of an outcome with a negative one.
|
||||
In practice this array is provided as part of the [Oracle events](#Oracle-events) structure.
|
||||
|
||||
When the outcome is not the same order of magnitude as the maximum possible outcome, leading zeros must be signed.
|
||||
|
||||
#### Example: BTC/USD rate
|
||||
|
||||
The following example illustrates how numerical decomposition can help reduce the number of required CETs while covering a large range of possible outcomes.
|
||||
|
||||
Alice and Bob wish to enter into a DLC at time `t` when BTC/USD ~= $10000 with a maturity time of `t+1`.
|
||||
The oracle provides 6 R-values `R0-5`, meaning that it will sign six digits `D0-5`, enabling him to attest to outcomes in the range `[000000,999999]`:
|
||||
|
||||
```
|
||||
base: 10
|
||||
isSigned: false
|
||||
RValues: [R0, R1, R2, R3, R4, R5]
|
||||
unit: dollars
|
||||
precision: 0
|
||||
```
|
||||
|
||||
Alice and Bob create a DLC with "relevant" outcomes between $10000 and $10999.
|
||||
Below $10000 Alice gets everything, and above $10999 Bob gets everything.
|
||||
They use the `R0` and `R1` values to cover the cases where BTC/USD < $10000 using `D0=0` and `D1=0`.
|
||||
They use `R0`, `R1` and `R2` to cover the cases where BTC/USD > $10999 and <= $19999, using `D1=0`, `D1=1` and `D2 in [0-9]`.
|
||||
They use `R0` and `R1` to cover the cases where BTC/USD >= $20000 and < $99999, using `D0=0` and `D1 in [2,9]`.
|
||||
Finally, they use only `D0` to cover the cases where BTC/USD >= $100000 and <= $999999, using `D0 in [1-9]`.
|
||||
|
||||
At maturity time, if the BTC/USD rate is less than $999999, the oracle signs each of the digits representing the outcome value using the digits' corresponding R value.
|
||||
For example, if the rate at maturity time is $20000, the oracle will sign the digits `0`, `2`, `0`, `0`, `0`, `0`.
|
||||
|
||||
If the rate is greater than $999999, the oracle signs the digits `9`, `9`, `9`, `9`, `9`, `9`.
|
||||
|
||||
### Serialization and signing of outcome values
|
||||
|
||||
Every outcome value should be encoded as [a UTF-8 string with NFC normalization](./Messaging.md#Fundamental-types), before being passed to the signing algorithm.
|
||||
UTF-8 is chosen as being a widely supported and easy to implement encoding format.
|
||||
|
||||
For numerical outcomes represented in bases greater than 10, each digit should be converted to base 10 before being encoded (note that base 10 numbers in UTF-8 take values in the 0x0030-0x0039 range).
|
||||
This helps preventing any confusion about the capitalization of letters or the introduction of non-standard characters.
|
||||
|
||||
### Serialization of event descriptors
|
||||
|
||||
Event descriptors should be serialized using [TLV format](https://github.com/lightningnetwork/lightning-rfc/blob/master/01-messaging.md#type-length-value-format) as described bellow.
|
||||
|
||||
#### Version 0 `enum_event_descriptor`
|
||||
|
||||
1. type: 55302 (`enum_event_descriptor_v0`)
|
||||
2. data:
|
||||
* [`u16`:`num_outcomes`]
|
||||
* [`string`:`outcome_1`]
|
||||
* ...
|
||||
* [`string`:`outcome_n`]
|
||||
|
||||
This type of event descriptor is a simple enumeration where the value `n` is the number of outcomes in the event.
|
||||
|
||||
Note that `outcome_i` is the outcome value itself and not its hash that will be signed by the oracle.
|
||||
|
||||
#### Version 0 `range_event_descriptor`
|
||||
|
||||
1. type: 55304 (`range_event_descriptor_v0`)
|
||||
2. data:
|
||||
* [`int32`:`start`]
|
||||
* [`u32`:`count`]
|
||||
* [`u16`:`step`]
|
||||
* [`string`:`unit`]
|
||||
* [`int32`:`precision`]
|
||||
|
||||
#### Version 0 `digit_decomposition_event_descriptor`
|
||||
|
||||
1. type: 55306 (`digit_decomposition_event_descriptor_v0`)
|
||||
2. data:
|
||||
* [`bigsize`:`base`]
|
||||
* [`bool`:`is_signed`]
|
||||
* [`string`:`unit`]
|
||||
* [`int32`:`precision`]
|
||||
* [`uint16`:`nb_digits`]
|
||||
|
||||
### Oracle events
|
||||
|
||||
For users to be able to create DLCs based on a given event, they also need to obtain information about the oracle and the time at which it plans on releasing a signature over the event outcome.
|
||||
Oracle events contain such information, which includes:
|
||||
* the nonce(s) that will be used to sign the event outcome(s)
|
||||
* the earliest time (UTC) at which it plans on releasing a signature over the event outcome, in epoch seconds,
|
||||
* the event descriptor,
|
||||
* the event ID which can be a name or categorization associated with the event by the oracle.
|
||||
|
||||
The TLV serialization for oracle events is as follow:
|
||||
|
||||
#### Version 0 `oracle_event`
|
||||
|
||||
1. type: 55330 (`oracle_event_v0`)
|
||||
2. data:
|
||||
* [`u16`:`nb_nonces`]
|
||||
* [`nb_nonces*x_point`:`oracle_nonces`]
|
||||
* [`u32`:`event_maturity_epoch`]
|
||||
* [`event_descriptor`:`event_descriptor`]
|
||||
* [`string`:`event_id`]
|
||||
|
||||
## Oracle announcements
|
||||
|
||||
In order to make it possible to hold oracles accountable in cases where they do not release a signature for an event outcome, there needs to be a proof that an oracle has committed to a given outcome.
|
||||
This proof is given in a so-called oracle announcement, which contains an oracle event together with the oracle public key and a signature over its serialization, which must be valid with respect to the specified public key.
|
||||
|
||||
This also makes it possible for users to obtain oracle event information from an un-trusted peer while being guaranteed that it originates from a given oracle.
|
||||
|
||||
The TLV serialization of oracle announcements is as follow.
|
||||
|
||||
#### Version 0 `oracle_announcement`
|
||||
|
||||
1. type: 55332 (`oracle_announcement`)
|
||||
2. data:
|
||||
* [`signature`:`annoucement_signature`]
|
||||
* [`x_point`:`oracle_public_key`]
|
||||
* [`oracle_event`:`oracle_event`]
|
||||
|
||||
where `signature` is a Schnorr signature over a sha256 hash of the serialized `oracle_event`.
|
||||
Reference in New Issue
Block a user