From 1a05b8c17e67fd32d2dfd407ce7fa1c6494ece34 Mon Sep 17 00:00:00 2001 From: "Dr. Maxim Orlovsky" Date: Sun, 18 Dec 2022 14:35:18 +0100 Subject: [PATCH 1/6] Rewrite RGB20 spec using Contractum & concept of interfaces --- lnpbp-0020.md | 332 ++++++++++++++++---------------------------------- 1 file changed, 105 insertions(+), 227 deletions(-) diff --git a/lnpbp-0020.md b/lnpbp-0020.md index b4ff183..f5247b2 100644 --- a/lnpbp-0020.md +++ b/lnpbp-0020.md @@ -1,7 +1,7 @@ ``` LNPBP: 0020 Vertical: Smart contracts -Title: RGB fungible assets schema (RGB-20) +Title: RGB fungible assets interface (RGB-20) Authors: Dr Maxim Orlovsky , Giacomo Zucco, Marco Amadori, @@ -10,240 +10,105 @@ Authors: Dr Maxim Orlovsky , Sabina Sachtachtinskagia, Martino Salvetti Comments-URI: -Status: Final +Status: Proposal Type: Standards Track Created: 2019-09-23 -Finalized: 2020-10-10 +Finalized: 2022-12-18 License: CC0-1.0 ``` -Schema ID: `sch19s8js2gyxvtyzztp82l4tt4gr3x8m28yrgks93exsfuwc5u4fqlqf46ah5` - -Encoded schema data: `schema1qxx4qkgjsgcqcl2atrzgmugynnpuk7q5c7dcplkppl9jr0ywx75xnk3zyvup3p3ke99auju22h9734efqs6gfppkg6qcyy69a8uhnw7czt37ckszd950xwwn9mjr59payf3sd2yuezjdy5vu5jdkew7mr78prvvnjkg0x34qyf6fdfsxyd4fk6guzrpuuxp7exgkyhlntx8ruw9j2s2e7dt8sgjhczjkk5e2a3np886u86mq5ge92r5ckde9gr4htt2td66gkzvypm2hwpsr8gdm6vqzmgca3ltn8j0qqkd0rl5s6f3nllngjfldlt7kz7uarne8w0zkhwpr90k0smcxk48dx` - -Schema source: -```rust -Schema { - rgb_features: none!(), - root_id: none!(), - genesis: GenesisSchema { - metadata: type_map! { - FieldType::Ticker => Once, - FieldType::Name => Once, - FieldType::ContractText => NoneOrOnce, - FieldType::Precision => Once, - FieldType::Timestamp => Once, - FieldType::IssuedSupply => Once - }, - owned_rights: type_map! { - OwnedRightsType::Inflation => NoneOrMore, - OwnedRightsType::Epoch => NoneOrOnce, - OwnedRightsType::Assets => NoneOrMore, - OwnedRightsType::Renomination => NoneOrOnce - }, - public_rights: none!(), - abi: none!(), - }, - extensions: none!(), - transitions: type_map! { - TransitionType::Issue => TransitionSchema { - metadata: type_map! { - FieldType::IssuedSupply => Once - }, - closes: type_map! { - OwnedRightsType::Inflation => Once - }, - owned_rights: type_map! { - OwnedRightsType::Inflation => NoneOrMore, - OwnedRightsType::Epoch => NoneOrOnce, - OwnedRightsType::Assets => NoneOrMore - }, - public_rights: none!(), - abi: bmap! { - // sum(in(inflation)) >= sum(out(inflation), out(assets)) - TransitionAction::Validate => Procedure::Embedded(StandardProcedure::FungibleInflation) - } - }, - TransitionType::Transfer => TransitionSchema { - metadata: type_map! {}, - closes: type_map! { - OwnedRightsType::Assets => NoneOrMore - }, - owned_rights: type_map! { - OwnedRightsType::Assets => NoneOrMore - }, - public_rights: none!(), - abi: none!() - }, - TransitionType::Epoch => TransitionSchema { - metadata: none!(), - closes: type_map! { - OwnedRightsType::Epoch => Once - }, - owned_rights: type_map! { - OwnedRightsType::Epoch => NoneOrOnce, - OwnedRightsType::BurnReplace => NoneOrOnce - }, - public_rights: none!(), - abi: none!() - }, - TransitionType::Burn => TransitionSchema { - metadata: type_map! { - FieldType::BurnedSupply => Once, - // Normally issuer should aggregate burned assets into a - // single UTXO; however if burn happens as a result of - // mistake this will be impossible, so we allow to have - // multiple burned UTXOs as a part of a single operation - FieldType::BurnUtxo => OnceOrUpTo(None), - FieldType::HistoryProofFormat => Once, - FieldType::HistoryProof => NoneOrMore, - }, - closes: type_map! { - OwnedRightsType::BurnReplace => Once - }, - owned_rights: type_map! { - OwnedRightsType::BurnReplace => NoneOrOnce - }, - public_rights: none!(), - abi: bmap! { - TransitionAction::Validate => Procedure::Embedded(StandardProcedure::ProofOfBurn) - } - }, - TransitionType::BurnAndReplace => TransitionSchema { - metadata: type_map! { - FieldType::BurnedSupply => Once, - // Normally issuer should aggregate burned assets into a - // single UTXO; however if burn happens as a result of - // mistake this will be impossible, so we allow to have - // multiple burned UTXOs as a part of a single operation - FieldType::BurnUtxo => OnceOrMore, - FieldType::HistoryProofFormat => Once, - FieldType::HistoryProof => NoneOrMore - }, - closes: type_map! { - OwnedRightsType::BurnReplace => Once - }, - owned_rights: type_map! { - OwnedRightsType::BurnReplace => NoneOrOnce, - OwnedRightsType::Assets => OnceOrMore - }, - public_rights: none!(), - abi: bmap! { - TransitionAction::Validate => Procedure::Embedded(StandardProcedure::ProofOfBurn) - } - }, - TransitionType::Renomination => TransitionSchema { - metadata: type_map! { - FieldType::Ticker => NoneOrOnce, - FieldType::Name => NoneOrOnce, - FieldType::ContractText => NoneOrOnce, - FieldType::Precision => 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: none!(), - closes: type_map! { - OwnedRightsType::Inflation => NoneOrMore, - OwnedRightsType::Assets => NoneOrMore, - OwnedRightsType::Epoch => NoneOrOnce, - OwnedRightsType::BurnReplace => NoneOrOnce, - OwnedRightsType::Renomination => NoneOrOnce - }, - owned_rights: type_map! { - OwnedRightsType::Inflation => NoneOrMore, - OwnedRightsType::Assets => NoneOrMore, - OwnedRightsType::Epoch => NoneOrOnce, - OwnedRightsType::BurnReplace => NoneOrOnce, - 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! { - // Rational: if we will use just 26 letters of English alphabet (and - // we are not limited by them), we will have 26^8 possible tickers, - // i.e. > 208 trillions, which is sufficient amount - FieldType::Ticker => DataFormat::String(8), - FieldType::Name => DataFormat::String(256), - // Contract text may contain URL, text or text representation of - // Ricardian contract, up to 64kb. If the contract doesn't fit, a - // double SHA256 hash and URL should be used instead, pointing to - // the full contract text, where hash must be represented by a - // hexadecimal string, optionally followed by `\n` and text URL - FieldType::ContractText => DataFormat::String(core::u16::MAX), - FieldType::Precision => DataFormat::Unsigned(Bits::Bit8, 0, 18u128), - // We need this b/c allocated amounts are hidden behind Pedersen - // commitments - FieldType::IssuedSupply => DataFormat::Unsigned(Bits::Bit64, 0, core::u64::MAX as u128), - // Supply in either burn or burn-and-replace procedure - FieldType::BurnedSupply => DataFormat::Unsigned(Bits::Bit64, 0, core::u64::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) - FieldType::Timestamp => DataFormat::Integer(Bits::Bit64, 1602340666, core::i64::MAX as i128), - FieldType::HistoryProof => DataFormat::Bytes(core::u16::MAX), - FieldType::HistoryProofFormat => DataFormat::Enum(HistoryProofFormat::all()), - FieldType::BurnUtxo => DataFormat::TxOutPoint - }, - owned_right_types: type_map! { - OwnedRightsType::Inflation => StateSchema { - // How much issuer can issue tokens on this path. If there is no - // limit, than `core::u64::MAX` / sum(inflation_assignments) - // must be used, as this will be a de-facto limit to the - // issuance - format: StateFormat::CustomData(DataFormat::Unsigned(Bits::Bit64, 0, core::u64::MAX as u128)), - // Validation involves other state data, so it is performed - // at the level of `issue` state transition - abi: none!() - }, - OwnedRightsType::Assets => StateSchema { - format: StateFormat::DiscreteFiniteField(DiscreteFiniteFieldFormat::Unsigned64bit), - abi: bmap! { - // sum(inputs) == sum(outputs) - AssignmentAction::Validate => Procedure::Embedded(StandardProcedure::NoInflationBySum) - } - }, - OwnedRightsType::Epoch => StateSchema { - format: StateFormat::Declarative, - abi: none!() - }, - OwnedRightsType::BurnReplace => StateSchema { - format: StateFormat::Declarative, - abi: none!() - }, - 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) + + +## Abstract + + +## Background + + +## Motivation + + +## Design + + + +## Specification + +Interface specification is the following Contractum code: + +```haskell +-- # Defining main data structures + +-- number of decimal fractions (decimal numbers after floating point) +data DecFractions :: 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | + 14 | 15 | 16 | 17 | 18 + +data TxOut :: txid [Byte ^ 32], vout U16 + +data Amount :: U64 -- asset amount + +-- allocation of assets to some transactou output +data Allocation :: TxOut, Amount + +-- right over certain amount of assets; right owner may be unknown +data AssetControl :: TxOut?, Amount + +data Nomination :: + ticker [Ascii ^ 1..8], + name [Ascii ^ 1..40], + details [Unicode ^ 40..256]?, + contract [Unicode]??, + precision DecFractions + +data RGB20Info :: + 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 future burn operations + + knownAllocations [Allocation] -- known asset amounts allocated to known UTXOs + +interface RGB20 :: RGB20Info + op transfer :: inputs [TxOut ^ 1..] + -> beneficiaries [Allocation] + + -- question mark denotes optional operation, which may not be supported by + -- some of schemata implementing the intrface + + op? issue :: usingRight TxOut, amount Amount + -> nextRight TxOut?, beneficiaries [Allocation] + + op? burn :: usingRight TxOut, assets Allocation + -> nextRight TxOut? + + op? reissue :: usingRight TxOut, assets Allocation + -> nextRight TxOut?, beneficiaries [Allocation] + + op? renominate :: usingRight TxOut + -> nextRight TxOut?, newNomination AssetInfo ``` -## Subschemata +## Compatibility -- https://github.com/LNP-BP/LNPBPs/issues/44 ## Rationale @@ -251,3 +116,16 @@ Include from - https://github.com/LNP-BP/LNPBPs/issues/27 - https://github.com/LNP-BP/LNPBPs/issues/28 - https://github.com/LNP-BP/LNPBPs/issues/50 + +## Reference implementation + + +## Acknowledgements + + +## References + + +## Copyright + +This document is licensed under the Creative Commons CC0 1.0 Universal license. From 91e6070d3ef0b86f989a3d6a0eedf94e4b948bce Mon Sep 17 00:00:00 2001 From: "Dr. Maxim Orlovsky" Date: Sun, 18 Dec 2022 16:18:16 +0100 Subject: [PATCH 2/6] RGB20: add operation falures, proofs and support for decentralized issue --- lnpbp-0020.md | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/lnpbp-0020.md b/lnpbp-0020.md index f5247b2..c3d87e6 100644 --- a/lnpbp-0020.md +++ b/lnpbp-0020.md @@ -56,6 +56,10 @@ data DecFractions :: 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | data TxOut :: txid [Byte ^ 32], vout U16 +data POR :: -- proof of reserves + utxo TxOut, + proof [Bytes] -- auxilary data which are schema-specific + data Amount :: U64 -- asset amount -- allocation of assets to some transactou output @@ -90,21 +94,38 @@ data RGB20Info :: interface RGB20 :: RGB20Info op transfer :: inputs [TxOut ^ 1..] -> beneficiaries [Allocation] + !! -- options for operation failure: + outputSpent(TxOut) + | noAssets(TxOut) + | inequalAmounts -- question mark denotes optional operation, which may not be supported by -- some of schemata implementing the intrface op? issue :: usingRight TxOut, amount Amount -> nextRight TxOut?, beneficiaries [Allocation] + !! invalidRight + | invalidAmount + + op? dcntrlIssue -> reserves POR, beneficiaries [Allocation] + !! invalidReserves + | insufficientReserves - op? burn :: usingRight TxOut, assets Allocation + op? burn :: usingRight TxOut, proofs [POR], amount Amount -> nextRight TxOut? + !! invalidRight + | invalidAmount + | invalidProof(POR) - op? reissue :: usingRight TxOut, assets Allocation + op? reissue :: usingRight TxOut, proofs [POR], amount Amount -> nextRight TxOut?, beneficiaries [Allocation] + !! invalidRight + | invalidAmount + | invalidProof(POR) op? renominate :: usingRight TxOut -> nextRight TxOut?, newNomination AssetInfo + !! invalidRight ``` ## Compatibility From e455ab41f56109fb356a46119fdd816740a523a5 Mon Sep 17 00:00:00 2001 From: "Dr. Maxim Orlovsky" Date: Fri, 23 Dec 2022 11:39:40 +0100 Subject: [PATCH 3/6] RGB20: Use new interface grammar --- lnpbp-0020.md | 82 +++++++++++++++++++++++---------------------------- 1 file changed, 37 insertions(+), 45 deletions(-) diff --git a/lnpbp-0020.md b/lnpbp-0020.md index c3d87e6..634d62a 100644 --- a/lnpbp-0020.md +++ b/lnpbp-0020.md @@ -62,70 +62,62 @@ data POR :: -- proof of reserves data Amount :: U64 -- asset amount --- allocation of assets to some transactou output -data Allocation :: TxOut, Amount - --- right over certain amount of assets; right owner may be unknown -data AssetControl :: TxOut?, Amount - -data Nomination :: +data Denomination :: ticker [Ascii ^ 1..8], name [Ascii ^ 1..40], details [Unicode ^ 40..256]?, - contract [Unicode]??, precision DecFractions -data RGB20Info :: - 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 future burn operations +interface RGB20 :: RGB20Info + global Denomination :: Denomination - knownAllocations [Allocation] -- known asset amounts allocated to known UTXOs + -- Contract text is separated from the denomination since it must not be + -- changeable by an issuer. + global Contract :: [Unicode] + -- The difference between `global _ :: [_]` and `global _? :: _` is that + -- the first indicates that the global state may not be present, while + -- the second requires the state must be present and have a form of array + -- of the elements. -interface RGB20 :: RGB20Info - op transfer :: inputs [TxOut ^ 1..] - -> beneficiaries [Allocation] - !! -- options for operation failure: - outputSpent(TxOut) - | noAssets(TxOut) - | inequalAmounts + owned IssueRight+ :: Amount + owned DenominationRight? + owned BurnRight? + + owned Assets* :: Amount + + -- operations are declared as + -- `op` NAME `::` CLOSED_SEALS,+ INPUT_METADATA,* + -- `->` DEFINED_SEALS,+ + -- `<-` NEW_GLOBAL_STATE,* + -- `!!` ERRORS|* + + op transfer :: inputs [Assets] + -> beneficiaries [Assets] + !! inequalAmounts -- question mark denotes optional operation, which may not be supported by -- some of schemata implementing the intrface - op? issue :: usingRight TxOut, amount Amount - -> nextRight TxOut?, beneficiaries [Allocation] - !! invalidRight - | invalidAmount + op? issue :: using IssueRight + -> next IssueRight?, beneficiaries [Assets] + !! nonEqualAmounts - op? dcntrlIssue -> reserves POR, beneficiaries [Allocation] + op? dcntrlIssue -> reserves POR, beneficiaries [Assets] !! invalidReserves | insufficientReserves - op? burn :: usingRight TxOut, proofs [POR], amount Amount - -> nextRight TxOut? - !! invalidRight - | invalidAmount + op? burn :: using BurnRight, proofs [POR], amount Amount + -> next BurnRight? + !! nonEqualAmounts | invalidProof(POR) - op? reissue :: usingRight TxOut, proofs [POR], amount Amount - -> nextRight TxOut?, beneficiaries [Allocation] - !! invalidRight - | invalidAmount + op? reissue :: using BurnRight, proofs [POR] + -> next BurnRight?, beneficiaries [Assets] + !! nonEqualAmounts | invalidProof(POR) - op? renominate :: usingRight TxOut - -> nextRight TxOut?, newNomination AssetInfo - !! invalidRight + op? rename :: using DenominationRight + -> next DenominationRight?, new Denomination ``` ## Compatibility From 8ba5f658c685d74f7527a150e97cb76e62cd703d Mon Sep 17 00:00:00 2001 From: "Dr. Maxim Orlovsky" Date: Fri, 23 Dec 2022 14:11:00 +0100 Subject: [PATCH 4/6] RGB-20: Add information about past issues to the API --- lnpbp-0020.md | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/lnpbp-0020.md b/lnpbp-0020.md index 634d62a..505a6c8 100644 --- a/lnpbp-0020.md +++ b/lnpbp-0020.md @@ -79,6 +79,13 @@ interface RGB20 :: RGB20Info -- the second requires the state must be present and have a form of array -- of the elements. + -- state which accumulates amounts issued + global Issued* :: Amount + -- state which accumulates amounts burned + global Burned* :: Amount + -- state which accumulates amounts burned and then replaced + global Repalced* :: Amount + owned IssueRight+ :: Amount owned DenominationRight? owned BurnRight? @@ -100,19 +107,23 @@ interface RGB20 :: RGB20Info op? issue :: using IssueRight -> next IssueRight?, beneficiaries [Assets] + <- amount Issued !! nonEqualAmounts op? dcntrlIssue -> reserves POR, beneficiaries [Assets] + <- amount Issued !! invalidReserves | insufficientReserves op? burn :: using BurnRight, proofs [POR], amount Amount -> next BurnRight? + <- amount Burned !! nonEqualAmounts | invalidProof(POR) - op? reissue :: using BurnRight, proofs [POR] + op? replace :: using BurnRight, proofs [POR] -> next BurnRight?, beneficiaries [Assets] + <- amount Replaced !! nonEqualAmounts | invalidProof(POR) From 7bfa3145e901aa6922a847f6932c7c364ddc228e Mon Sep 17 00:00:00 2001 From: "Dr. Maxim Orlovsky" Date: Fri, 23 Dec 2022 14:54:14 +0100 Subject: [PATCH 5/6] RGB20: Add reference implementation of a simple asset --- lnpbp-0020.md | 59 ++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 58 insertions(+), 1 deletion(-) diff --git a/lnpbp-0020.md b/lnpbp-0020.md index 505a6c8..9698be6 100644 --- a/lnpbp-0020.md +++ b/lnpbp-0020.md @@ -86,7 +86,7 @@ interface RGB20 :: RGB20Info -- state which accumulates amounts burned and then replaced global Repalced* :: Amount - owned IssueRight+ :: Amount + owned IssueRight* :: Amount owned DenominationRight? owned BurnRight? @@ -143,6 +143,63 @@ Include from ## Reference implementation +Simple asset issuance: + +```Haskell +import RGB20 + +schema SimpleAsset + global Denomination :: Denomination + global Contract :: [Unicode] + + global Issued* :: Amount + owned Assets* :: Amount + + genesis -> allocations [Assets] + <- totalAmount Issued, naming Denomination, contract Contract + sum allocations =? totalAmount !! nonEqualAmounts + + op transfer :: inputs [Assets] -> beneficiaries [Assets] + sum inputs =? sum beneficiaries !! nonEqualAmounts + +implement RGB20 for SimpleAsset + +let issuerOwned := Seal fac503c4641c3deda72a2d00bc9d6ff1094b15276c386efea403746a91436772, 1 + +contract sampleAsset := SimpleAsset ( + naming := Denomination( + ticker := "OTI", + name := "One time issued token", + details := "Absolutely useless", + precision := 8 + ), + contract := """ + THE ASSET TOKEN IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR + OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + ARISING FROM, OUT OF OR IN CONNECTION WITH THE ASSET TOKEN OR THE USE + OR OTHER DEALINGS IN THE CONTRACT. + """, + allocations := [ + (issuerOwned, 10_000_000__0000_0000) + ], + totalAmount := 10_000_000__0000_0000 +) + +let friendOwned := Seal ~, 0 +let issuerChange := Seal ~, 1 + +transition sendToFriend := SimpleAsset.transfer ( + inputs := [issuerOwned], + beneficiaries := [ + (friendOwned, 1_000_000__0000_0000), + (issuerChange, 9_000_000__0000_0000) + ] +) +``` + ## Acknowledgements From 25a115297cc371f65e6f0bb4a1d1d4da50f73239 Mon Sep 17 00:00:00 2001 From: "Dr. Maxim Orlovsky" Date: Fri, 23 Dec 2022 15:09:52 +0100 Subject: [PATCH 6/6] RGB-20: Improve metadata --- lnpbp-0020.md | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/lnpbp-0020.md b/lnpbp-0020.md index 9698be6..6570c9c 100644 --- a/lnpbp-0020.md +++ b/lnpbp-0020.md @@ -1,19 +1,22 @@ ``` LNPBP: 0020 +Aliases: RGB20 Vertical: Smart contracts Title: RGB fungible assets interface (RGB-20) -Authors: Dr Maxim Orlovsky , +Authors: Dr Maxim Orlovsky , Giacomo Zucco, Marco Amadori, Nicola Busanello, Federico Tenga, Sabina Sachtachtinskagia, Martino Salvetti -Comments-URI: +Comments-URI: Status: Proposal Type: Standards Track Created: 2019-09-23 -Finalized: 2022-12-18 +Updated: 2022-12-23 +Finalized: ~ +Copyright: (0) public domain License: CC0-1.0 ``` @@ -210,3 +213,15 @@ transition sendToFriend := SimpleAsset.transfer ( ## Copyright This document is licensed under the Creative Commons CC0 1.0 Universal license. + +

+ + CC0 + +
+ To the extent possible under law, + + LNP/BP Standards Association + has waived all copyright and related or neighboring rights to this work. +