From fb1253ccc649772049d16c9ab23205064fab3dca Mon Sep 17 00:00:00 2001 From: "Dr. Maxim Orlovsky" Date: Sun, 18 Dec 2022 16:05:04 +0100 Subject: [PATCH 01/10] Rewrite RGB21 spec using Contractum & concept of interfaces --- lnpbp-0021.md | 358 ++++++++++++++++++++++---------------------------- 1 file changed, 158 insertions(+), 200 deletions(-) diff --git a/lnpbp-0021.md b/lnpbp-0021.md index 849a191..76e7e89 100644 --- a/lnpbp-0021.md +++ b/lnpbp-0021.md @@ -1,11 +1,13 @@ ``` LNPBP: 0021 Vertical: Smart contracts -Title: RGB non-fungible assets schema for collectibles (RGB-21) -Authors: Dr Maxim Orlovsky , +Title: RGB non-fungible assets interface for collectibles (RGB-21) +Authors: Dr Maxim Orlovsky , + Hunter Trello, + Federico Tenga, Carlos Roldan, + Olgsa Ukolova, Giacomo Zucco, - Olgsa Ukolova Comments-URI: Status: Proposal Type: Standards Track @@ -13,201 +15,157 @@ Created: 2020-09-10 License: CC0-1.0 ``` -- [x] Unique tokens & token-specfic data -- [x] Issue control -- [x] Generic token data, internal or external, in different formats -- [x] Engravings (any why Schema subclassing is required) -- [x] LockUTXOs and descriptors for proof of reserves -- [x] Renominations -- [x] Rights splits - -```rust -Schema { - rgb_features: none!(), - root_id: none!(), - genesis: GenesisSchema { - metadata: type_map! { - FieldType::Name => Once, - FieldType::Description => NoneOrOnce, - FieldType::Data => NoneOrMore, - FieldType::DataFormat => NoneOrOnce, - // Proof of reserves UTXO - FieldType::LockUtxo => NoneOrMore, - // Proof of reserves scriptPubkey descriptor used for - // verification - FieldType::LockDescriptor => NoneOrUpTo(32), - FieldType::Timestamp => Once, - FieldType::NftSource => NoneOrMore, - FieldType::Salt => Once - }, - owned_rights: type_map! { - OwnedRightsType::Inflation => NoneOrOnce, - OwnedRightsType::Renomination => NoneOrOnce, - OwnedRightsType::Ownership => OnceOrMore - }, - public_rights: none!(), - abi: bmap! { - // Here we validate hash uniqueness of NftSource values and that - // there is always one ownership state per NftSource matching - // its hash - // and verification of proof of reserves - GenesisAction::Validate => Procedure::Embedded(StandardProcedure::NonfungibleInflation) - }, - }, - extensions: bmap! {}, - transitions: type_map! { - TransitionType::Issue => TransitionSchema { - metadata: type_map! { - // Proof of reserves UTXO - FieldType::LockUtxo => NoneOrMore, - // Proof of reserves scriptPubkey descriptor used for - // verification - FieldType::LockDescriptor => NoneOrUpTo(32), - FieldType::NftSource => NoneOrMore, - FieldType::Salt => Once - }, - closes: type_map! { - OwnedRightsType::Inflation => Once - }, - owned_rights: type_map! { - OwnedRightsType::Inflation => NoneOrOnce, - OwnedRightsType::Ownership => OnceOrMore - }, - public_rights: none!(), - abi: bmap! { - // Here we validate hash uniqueness of NftSource values and that - // there is always one ownership state per NftSource matching - // its hash, plus the fact that - // count(in(inflation)) >= count(out(inflation), out(nft_source)) - // and verification of proof of reserves - TransitionAction::Validate => Procedure::Embedded(StandardProcedure::NonfungibleInflation) - } - }, - TransitionType::Transfer => TransitionSchema { - metadata: type_map! { - // By default, use 0 - FieldType::Salt => Once - }, - closes: type_map! { - OwnedRightsType::Ownership => OnceOrMore - }, - owned_rights: type_map! { - OwnedRightsType::Ownership => OnceOrMore - }, - public_rights: none!(), - abi: none!() - }, - // One engraving per set of tokens - TransitionType::Engraving => TransitionSchema { - metadata: type_map! { - FieldType::Data => NoneOrMore, - FieldType::DataFormat => NoneOrOnce, - // By default, use 0 - FieldType::Salt => Once - }, - closes: type_map! { - OwnedRightsType::Ownership => OnceOrMore - }, - owned_rights: type_map! { - OwnedRightsType::Ownership => OnceOrMore - }, - public_rights: none!(), - abi: none!() - }, - TransitionType::Renomination => TransitionSchema { - metadata: type_map! { - FieldType::Name => NoneOrOnce, - FieldType::Description => NoneOrOnce, - FieldType::Data => NoneOrMore, - FieldType::DataFormat => NoneOrOnce - }, - closes: type_map! { - OwnedRightsType::Renomination => Once - }, - owned_rights: type_map! { - OwnedRightsType::Renomination => NoneOrOnce - }, - public_rights: none!(), - abi: none!() - }, - // Allows split of rights if they were occasionally allocated to the - // same UTXO, for instance both assets and issuance right. Without - // this type of transition either assets or inflation rights will be - // lost. - TransitionType::RightsSplit => TransitionSchema { - metadata: type_map! { - FieldType::Salt => Once - }, - closes: type_map! { - OwnedRightsType::Inflation => NoneOrMore, - OwnedRightsType::Ownership => NoneOrMore, - OwnedRightsType::Renomination => NoneOrOnce - }, - owned_rights: type_map! { - OwnedRightsType::Inflation => NoneOrMore, - OwnedRightsType::Ownership => NoneOrMore, - OwnedRightsType::Renomination => NoneOrOnce - }, - public_rights: none!(), - abi: bmap! { - // We must allocate exactly one or none rights per each - // right used as input (i.e. closed seal); plus we need to - // control that sum of inputs is equal to the sum of outputs - // for each of state types having assigned confidential - // amounts - TransitionAction::Validate => Procedure::Embedded(StandardProcedure::RightsSplit) - } - } - }, - field_types: type_map! { - FieldType::Name => DataFormat::String(256), - FieldType::Description => DataFormat::String(core::u16::MAX), - FieldType::Data => DataFormat::Bytes(core::u16::MAX), - FieldType::DataFormat => DataFormat::Unsigned(Bits::Bit16, 0, core::u16::MAX as u128), - // While UNIX timestamps allow negative numbers; in context of RGB - // Schema, assets can't be issued in the past before RGB or Bitcoin - // even existed; so we prohibit all the dates before RGB release - // This timestamp is equal to 10/10/2020 @ 2:37pm (UTC) - the same - // as for RGB-20 standard. - FieldType::Timestamp => DataFormat::Integer(Bits::Bit64, 1602340666, core::i64::MAX as i128), - FieldType::LockUtxo => DataFormat::TxOutPoint, - FieldType::LockDescriptor => DataFormat::String(core::u16::MAX), - FieldType::BurnUtxo => DataFormat::TxOutPoint, - // This type is used to "shift" unique tokens ids if there was a - // collision between them - FieldType::Salt => DataFormat::Unsigned(Bits::Bit32, 0, core::u32::MAX as u128), - // Hash of these data serves as a unique NFT identifier; - // if NFT contains no intrinsic data than simply put any unique - // value here (like counter value, increased with each token); - // it must be unique only within single issuance transition - FieldType::NftSource => DataFormat::Bytes(core::u16::MAX) - }, - owned_right_types: type_map! { - OwnedRightsType::Inflation => StateSchema { - // How much issuer can issue tokens on this path - format: StateFormat::CustomData(DataFormat::Unsigned(Bits::Bit64, 0, core::u64::MAX as u128)), - abi: none!() - }, - OwnedRightsType::Ownership => StateSchema { - // This is unique token identifier, which is - // SHA256(SHA256(nft_source_state), issue_transition_id) - // convoluted to 32-bits with XOR operation and then XORed with - // salt value from state transition metadata. - // NB: It is unique inside single state transition only, not - // globally. For global unique id use non-convoluted hash value. - format: StateFormat::CustomData(DataFormat::Unsigned(Bits::Bit32, 0, core::u32::MAX as u128)), - abi: bmap! { - // Here we ensure that each unique state value is - // transferred once and only once (using "salt" value for - // collision resoultion) - AssignmentAction::Validate => Procedure::Embedded(StandardProcedure::IdentityTransfer) - } - }, - OwnedRightsType::Renomination => StateSchema { - format: StateFormat::Declarative, - abi: none!() - } - }, - public_right_types: none!(), -} +- [Abstract](#abstract) +- [Background](#background) +- [Motivation](#motivation) +- [Design](#design) +- [Specification](#specification) +- [Compatibility](#compatibility) +- [Rationale](#rationale) +- [Reference implementation](#reference-implementation) +- [Acknowledgements](#acknowledgements) +- [References](#references) +- [Copyright](#copyright) +- [Test vectors](#test-vectors) + + +## Abstract + + +## Background + + +## Motivation + + +## Design + +- [x] Media as URI (which can be attachments distributed with Storm or usual URLs) +- [x] Small media ("previews" if given together with large media) +- [x] Fraction of assets +- [x] Engravings +- [x] Reserves +- [x] Possible decentralized issue + + +## Specification + +Interface specification is the following Contractum code: + +```haskell +-- # Defining main data structures + +-- collectibles are usually scarse, so we limit their max number to 64k +data ItemsCount :: U16 + +-- each collectible item is unique and must have an id +data TokenId :: U16 + +-- Collectibles are owned in fractions of a single item; here the owned +-- fraction means `1/F`. Ownership of the full item is specified `F=1`; +-- half of an item as `F=2` etc. +data OwnedFraction :: U64 + +data TxOut :: txid [Byte ^ 32], vout U16 + +-- allocation of a single token or its fraction to some transaction output +data Allocation :: TxOut, TokenId, OwnedFraction + +-- right over certain amount of collectible items; right owner may be unknown +data AssetControl :: TxOut?, ItemsCount + +data Media :: + type MimeType, + data [Byte] + +data Attachment :: + type MimeType, + uri: Uri + +data Token :: + id Id, + name [Ascii ^ 1..40], + details [Unicode ^ 40..256]?, + media Media?, + attachment Attachment?, + reserves: TxOut? -- output containing locked bitcoins; how reserves are + -- proved is a matter of a specific schema implementation + +data Nomination :: + ticker [Ascii ^ 1..8], + name [Ascii ^ 1..40], + details [Unicode ^ 40..256]?, + contract [Unicode]??, + isFractional: Bool + +data CollectionInfo :: + knownInfo Nomination, + origInfo Nomination, + isFinalInfo Bool, + renominationRight TxOut?, + + isSupplyKnown Bool, -- indicates that all issues, burn and reissues are known + supplyKnown Amount, -- returns information about known cirtulating supply + supplyLimit Amount, -- maximum possible asset inflation + pastIssues [AssetControl], -- known past issue operations + futureIssues [AssetControl], -- known future issue operations + knownBurns [AssetControl], -- known past burn operations + knownReissues [AssetControl], -- known past reissue operations + + tokens [(Token)] + -- known asset amounts allocated to known UTXOs + knownAllocations [(Allocation, [Engraving])] + +interface RGB21 :: CollectionInfo + op transfer :: inputs [TxOut ^ 1..] + -> beneficiaries [Allocation] + !! -- options for operation failure: + outputSpent(TxOut) + | noTokens(TxOut) + | inequalFractions(TokenId) + | nonFractionalToken + + -- question mark denotes optional operation, which may not be supported by + -- some of schemata implementing the intrface + + op? engrave :: inputs [TxOut ^ 1..] + -> beneficiaries [(Allocation, Engraving?)] + !! outputSpent(TxOut) + | noTokens(TxOut) + | inequalFractions(TokenId) + | nonFractionalToken + | noEngravings + + op? issue :: usingRight TxOut, + -> nextRight TxOut?, tokens [Token], beneficiaries [Allocation] + !! invalidRight + + -- decentralized issue + op? dcntrlIssue -> tokens [Token], + beneficiaries [Allocation] + !! noReserves(TokenId) + | invalidReserves(TxOut) + + op? renominate :: usingRight TxOut + -> nextRight TxOut?, newNomination AssetInfo + !! invalidRight ``` + +## Compatibility + + +## Rationale + + +## Reference implementation + + +## Acknowledgements + + +## References + + +## Copyright + +This document is licensed under the Creative Commons CC0 1.0 Universal license. From e3255a1ac928aabf2ba56fbf58e942d2e148857c Mon Sep 17 00:00:00 2001 From: "Dr. Maxim Orlovsky" Date: Sun, 18 Dec 2022 16:24:24 +0100 Subject: [PATCH 02/10] RGB21: Improve reserve proofs --- lnpbp-0021.md | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/lnpbp-0021.md b/lnpbp-0021.md index 76e7e89..7a2ac3c 100644 --- a/lnpbp-0021.md +++ b/lnpbp-0021.md @@ -82,14 +82,18 @@ data Attachment :: type MimeType, uri: Uri +data POR :: -- proof of reserves + reserves TxOut, + proof [Bytes] -- schema-specific proof + data Token :: id Id, name [Ascii ^ 1..40], details [Unicode ^ 40..256]?, media Media?, attachment Attachment?, - reserves: TxOut? -- output containing locked bitcoins; how reserves are - -- proved is a matter of a specific schema implementation + reserves: POR? -- output containing locked bitcoins; how reserves are + -- proved is a matter of a specific schema implementation data Nomination :: ticker [Ascii ^ 1..8], @@ -139,12 +143,13 @@ interface RGB21 :: CollectionInfo op? issue :: usingRight TxOut, -> nextRight TxOut?, tokens [Token], beneficiaries [Allocation] !! invalidRight + | invalidReserves(POR) -- decentralized issue op? dcntrlIssue -> tokens [Token], beneficiaries [Allocation] !! noReserves(TokenId) - | invalidReserves(TxOut) + | invalidReserves(POR) op? renominate :: usingRight TxOut -> nextRight TxOut?, newNomination AssetInfo From bd7dd75c6a4dfc0cab81f110bad014468d1c4c39 Mon Sep 17 00:00:00 2001 From: "Dr. Maxim Orlovsky" Date: Sun, 18 Dec 2022 22:01:34 +0100 Subject: [PATCH 03/10] RGB21: Improve specification language --- lnpbp-0021.md | 90 ++++++++++++++++++++++----------------------------- 1 file changed, 38 insertions(+), 52 deletions(-) diff --git a/lnpbp-0021.md b/lnpbp-0021.md index 7a2ac3c..0b0ca68 100644 --- a/lnpbp-0021.md +++ b/lnpbp-0021.md @@ -69,10 +69,7 @@ data OwnedFraction :: U64 data TxOut :: txid [Byte ^ 32], vout U16 -- allocation of a single token or its fraction to some transaction output -data Allocation :: TxOut, TokenId, OwnedFraction - --- right over certain amount of collectible items; right owner may be unknown -data AssetControl :: TxOut?, ItemsCount +data Allocation :: TokenId, OwnedFraction data Media :: type MimeType, @@ -84,7 +81,7 @@ data Attachment :: data POR :: -- proof of reserves reserves TxOut, - proof [Bytes] -- schema-specific proof + proof [Byte] -- schema-specific proof data Token :: id Id, @@ -92,68 +89,57 @@ data Token :: details [Unicode ^ 40..256]?, media Media?, attachment Attachment?, - reserves: POR? -- output containing locked bitcoins; how reserves are - -- proved is a matter of a specific schema implementation + reserves POR? -- output containing locked bitcoins; how reserves are + -- proved is a matter of a specific schema implementation data Nomination :: ticker [Ascii ^ 1..8], name [Ascii ^ 1..40], details [Unicode ^ 40..256]?, contract [Unicode]??, - isFractional: Bool - -data CollectionInfo :: - knownInfo Nomination, - origInfo Nomination, - isFinalInfo Bool, - renominationRight TxOut?, - - isSupplyKnown Bool, -- indicates that all issues, burn and reissues are known - supplyKnown Amount, -- returns information about known cirtulating supply - supplyLimit Amount, -- maximum possible asset inflation - pastIssues [AssetControl], -- known past issue operations - futureIssues [AssetControl], -- known future issue operations - knownBurns [AssetControl], -- known past burn operations - knownReissues [AssetControl], -- known past reissue operations - - tokens [(Token)] - -- known asset amounts allocated to known UTXOs - knownAllocations [(Allocation, [Engraving])] - -interface RGB21 :: CollectionInfo - op transfer :: inputs [TxOut ^ 1..] - -> beneficiaries [Allocation] + +interface RGB21 + global Name :: Nomination + global Tokens :: [(Token, [Engraving])] + global isFractional :: Bool + + owned Allocations+ :: Allocation + owned IssueRight* :: Amount + owned RenominationRight + + -- returns information about known circulating supply + read supplyKnown :: Amount + count Self.state["Tokens"] + -- sum Self.ops["issue"]..closed["usingRight"].state ?? 0 + + -- maximum possible asset inflation + read supplyLimit :: Amount + sum Self.IssueRight..state ?? 0 + + read isCirculationKnown :: Bool + all Self.ops["issue"]..stateKnown + + op transfer :: inputs [Allocation+] -> beneficiaries [Allocation] !! -- options for operation failure: - outputSpent(TxOut) - | noTokens(TxOut) - | inequalFractions(TokenId) + inequalFractions(TokenId) | nonFractionalToken -- question mark denotes optional operation, which may not be supported by -- some of schemata implementing the intrface - op? engrave :: inputs [TxOut ^ 1..] - -> beneficiaries [(Allocation, Engraving?)] - !! outputSpent(TxOut) - | noTokens(TxOut) - | inequalFractions(TokenId) - | nonFractionalToken - | noEngravings + op? engrave :: Allocation -> Allocation + <- Engraving - op? issue :: usingRight TxOut, - -> nextRight TxOut?, tokens [Token], beneficiaries [Allocation] - !! invalidRight - | invalidReserves(POR) + op? issue :: IssueRight -> IssueRight, beneficiaries {Allocation} + <- tokens {Token} + !! invalidReserves(POR) -- decentralized issue - op? dcntrlIssue -> tokens [Token], - beneficiaries [Allocation] - !! noReserves(TokenId) - | invalidReserves(POR) - - op? renominate :: usingRight TxOut - -> nextRight TxOut?, newNomination AssetInfo - !! invalidRight + op? dcntrlIssue -> tokens {Token}, beneficiaries {Allocation} + !! invalidReserves(POR) + + op? renominate :: RenominationRight -> RenominationRight + <- Nomination ``` ## Compatibility From 7892ed983ddeb7689ababfa7339542409b7ada2f Mon Sep 17 00:00:00 2001 From: "Dr. Maxim Orlovsky" Date: Tue, 20 Dec 2022 10:06:01 +0100 Subject: [PATCH 04/10] RGB21: fix author name spelling Co-authored-by: Hunter Trujillo --- lnpbp-0021.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lnpbp-0021.md b/lnpbp-0021.md index 0b0ca68..6cad8ad 100644 --- a/lnpbp-0021.md +++ b/lnpbp-0021.md @@ -3,10 +3,10 @@ LNPBP: 0021 Vertical: Smart contracts Title: RGB non-fungible assets interface for collectibles (RGB-21) Authors: Dr Maxim Orlovsky , - Hunter Trello, + Hunter Trujillo, Federico Tenga, Carlos Roldan, - Olgsa Ukolova, + Olga Ukolova, Giacomo Zucco, Comments-URI: Status: Proposal From c4000cfdf65618a70e6b8a9b4b459fcf616d635f Mon Sep 17 00:00:00 2001 From: "Dr. Maxim Orlovsky" Date: Tue, 20 Dec 2022 10:14:23 +0100 Subject: [PATCH 05/10] RGB21: fix token id type --- lnpbp-0021.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lnpbp-0021.md b/lnpbp-0021.md index 6cad8ad..100b92f 100644 --- a/lnpbp-0021.md +++ b/lnpbp-0021.md @@ -84,7 +84,7 @@ data POR :: -- proof of reserves proof [Byte] -- schema-specific proof data Token :: - id Id, + id TokenId, name [Ascii ^ 1..40], details [Unicode ^ 40..256]?, media Media?, From 31d2b0e1cbdfe6bd2b777fbf60d19bf469c23b8e Mon Sep 17 00:00:00 2001 From: "Dr. Maxim Orlovsky" Date: Tue, 20 Dec 2022 18:18:55 +0100 Subject: [PATCH 06/10] RGB21: Apply suggestions from code review Co-authored-by: Hunter Trujillo --- lnpbp-0021.md | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/lnpbp-0021.md b/lnpbp-0021.md index 100b92f..ca37eed 100644 --- a/lnpbp-0021.md +++ b/lnpbp-0021.md @@ -102,10 +102,12 @@ interface RGB21 global Name :: Nomination global Tokens :: [(Token, [Engraving])] global isFractional :: Bool +global Registry :: Auxiliary owned Allocations+ :: Allocation owned IssueRight* :: Amount owned RenominationRight +owned ControlRight -- returns information about known circulating supply read supplyKnown :: Amount @@ -125,7 +127,7 @@ interface RGB21 | nonFractionalToken -- question mark denotes optional operation, which may not be supported by - -- some of schemata implementing the intrface + -- some of schemata implementing the interface op? engrave :: Allocation -> Allocation <- Engraving @@ -135,9 +137,13 @@ interface RGB21 !! invalidReserves(POR) -- decentralized issue - op? dcntrlIssue -> tokens {Token}, beneficiaries {Allocation} + op? decentralizedIssue -> tokens {Token}, beneficiaries {Allocation} !! invalidReserves(POR) +-- updates registry of auxiliary data to a new version +op? update :: controlRight -> controlRight + <- Registry + op? renominate :: RenominationRight -> RenominationRight <- Nomination ``` From 05ad82559a20d7d92783f6158e3b2064897843cc Mon Sep 17 00:00:00 2001 From: "Dr. Maxim Orlovsky" Date: Wed, 21 Dec 2022 11:26:12 +0100 Subject: [PATCH 07/10] RGB21: allow multople attachments --- lnpbp-0021.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/lnpbp-0021.md b/lnpbp-0021.md index ca37eed..69903c8 100644 --- a/lnpbp-0021.md +++ b/lnpbp-0021.md @@ -87,8 +87,9 @@ data Token :: id TokenId, name [Ascii ^ 1..40], details [Unicode ^ 40..256]?, - media Media?, - attachment Attachment?, + preview Media?, -- always embedded preview media < 64kb + media Attachment?, -- external media which is the main media for the token + attachments { U8 ^ ..20 -> Attachment } -- auxillary attachments by type (up to 20 attachments) reserves POR? -- output containing locked bitcoins; how reserves are -- proved is a matter of a specific schema implementation From e37dfb44b5e793a81e7515f0fa94892318c11b1d Mon Sep 17 00:00:00 2001 From: "Dr. Maxim Orlovsky" Date: Wed, 21 Dec 2022 11:27:24 +0100 Subject: [PATCH 08/10] RGB21: auxiliary data --- lnpbp-0021.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/lnpbp-0021.md b/lnpbp-0021.md index 69903c8..b5bd94a 100644 --- a/lnpbp-0021.md +++ b/lnpbp-0021.md @@ -99,6 +99,19 @@ data Nomination :: details [Unicode ^ 40..256]?, contract [Unicode]??, +data Auxiliary :: + -- list of allowed sources + sources [Source] + + -- each attachment type is a mapping from attachment id + -- (used as `Token.attachments` keys) to a short Ascii string + -- verbally explaining the type of the attachment for the UI + -- (like "sample" etc). + attachmentTypes { U8 ^ ..32 -> [Ascii ^ 1..20] } + +data Source :: url(Proto, Dns) | urn(UrnPrefix) | storm(NodeAddr) +data Proto :: http | https | httpxk | ws | wss | wssxk + interface RGB21 global Name :: Nomination global Tokens :: [(Token, [Engraving])] From a75d3352095751725b0a8f6f5ef916f077c21eaa Mon Sep 17 00:00:00 2001 From: "Dr. Maxim Orlovsky" Date: Thu, 22 Dec 2022 17:10:26 +0100 Subject: [PATCH 09/10] RGB21: Apply suggestions from code review --- lnpbp-0021.md | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/lnpbp-0021.md b/lnpbp-0021.md index b5bd94a..2fdcc53 100644 --- a/lnpbp-0021.md +++ b/lnpbp-0021.md @@ -56,7 +56,7 @@ Interface specification is the following Contractum code: -- # Defining main data structures -- collectibles are usually scarse, so we limit their max number to 64k -data ItemsCount :: U16 +data ItemsCount :: U32 -- each collectible item is unique and must have an id data TokenId :: U16 @@ -93,7 +93,7 @@ data Token :: reserves POR? -- output containing locked bitcoins; how reserves are -- proved is a matter of a specific schema implementation -data Nomination :: +data Denomination :: ticker [Ascii ^ 1..8], name [Ascii ^ 1..40], details [Unicode ^ 40..256]?, @@ -113,14 +113,15 @@ data Source :: url(Proto, Dns) | urn(UrnPrefix) | storm(NodeAddr) data Proto :: http | https | httpxk | ws | wss | wssxk interface RGB21 - global Name :: Nomination + global Name :: Denomination global Tokens :: [(Token, [Engraving])] global isFractional :: Bool -global Registry :: Auxiliary + global Registry :: Auxiliary owned Allocations+ :: Allocation owned IssueRight* :: Amount - owned RenominationRight + owned DenominationRight? + owned ControlRight -- returns information about known circulating supply @@ -158,7 +159,7 @@ owned ControlRight op? update :: controlRight -> controlRight <- Registry - op? renominate :: RenominationRight -> RenominationRight + op? rename :: DenominationRight -> DenominationRight? <- Denomination <- Nomination ``` From 6529733fa811dd0de1144afe7277c5d4b07387a4 Mon Sep 17 00:00:00 2001 From: "Dr. Maxim Orlovsky" Date: Thu, 20 Apr 2023 13:09:31 +0200 Subject: [PATCH 10/10] Apply suggestions from code review --- lnpbp-0021.md | 37 ++++++++++++++----------------------- 1 file changed, 14 insertions(+), 23 deletions(-) diff --git a/lnpbp-0021.md b/lnpbp-0021.md index 2fdcc53..7c5932a 100644 --- a/lnpbp-0021.md +++ b/lnpbp-0021.md @@ -5,6 +5,7 @@ Title: RGB non-fungible assets interface for collectibles (RGB-21) Authors: Dr Maxim Orlovsky , Hunter Trujillo, Federico Tenga, + Zoe FaltibĂ , Carlos Roldan, Olga Ukolova, Giacomo Zucco, @@ -71,13 +72,15 @@ data TxOut :: txid [Byte ^ 32], vout U16 -- allocation of a single token or its fraction to some transaction output data Allocation :: TokenId, OwnedFraction +data Engraving :: appliedTo TokenId, content Media + data Media :: type MimeType, data [Byte] data Attachment :: type MimeType, - uri: Uri + digest: [U8 ^ 32] -- this can be any type of 32-byte hash, like SHA256(d), BLACKE3 etc data POR :: -- proof of reserves reserves TxOut, @@ -89,7 +92,7 @@ data Token :: details [Unicode ^ 40..256]?, preview Media?, -- always embedded preview media < 64kb media Attachment?, -- external media which is the main media for the token - attachments { U8 ^ ..20 -> Attachment } -- auxillary attachments by type (up to 20 attachments) + attachments { U8 -> ^ ..20 Attachment } -- auxiliary attachments by type (up to 20 attachments) reserves POR? -- output containing locked bitcoins; how reserves are -- proved is a matter of a specific schema implementation @@ -99,31 +102,23 @@ data Denomination :: details [Unicode ^ 40..256]?, contract [Unicode]??, -data Auxiliary :: - -- list of allowed sources - sources [Source] - - -- each attachment type is a mapping from attachment id - -- (used as `Token.attachments` keys) to a short Ascii string - -- verbally explaining the type of the attachment for the UI - -- (like "sample" etc). - attachmentTypes { U8 ^ ..32 -> [Ascii ^ 1..20] } + -- each attachment type is a mapping from attachment id + -- (used as `Token.attachments` keys) to a short Ascii string + -- verbally explaining the type of the attachment for the UI + -- (like "sample" etc). +data AttachmentType :: id U8, description [Ascii ^ 1..20] -data Source :: url(Proto, Dns) | urn(UrnPrefix) | storm(NodeAddr) -data Proto :: http | https | httpxk | ws | wss | wssxk interface RGB21 global Name :: Denomination - global Tokens :: [(Token, [Engraving])] + global Tokens :: Token+ + global Engravings :: Engraving+ global isFractional :: Bool - global Registry :: Auxiliary + global AttachmentTypes :: AttachmentType+ owned Allocations+ :: Allocation owned IssueRight* :: Amount owned DenominationRight? - -owned ControlRight - -- returns information about known circulating supply read supplyKnown :: Amount count Self.state["Tokens"] @@ -148,17 +143,13 @@ owned ControlRight <- Engraving op? issue :: IssueRight -> IssueRight, beneficiaries {Allocation} - <- tokens {Token} + <- tokens {Token}, newAttachmentTypes {attachmentType}* !! invalidReserves(POR) -- decentralized issue op? decentralizedIssue -> tokens {Token}, beneficiaries {Allocation} !! invalidReserves(POR) --- updates registry of auxiliary data to a new version -op? update :: controlRight -> controlRight - <- Registry - op? rename :: DenominationRight -> DenominationRight? <- Denomination <- Nomination ```