lnpbp-0020
1
LNPBP: 0020
2
Layer: Application (5)
3
Vertical: Smart contracts
4
Title: RGB fungible assets schema (RGB-20)
5
Authors: Dr Maxim Orlovsky <[email protected]>,
6
Giacomo Zucco,
7
Marco Amadori,
8
Nicola Busanello,
9
Federico Tenga,
10
Sabina Sachtachtinskagia,
11
Martino Salvetti
12
Comments-URI: <https://github.com/LNP-BP/LNPBPs/issues/70>
13
Status: Final
14
Type: Standards Track
15
Created: 2019-09-23
16
Finalized: 2020-10-10
17
License: CC0-1.0
Copied!
Schema ID: sch19s8js2gyxvtyzztp82l4tt4gr3x8m28yrgks93exsfuwc5u4fqlqf46ah5
Encoded schema data: schema1qxx4qkgjsgcqcl2atrzgmugynnpuk7q5c7dcplkppl9jr0ywx75xnk3zyvup3p3ke99auju22h9734efqs6gfppkg6qcyy69a8uhnw7czt37ckszd950xwwn9mjr59payf3sd2yuezjdy5vu5jdkew7mr78prvvnjkg0x34qyf6fdfsxyd4fk6guzrpuuxp7exgkyhlntx8ruw9j2s2e7dt8sgjhczjkk5e2a3np886u86mq5ge92r5ckde9gr4htt2td66gkzvypm2hwpsr8gdm6vqzmgca3ltn8j0qqkd0rl5s6f3nllngjfldlt7kz7uarne8w0zkhwpr90k0smcxk48dx
Schema source:
1
Schema {
2
rgb_features: none!(),
3
root_id: none!(),
4
genesis: GenesisSchema {
5
metadata: type_map! {
6
FieldType::Ticker => Once,
7
FieldType::Name => Once,
8
FieldType::ContractText => NoneOrOnce,
9
FieldType::Precision => Once,
10
FieldType::Timestamp => Once,
11
FieldType::IssuedSupply => Once
12
},
13
owned_rights: type_map! {
14
OwnedRightsType::Inflation => NoneOrMore,
15
OwnedRightsType::Epoch => NoneOrOnce,
16
OwnedRightsType::Assets => NoneOrMore,
17
OwnedRightsType::Renomination => NoneOrOnce
18
},
19
public_rights: none!(),
20
abi: none!(),
21
},
22
extensions: none!(),
23
transitions: type_map! {
24
TransitionType::Issue => TransitionSchema {
25
metadata: type_map! {
26
FieldType::IssuedSupply => Once
27
},
28
closes: type_map! {
29
OwnedRightsType::Inflation => Once
30
},
31
owned_rights: type_map! {
32
OwnedRightsType::Inflation => NoneOrMore,
33
OwnedRightsType::Epoch => NoneOrOnce,
34
OwnedRightsType::Assets => NoneOrMore
35
},
36
public_rights: none!(),
37
abi: bmap! {
38
// sum(in(inflation)) >= sum(out(inflation), out(assets))
39
TransitionAction::Validate => Procedure::Embedded(StandardProcedure::FungibleInflation)
40
}
41
},
42
TransitionType::Transfer => TransitionSchema {
43
metadata: type_map! {},
44
closes: type_map! {
45
OwnedRightsType::Assets => NoneOrMore
46
},
47
owned_rights: type_map! {
48
OwnedRightsType::Assets => NoneOrMore
49
},
50
public_rights: none!(),
51
abi: none!()
52
},
53
TransitionType::Epoch => TransitionSchema {
54
metadata: none!(),
55
closes: type_map! {
56
OwnedRightsType::Epoch => Once
57
},
58
owned_rights: type_map! {
59
OwnedRightsType::Epoch => NoneOrOnce,
60
OwnedRightsType::BurnReplace => NoneOrOnce
61
},
62
public_rights: none!(),
63
abi: none!()
64
},
65
TransitionType::Burn => TransitionSchema {
66
metadata: type_map! {
67
FieldType::BurnedSupply => Once,
68
// Normally issuer should aggregate burned assets into a
69
// single UTXO; however if burn happens as a result of
70
// mistake this will be impossible, so we allow to have
71
// multiple burned UTXOs as a part of a single operation
72
FieldType::BurnUtxo => OnceOrUpTo(None),
73
FieldType::HistoryProofFormat => Once,
74
FieldType::HistoryProof => NoneOrMore,
75
},
76
closes: type_map! {
77
OwnedRightsType::BurnReplace => Once
78
},
79
owned_rights: type_map! {
80
OwnedRightsType::BurnReplace => NoneOrOnce
81
},
82
public_rights: none!(),
83
abi: bmap! {
84
TransitionAction::Validate => Procedure::Embedded(StandardProcedure::ProofOfBurn)
85
}
86
},
87
TransitionType::BurnAndReplace => TransitionSchema {
88
metadata: type_map! {
89
FieldType::BurnedSupply => Once,
90
// Normally issuer should aggregate burned assets into a
91
// single UTXO; however if burn happens as a result of
92
// mistake this will be impossible, so we allow to have
93
// multiple burned UTXOs as a part of a single operation
94
FieldType::BurnUtxo => OnceOrMore,
95
FieldType::HistoryProofFormat => Once,
96
FieldType::HistoryProof => NoneOrMore
97
},
98
closes: type_map! {
99
OwnedRightsType::BurnReplace => Once
100
},
101
owned_rights: type_map! {
102
OwnedRightsType::BurnReplace => NoneOrOnce,
103
OwnedRightsType::Assets => OnceOrMore
104
},
105
public_rights: none!(),
106
abi: bmap! {
107
TransitionAction::Validate => Procedure::Embedded(StandardProcedure::ProofOfBurn)
108
}
109
},
110
TransitionType::Renomination => TransitionSchema {
111
metadata: type_map! {
112
FieldType::Ticker => NoneOrOnce,
113
FieldType::Name => NoneOrOnce,
114
FieldType::ContractText => NoneOrOnce,
115
FieldType::Precision => NoneOrOnce
116
},
117
closes: type_map! {
118
OwnedRightsType::Renomination => Once
119
},
120
owned_rights: type_map! {
121
OwnedRightsType::Renomination => NoneOrOnce
122
},
123
public_rights: none!(),
124
abi: none!()
125
},
126
// Allows split of rights if they were occasionally allocated to the
127
// same UTXO, for instance both assets and issuance right. Without
128
// this type of transition either assets or inflation rights will be
129
// lost.
130
TransitionType::RightsSplit => TransitionSchema {
131
metadata: none!(),
132
closes: type_map! {
133
OwnedRightsType::Inflation => NoneOrMore,
134
OwnedRightsType::Assets => NoneOrMore,
135
OwnedRightsType::Epoch => NoneOrOnce,
136
OwnedRightsType::BurnReplace => NoneOrOnce,
137
OwnedRightsType::Renomination => NoneOrOnce
138
},
139
owned_rights: type_map! {
140
OwnedRightsType::Inflation => NoneOrMore,
141
OwnedRightsType::Assets => NoneOrMore,
142
OwnedRightsType::Epoch => NoneOrOnce,
143
OwnedRightsType::BurnReplace => NoneOrOnce,
144
OwnedRightsType::Renomination => NoneOrOnce
145
},
146
public_rights: none!(),
147
abi: bmap! {
148
// We must allocate exactly one or none rights per each
149
// right used as input (i.e. closed seal); plus we need to
150
// control that sum of inputs is equal to the sum of outputs
151
// for each of state types having assigned confidential
152
// amounts
153
TransitionAction::Validate => Procedure::Embedded(StandardProcedure::RightsSplit)
154
}
155
}
156
},
157
field_types: type_map! {
158
// Rational: if we will use just 26 letters of English alphabet (and
159
// we are not limited by them), we will have 26^8 possible tickers,
160
// i.e. > 208 trillions, which is sufficient amount
161
FieldType::Ticker => DataFormat::String(8),
162
FieldType::Name => DataFormat::String(256),
163
// Contract text may contain URL, text or text representation of
164
// Ricardian contract, up to 64kb. If the contract doesn't fit, a
165
// double SHA256 hash and URL should be used instead, pointing to
166
// the full contract text, where hash must be represented by a
167
// hexadecimal string, optionally followed by `\n` and text URL
168
FieldType::ContractText => DataFormat::String(core::u16::MAX),
169
FieldType::Precision => DataFormat::Unsigned(Bits::Bit8, 0, 18u128),
170
// We need this b/c allocated amounts are hidden behind Pedersen
171
// commitments
172
FieldType::IssuedSupply => DataFormat::Unsigned(Bits::Bit64, 0, core::u64::MAX as u128),
173
// Supply in either burn or burn-and-replace procedure
174
FieldType::BurnedSupply => DataFormat::Unsigned(Bits::Bit64, 0, core::u64::MAX as u128),
175
// While UNIX timestamps allow negative numbers; in context of RGB
176
// Schema, assets can't be issued in the past before RGB or Bitcoin
177
// even existed; so we prohibit all the dates before RGB release
178
// This timestamp is equal to 10/10/2020 @ 2:37pm (UTC)
179
FieldType::Timestamp => DataFormat::Integer(Bits::Bit64, 1602340666, core::i64::MAX as i128),
180
FieldType::HistoryProof => DataFormat::Bytes(core::u16::MAX),
181
FieldType::HistoryProofFormat => DataFormat::Enum(HistoryProofFormat::all()),
182
FieldType::BurnUtxo => DataFormat::TxOutPoint
183
},
184
owned_right_types: type_map! {
185
OwnedRightsType::Inflation => StateSchema {
186
// How much issuer can issue tokens on this path. If there is no
187
// limit, than `core::u64::MAX` / sum(inflation_assignments)
188
// must be used, as this will be a de-facto limit to the
189
// issuance
190
format: StateFormat::CustomData(DataFormat::Unsigned(Bits::Bit64, 0, core::u64::MAX as u128)),
191
// Validation involves other state data, so it is performed
192
// at the level of `issue` state transition
193
abi: none!()
194
},
195
OwnedRightsType::Assets => StateSchema {
196
format: StateFormat::DiscreteFiniteField(DiscreteFiniteFieldFormat::Unsigned64bit),
197
abi: bmap! {
198
// sum(inputs) == sum(outputs)
199
AssignmentAction::Validate => Procedure::Embedded(StandardProcedure::NoInflationBySum)
200
}
201
},
202
OwnedRightsType::Epoch => StateSchema {
203
format: StateFormat::Declarative,
204
abi: none!()
205
},
206
OwnedRightsType::BurnReplace => StateSchema {
207
format: StateFormat::Declarative,
208
abi: none!()
209
},
210
OwnedRightsType::Renomination => StateSchema {
211
format: StateFormat::Declarative,
212
abi: none!()
213
}
214
},
215
public_right_types: none!(),
216
}
Copied!

Subschemata

Rationale

Include from
Last modified 3mo ago
Export as PDF
Copy link