Giter Club home page Giter Club logo

spec's People

Contributors

afilini avatar dr-orlovsky avatar fedsten avatar gabridome avatar giacomozucco avatar isghe avatar msgilligan avatar rubenwaterman avatar sylti avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

spec's Issues

Nested proof structure results in very large proofs for transfers with multiple inputs

I've uploaded a simple example proof together with a module for generating branched scripts. https://github.com/chm-diederichs/rgb-proof-examples

proofGen(depth, branch) generates a proof that is depth transfers away from the root issuance proof, with each non-root proof taking branch identical inputs defined as proofGen(depth - 1, branch).

The recursive branching structure is oversimplified, but provides useful heuristics. The size of the proof scales as the sum of the lengths of upstream branches. The example given shows the output of proofGen(7, 3) printed as a JSON object. The file size is 2.2MB, but the encoded proof comes to 393kB.

The above parameters were chosen so that file sizes were convenient, but proof size quickly explodes as depth or branch are increased, e.g. proofGen(14, 3) yields an encoded proof 860MB in size.

I understand this recursive structure is the extreme case, but with assets such as USDT being traded over lightning the degree branching would be significant nonetheless and proof sizes may grow unreasonably over time, but maybe my intuition about this is off?

It should be noted that in cases where different assets are transferred in the same proof, later parties could prune off the proof chains of assets they are not interested in, but this does not help in the case of multiple inputs for a single asset.

Possible solutions are:

  1. Periodic return to central issuer who could validate a large chain of proofs to then burn and reissue the asset with a virgin proof.

  2. Each party must only verify the previous proof in the chain (i.e. the recipient verifies the donor's ownership) before accepting the trade.

  • Potential issue: a malicious party could transfer an asset to themselves and accept an invalid proof, which future buyers could not check
  1. A zero-knowledge protocol to validate proofs between parties and reduce the number of proofs needed to be passed along (this is proposed as a future optimisation rather than an immediate option).

Privacy issues

The current structure of the Color_Def present multiple privacy problems, in particular:

  1. RGB Version: this byte will always be set at 0 until further versions are developed, and even at that time there will probably be a dominant version having most of the RGB transactions set with the same version number. Even if it is just a byte, it can help an attacker to identify RGB transactions.

  2. Second input position : we can expect many transactions to have a single colored input, making this byte often set to 0xff, making easier for an attacker to identify many RGB transactions. A possible solution could be to increase the quantity of values that invalidated the second colored input field (e.g. 16 instead of only one). This would obviously reduce the number of input supported, however it seems a good trade-off between privacy and usability since most bitcoin transactions have less than 240 inputs.

  3. Second input field: we can expect many transactions to have a single colored input, making the 12 bytes set at 0xffffffffffffffff a very good indicator for an attacker interested in identify RGB transactions. Since this field is already considered invalid if the position byte is set to 0xff, I would suggest to put a random value here. RGB client will ignore it anyway when they see the position byte set to 0xff, but the transaction will be far less identifiable.

  4. bytes 29-32: we can expect most of RGB transactions to have at least 3 outputs, but the colored ones could be even only one. In general, setting at 0xff the last bytes of all the transactions with few colored outputs is very bad for privacy. Assuming the transaction has n outputs and m colored outputs (m<n<6):
    m output fields will be correctly set to the actual colored output position
    n-m output fields will be set to any random value >n (hence invalid)
    5-n fields will be set to any random number, as RGB clients will just ignore this field

Decide how to "sort" transactions in the same block

This is necessary to make something similar to the "crowdsale" contract implemented in the proof of concept: this kind of contract "mints" new tokens whenever a transaction which sends some satoshis to a predetermined address is seen on the blockchain. This transaction itself is then used as the first node of the chain of proofs1.

We have to agree on a criteria to "sort" all of those transactions buying tokens, because when we reach the max supply of tokens, we need to agree on who is going to get the tokens and who is going to get the "refund". If multiple transactions are confirmed in the same block we don't really have a way to know which one "comes first".

This way of distributing tokens is pretty good at reducing space on the blockchain and making everything more "automatic". It's also very useful to increase privacy, since many chains of proof will be created instead of one, making it more difficult to analyze all the movements later down the chain.


1: Since the transaction NEEDS to have only two outputs (one which is paying some satoshis to the deposit address specified in the contract and the other which will receive all the tokens/change/refund), by showing that you paid some satoshis to this specific address you are actually proving that you own the tokens, as long as you can spend the second output of the transaction.

Proposed Spectrum tx structure

Graphical specification for funding and commitment transactions with RGB proofs:

RGB Specifications

Notes:

  • The chart covers P2C commitment scheme only. Whether OP_RETURN scheme can be used with lightning — and is there any need in using it — should be a matter of separate discussion.
  • Here we follow the #93 recommendation, putting the tweaked key in the same output which is used for the channel creation. This is not a requirement, the same workflow will work with the tweaked key (=proof commitment) put into any of the outputs (according to #92) ...
  • ... or even into some external transaction. The question is do we need this form of flexibility and why is it needed? As for non-LN part of RGB, it can be useful to allocate the assets to an existing UTXO, but with Spectrum we will have funding on-chain transaction in any way, so I propose to limit channel opening only to vout addressing option.

HD derivation problem

K is 12-bytes long and is split into three 4-bytes chunks, which are then used to derive from an xpub. 4 bytes can represent derivation indices ranging from 0 to 232-1. However, as per BIP32, indexes 231 through 232-1 are used for hardened child derivation, which is not possible without having the xpriv corresponding to the xpub.

A solution would require having the most significant bit of every chunk of J and K always set to 0 and randomly generating the other bits.

Sign-to-contract and multisig addresses

As stated in the protocol specification, in case of multisig addresses spending funds it's necessary that all the required signatures agree and include the same commitment.

Assuming that all the signers check the previous signatures, this allows the last signer to effectively burn all the tokens linked to the UTXO being spent by signing the transaction without the same commitment and broadcasting it to the network.

To overcome this issue my proposal is to ask the signers to sign just the proof first and add all these signatures in a "witness area" of the proof itself. Later, they will all sign the transaction and add the commitment to this proof. In this way, even if only one of the signers adds the commitment in its transaction signature, this is enough to prove that all the party agreed on the proof he owns, since he can also show all the signatures.

This will obviously increase the size of all the proofs coming from multisig addresses, but right now I don't see any other way to fix this. Any ideas?

Update proof structure separating commitment and prunable parts

From #80 and #78 – and also from rgb-archive/rust-rgb-2019#8 – it follows that the proof structure:

  1. will be updated after the actual UTXO is spent (for pay-to-existing UTXO proofs)
  2. will contain parts that are prunable and do not take a part in the proof commitment

It is proposed to clearly separate these parts in the proof header and (potentially) body, because specific future blueprint-specific data may require the same functionality.

Design meta-script language

Design a meta-scripting language to encode complex contracts that have more
unique or convoluted behaviours.

  * **Scripting language**: Design the scripting language
  * **Template**: Integrate the language into an RGB contract template

Remove maxfeepercent limit in RGB lightning implementation

c-lightning has a limit on the max fee a user can pay, in order to prevent the payer from paying a fee several times greater than the actual payment. In particular, the maxfeepercent value has to be between 0 and 100, making impossible to pay a fee greater than the value of the payment.

In RGB, this would slightly affect the payment experience, as it requires the user to (i) send some extra satoshis to the counterparty, even if she does not want to, in order to keep the fee percent between the allowed values and (ii) always have some extra satoshis in the channel, in order to avoid ending up with the tokens blocked due to inability to transfer enough satoshis.

Even if this is a minor issue, I think it would still be good to remove this limit or make it more flexible in an RGB lightning implementation.

Improve token burn procedure

Instead of sending tokens to a "burn address", it should be possible to simply, writing in the proof that an RGB output has been burned

Commitment output signaling

When committing to proofs using p2c it would be nice to hide to blockchain observers which one is the output effectively committing to data.

From a very basic discussion between me and @giacomozucco, our first idea was to use the amount sent to the first output mod the number of outputs: unfortunately, since the amount is not really random and generally has many zeros at its least significant digits, it would mean that either 90% of the proofs are committed to in the first output itself, or we would see really strange looking amounts like 0.05000001.

Another possibility could be to use fees instead of the amount paid: the idea is that fees are already "strange-looking" because of fee estimation software. Adding one or two satoshis won't hurt anyone but could allow the sender to choose which output to use for the commitment.

Design proper multi-asset proof specs

Each proof can cover multiple asset transfers issued by a multiple contract. We need to ensure that this part is covered through spec. We also need to design how asset_id is defined: it needs to contain hash of the contract + some id of the asset within that contract.

Is consensus encoding necessary to serialise contracts?

As RGB contracts are not parsed by Bitcoin nodes directly, is it necessary to serialise using consensus encoding? Consensus encoding seems underspecified, and structs are only defined implicitly in the custom encoder.
Protocol buffers, as used in LN, provide freedom to update contract headers in the future as more contract types are introduced. They are also well defined structures, making it easier to integrate across platforms.

Flexibility in using commitment schemes with P2C being the default one

In the current specification, the choice on the commitment scheme to be used for transactions is left to the issuer. However, different users of an asset may had different preferences. For example, a private user may prioritize the minimization of the on-chain footprint (either for privacy or efficiency) and prefer the pay-to-contract scheme, while an exchange may prefer the OP_RETURN based commitments to enable easier HSMs support. Therefore, forcing all future users to the same commitment scheme may result limiting.

I don't see why this sort of limitation is necessary. Probably the choice could be left to the two parties involved in each transaction rather than to the issuer, with the receiving party signalling through an invoice which scheme(s) it supports.

Idea: RGB-extended Bitcoin transaction validation

It seems the details of this protocol have not been fixed yet, so I shall express here, an idea that I hope will allow RGB to be useable with future extensions to Bitcoin, and also with any Bitcoin-expressable smart contract, including offchain protocols like Lightning Network and CoinSwap and CoinJoin.

In transaction validation, much of the effort is signature validation, as controlled by a Bitcoin SCRIPT execution. In actuality, for native P2WPKH, there is not even any Bitcoin SCRIPT execution, and only a validation of public key and signature, uncontrolled by Bitcoin SCRIPT.

An RGB transaction is simply a Bitcoin transaction, extended with RGB-specific data.

RGB coins are colored by using the pay-to-contract construction, where a public key is tweaked. At the Bitcoin level, the tweaked key is used, but at the RGB level, the pre-tweaked public key and the RGB contract is used instead.

An RGB transaction includes an additional rgbWitness stack. This rgbWitness is additional witness data that an RGB protocol will validate.

Suppose we have a P2WPKH. At the Bitcoin level, the witness should be the signature pubKey. Roughly speaking, P2WPKH performs OP_DUP OP_HASH160 <pubKeyHash> OP_EQUALVERIFY OP_CHECKSIG. This is implicitly done by P2WPKH (in pre-SegWit P2PKH the script is explicitly written in scriptPubKey).

What I propose is that any time the Bitcoin level executes an OP_CHECKSIG or OP_CHECKMULTISIG (or equivalent operation as the implicit OP_CHECKSIG in P2WPKH) and takes pubkey(s) and signature(s) from the witness stack, the RGB level (which also runs the same verifications that Bitcoin does) will, in addition, take two items from the rgbWitness stack.

Those two items are (1) at stack top, a proof showing that the Bitcoin-level public key is the tweaked key Q committing to P and a contract that outputs some RGB-level assets, and (2) at stack top - 1, a signature of P signing the RGB-level transaction that takes the previous output and distributes it to the current transaction outputs.

For instance, suppose we already exist a unique cryptokitty whose sole purpose is to consume space on the blockchain, and that cryptokitty is hidden in a pre-existing UTXO that is a simple P2PKH. The public key secretly commits to the cryptokitty, and has the contract "1 cute ZmnSCPxj kitty" coming from ..., where ... is the client-side validated history (RGB-transactions) of the kitty.

To transfer this kitty to a 2-of-2 P2WSH, we create a Bitcoin-level transaction that spends the P2PKH normally (providing signature pubKey in the scriptSig as per pre-SegWit). Suppose we would like to put it in output 1 and some of our normal Bitcoin funds into output 0. Then the output 1 of the Bitcoin-level transaction would commit to a 2-of-2 multisig P2WSH, with the care point that the public keys in the multisig would have to commit to an RGB-level transaction that has as input the "1 cute ZmnSCPxj kitty", and two outputs, one with "0 cute ZmnSCPxj kitties" (output 0, which is a plain Bitcoin output), and the other with "1 cute ZmnSCPxj kitty" (output 1, where we want to move our kitty).

The public keys in the scriptPubKey commit to the RGB-level transaction, excluding the rgbWitness stack (since the rgbWitness stack itself contains signatures committing to the RGB-level transaction, and similar to how SegWit works where the txid does not commit to the witness stack).

So let us turn back to our cryptokitty. There exists a "1 cute ZmnSCPxj kittty" output on some RGB-level transaction R1, that is committed to by some Bitcoin-level transaction T1. Some pubkey Q1 on an output of T1 commits to the RGB-level transaction R1. The RGB-level transaction R2 that moves the kitty from the P2PKH to output 1 P2WSH. The RGB-level transaction then has a rgbWitness stack showing that Q1 commits to P1 and the RGB-level transaction R1, and also has a signature signed with P1 with the message R2. R2 has two outputs, one with "0 cute ZmnSCPxj kitty" and "1 cute ZmnSCPxj kitty". The Bitcoin-level T2 has a P2WSH whose public keys both commit to R2. To properly transfer the kitty from the 2-of-2 P2WSH to a different address, we would require another R3/T3 that shows that public key commits to R2, and contains signatures for R3 in its own rgbWitness space.

RGB clients would need to pass around the entire history of any assets they transfer (or possibly you use the RGB proof server).

This has the massive disadvantage that you would require reimplementing a Bitcoin client, since you need to hook into the CHECKSIG and CHECKMULTISIG operations, including those points where they are called automatically outside of script (e.g. P2WPKH). Any new Bitcoin improvements will also require updating the RGB client.

This however has the massive advantage that RGB can be made to work with any valid Bitcoin transaction. This means that any future offchain protocol can, with some effort, be made to work with RGB assets.

I'm Here for the 10k Free ETH 😆

I just got done watching the presentation on this topic and wanted to share my appreciation for the thought and effort put around this. I am building a proof-of-concept around this space and am very interested in seeing where I can help out, if at all. Unfortunately, I am a .NET developer which seems to be quite rare to date, but I hope to help change that in the near future. 😄

Also as a FWIW: in my case, I am looking to support more than BTC and would like to support several additional blockchains. From what I can gather, that should be possible with this specification, correct? In my case I would like to support LTC, BCH, and ETH in addition to BTC for my proof-of-concept.

I may be biting off more than I can chew, however. I might stick to BTC for the first version. 😇

In any case, I wanted to share my appreciation towards the efforts here. 👍

Why we use addition instead of multiplication in public key tweaking

This is standard way the public key tweak procedure works, including the code in the rust-bitcoin library written by A. Poelstra.

However it is known that public and private key multiplication is more secure procedure, giving less predictable result, and preventing malicious agents from collecting the information from multiple sources and assuming the actual tweak factor.

We decided to ask Leo and Andrew on this design choice...

Why up to 5 colored outputs?

The structure of an RGB transaction seems to be able to support at most one receiver. Since you have to encrypt Color_Def with K, you cannot support multiple receivers with multiple Ks. Therefore, why the protocol supports up to 5 coloured outputs? You will usually need only 2 coloured outputs, one for the receiver and one for the change.
The extra bytes used for 3th, 4th and 5th coloured vouts could be used to increase the entropy of K (much needed, another issue WIP on this regard).

Specifications for invoice based payments

The current Kaleidoscope implementation uses a sendtoaddress payment method, which is basically the standard also in Bitcoin wallets. However, since we are building a new protocol, it could be a good opportunity to encourage the usage of invoices, that have the advantage of mitigating human errors with the amount or asset_id, and facilitate the transmission of other relevant information from the payee to the payer (such as the commitment scheme preference, see #82).

For this scope, it would be useful to formalise an invoicing standard in the protocol specifications.

Why transfer proofs needs asset id field?

The spec suggests that the transaction proofs need to contain triplets for each output with a specified color of the token being transacted (i.e. asset id = hash of the serialized contract).

This is redundant, since each proof is linked to a single asset, so there is no need to provide asset id information within output fields for the proofs

Lack of entropy for encryption keys

The specification defines K as 12 bytes random value, however 96 bits are not considered enough for today's security standards, so it is necessary to increase the entropy of the keys, but we still want to keep the 32 bytes limit to make the Color_Def undistinguishable form a SHA256.
Unfortunately we cannot get to the raccomandable128 bits, since with such entropy the two keys would use the whole 32 bytes available making it impossible to put other data in the Color_Def, we would therefore recommend 120 bits, which represent a significant improvement and are an integer in bytes.
To express all the other information in just two bytes is a bit challenging, but it is possible with acceptable trade-offs.

Currently the position of the two coloured inputs are expressed using two bytes, however if we make the protocol define that the coloured inputs always have to stay in first or second (when applicable) position, we can compress the input positions information in a single bit, which will simply specifies if there are either one or two coloured inputs (that will be found in the first or the first two positions).

We can similarly save space with the coloured vouts, if we enforce the coloured outputs to be always in the first positions, we just have to express how many coloured outputs there are in the transaction, knowing already they will be at the beginning of the output field. In this way, we can have up to 16 coloured outputs using only 4 bits.

Position Size Desciption
0-1 1 byte RGB version
1-2 1 byte Mask: 1 bit number of coloured inputs, 4 bits number of coloured outputs, 3 bits reserved
3-17 15 bytes Tagging value of the previous output of the first coloured input
18-32 15 bytes Tagging value of the previous output of the second coloured input , otherwise 0xffffffffffffffffffffffff

If we want to use XXTEA encryption algorithm to encrypt the Color_Def (not sure if we can consider it secure, please double check) needing an extra byte, we already have 3 reserved bits, and we can easily find other 5 bits reducing the version and the coloured outputs fields.

However even such solution is far from being optimal, 120 bits of entropy may be a security issue in the future and 32 bytes may not be enough to use a good symmetric encryption algorithm. Once we exceed the 32 bytes limit, for fungibility the second best number of bytes used is probably 80 bytes (you are just pushing as much data as you can in the OP_RETURN, multiple use cases). In this way, we can use 30 bytes for each key achieving a good level of entropy, 4 bytes to encode version and positions information, and 16 bytes used for encryption overheads (e.g. AES):

Position Size Desciption
0-1 1 byte RGB version
1-2 1 byte Mask: 1 bit number of coloured inputs, 4 bits number of coloured outputs, 3 bits reserved
3-32 30 bytes Tagging value of the previous output of the first coloured input
33-64 30 bytes Tagging value of the previous output of the second coloured input , otherwise 0xffffffffffffffffffffffff
65-80 16 bytes Encryption overhead

In this case, if we find a symmetric encryption scheme which requires less than 16 bytes of overhead, we can even reach 32 bytes of entropy for each tagging value, which would be optimal.

To meta-script or not to meta-script?

Honestly, I don't think we really need a meta-script language. We could just add some "blueprints" for contracts, so that we define their behavior, while the issuer only needs to fill up some fields.

The first two blueprints I can think of are:

  1. The old token issuance where the issuer "prints" N tokens and sends all of them to a specific address
  2. The "crowdsale" issuance, where the users who buy these tokens are actually printing them for themselves, by proving that they sent a payment to a specific BTC address.

I agree that we need a versioning system, but I would use it to "tag" changes in the behavior of the blueprints themselves. Something like:

Crowdsale issuance (type 0x02), version 1.0: Everyone can buy the tokens

Crowdsale issuance (same type, 0x02), but version 2.0: There is one more field that allows the issuer to force users to send segwit transactions only.

This doesn't really make any sense, it's just an example of the following concept: every blueprint (contract) have a specific type, and a version number. By changing the version number we conceptually keep the same "behavior", while we can add some more features/improved privacy/security and even more.

This kind of structure allow users (or wallets) to ban specific contract types, while welcoming version updates on the kind they accept. Instead, with a "general" RGB version number we could risk forks when a controversial change is applied together with some useful updates, since someone would like to accept the "useful updates" while rejecting the "controversial change", possibly resulting in a fork.

Oh, and this would allow us to add a meta-script language in the future, by creating a new blueprint with a field that contains the script itself.

No support for spending single RGB output from the proof

In the current spec the proof can contain multiple outputs with different amount of RGB assets in each. However, the input part of the proof references the whole previous proof which it spends, not a particular proof output. Thus, if Alice sends 1000 USD₮ to Bob and 500USD₮ to Carol, both Bob and Carol can't spend their own assets without spending assets of the other party.

The same is true for the original librgb code. Am I missing something?

How to deterministically define output containing the tweaked key for P2C schemes

The original problem is put forward by @giacomozucco: in order to avoid double spending with pay to contract commitment schemes, all future owners of the assets must be able to know exactly WHERE the proof-commitment is, in each step. Without it, one could create two versions of the same proof that commit to different outputs, allowing therefore double spends.

To demonstrate the problem he had provided such case:

Alice sends assets to Bob with Txa. Bob sends them to Carol with Txb. Carol to Daniel with Txc. In order to avoid double spending, ALL of them must to be able to know exactly WHERE the proof-commitment is, in each step. Bob may not know which output of Txa is the actual change of Alice (even if he COULD deduce it in trivial cases, by exclusion). Carol and Daniel would have NO IDEA of that. So, the rule must be deterministic for everybody.

Some of his suggestions are:

"First output" is ok, just as it's ok any deterministic mechanism. Actually, I'd prefer some simple deterministic way (like, count satoshis in the first output and use mod(N) to get to the right output) for the reason tha I don't like the idea of forcing the RGB wallet to always put the change in 1st position, since that may conflict with some future best practice in Bitcoin, like value-based ordering, lexicographic ordering, or ordering patterns that serve other porpuses in CoinJoins or wathever. But the point is that "change output" is NOT an alternative to "first output". We need a deterministic way to know WHICH output contains the commitment, AND, orthogonally, it would be often better IF that output was also a change by the spender, for many reasons.

@fedsten had the following argument regarding this:

Regarding the proposal of using the amount to deterministically identify the change output I don't really agree. Using satoshis to encode information only works until satoshis are irrelevant, which we cannot expect to be the case forever, but I'm sure we can find something else (eg unused space in the sequence or even some ugly brute force on the signature)

@giacomozucco:

We could use other fields, probably, like nsequence (but it could interfeer with RBF?). In general, anyway, I'd like the order of the output to tweek to leave some degree of freedom to spender in case of other ordering schemes.
So, to recap:

  • in general, the UTXO which can be spent to move the asset NEXT is not necessarily (and I think shouldn't be in general) the same UTXO which contains the commitment NOW
  • it must be possible for a receiver of proofs to deterministically know, from public info, which output contains the commitment BEFORE even opening the proof, or one could doublespend (but I'd like to avoid fixed orders)
  • in general, it would be cool to have the default of the change as the proof container, since it's likely there anyway and the sender knows the tweaking secret by definition, since he created it.

@fedsten:

I was thinking that if we have a deterministic way to find the change output with on-chain data, than the same information is available to chain analyst attackers eliminating the benefits of not having a fixed outputs order. So anyway whatever we use, it cannot be something that could make the tx identifiable as RGB (so nsequence, version and unactivated timelock are to be excluded).

@giacomozucco:

Precisely. It should be something that IF one assumes that's an RGB transaction, THEN identifies uniquely the output

Add support for eltoo

I was thinking about how we could add support for eltoo-style lightning network channels.

Initially I was pretty sure that we would need to implement our own "noinput" signature format, but now I'm wondering if we really need to explicitly add the input proofs to a new proof we are creating: it's actually implicit, while we spend a specific UTXO we can "plug in" as inputs all the proofs that are bound to this UTXO and there's no need to add a "previous proof hash" into a new proof.

This would obviously imply an out-of-the-box support for eltoo in RGB, since there are no "inputs" in a signed proof that would need to be updated later on.

Remove the proof of concept

I'm worried that some people might think that the python code in this repo is the "real" rgb implementation. what if we move the code out, into a separate repository?

Increasing asset safety by combining commitment output with asset binding output

  1. If someone would like to protect RGB asset from an occasional loss due to a wrong wallet software being used, then
    a) use P2C commitments
    b) commit only to colored outputs
    c) this will disallow payments to existing address
    d) with multisig one will need to tweak all public keys of all participants

  2. Otherwise, everybody are free to use OP_RETURN, pay to existing address or have «simple» multisig version with commitments stored in a (dummy) change output

To put this protocol enhancement forward we have the following options:
A. Commit to the (dummy) change output always
B. Commit to the first public key inside the script always
C. Allow «safe» multisigs as an option for those who needs to with commitments in all public keys (i.e. all of them will be tweaked)
D. Make «safe» multisigs the only possible option

«A» means we add just a tiny bit to bitcoin blockchain pollution (by increasing transaction size b/c of the additional transaction output in cases when there is no change) — but simplify the protocol, software. However, it will be possible to attack some of the non-symmetrial multisig wallets by burning RGB assets by the will of some (not all) of the multisig wallet owners

«B» does the same but w/o blockchain pollution, instead adding to the protocol complexity and requiring each time to create custom multisig wallet

«C» solves the safety issue allowing for thos who do not need it to failback to simple protocol like «A» and «B»

«D» is strictly safe, but most complex option, also requiring a multisig wallet to be used only once (it does not affect the blockchain size footprint though, just adding to wallet software and custodial policies complexity)

UTXO-based RGB transaction proofs breaks pay to contract scheme design

The current spec provides two options to specify the receiver: with UTXO-based output and address-based. The first form allows paying to some existing UTXO, while the second requires a new address to be generated by the payee (see https://github.com/rgb-org/spec/blob/master/01-rgb.md#address-based-vs-utxo-based for more details).

However, when combined with pay-to-contract scheme, the receiving UTXO will be no more tweaked, so the whole design consideration for the pay-to-contract gets broken here...

Remove obsolete dark tag terminology and references

@afilini and @giacomozucco confirmed that any "dark tag" reference should be strictly vestigial.

The term doesn't design anything particular anymore. Some of Bifröst spec could still contain it as the name of some obfuscation key in general.

So the term and dark tag fields should be removed from the spec

Add versioning to RGB protocol

With the current spec, we have versioning system for blueprints, but not for the protocol. However, in the future we can have compatibility-breaking changes in the protocol (like the structure of the contract headers, proofs, or to the function for defining which Tx output is used for P2C commitments) and it can't be done without the proper versioning system.

Possible conflict of pay-to-contract schemes with Taproot

As the subject says, pay-to-contract schemes may conflict with Taproot in the future, if extended naively to a future Bitcoin version with Taproot support.

Proofs may themselves be marshalled into a form which can also be read as Bitcoin SCRIPT. This would allow a scammer to induce a victim to construct a proof that can be reinterpreted as a Bitcoin SCRIPT which the scammer may know how to solve, allowing the scammer to burn the colored asset and steal the backing Bitcoin UTXO via the always-enabled Taproot branch. I have not seen spec about proof marshalling (perhaps, not yet created?), but this is care point.

An idea, is to make an OP_RETURN byte (0x6A) be the first byte in every marshalling of a proof. Thus when reinterpreted as Bitcoin SCRIPT, the first instruction, is an OP_RETURN, which prevents the proof from being reinterpreted as a Bitcoin SCRIPT that can be solved, as OP_RETURN scripts are unsolveable.

(Another mitigation is to make the backing Bitcoin funds so small as to be not worth the effort of stealing, but this may conflict with your intended plan, for using also a UTXO to back LN channels with both Bitcoin and asset)

(also this may be an argument against an always-enabled Taproot; possibly we could add a flag or marker, in the contract space, which selects "domain", and Bitcoin Taproot is simply an additional domain)

Care must still be taken in future. Other schemes that use pay-to-contract may also conflict with RGB usage in the same manner: a proof marshalling under RGB may be reinterpreted as a contract in another scheme, which may lead to victims assuming they have proofs under one system and then inadvertently signing off on a proof/contract for another system.

Technical debt of dual commitment schemes

Current protocol specifications define two separate commitment schemes for proofs and contracts, one using OP_RETURN and the other using pay-to-contract. While pay-to-contract offers obvious and significant advantages, it is unclear if there is any use case in which OP_RETURN would be preferable.
If p2c ends up being always superior, I don't see the point of having an alternative commitment scheme which would only cause a burden for wallet developers who will have to keep compatibility with both schemes, even if only one is widely used.

Clarify how different assets are supported and identified in multi-asset proofs

The section on transfer proofs in the specification https://github.com/rgb-org/spec/blob/master/01-rgb.md#transfer-proofs implies that multiple assets can be transferred in a single proof:

Every RGB on-chain transaction will have a corresponding "proof", where the payer encrypts, using the payee’s dark-tag, the following information in a structured way: <...>
a list of triplets made with:

  • color of the token being transacted
  • amount being transacted
  • either the hash of an UTXO in the form (TX_hash, index) to send an UTXO-Based transaction or an index which will bind those tokens to the corresponding output of the transaction spending the colored UTXO.

We need more clarification on how the "color of the token** is specified

Related issues:

Add validation hints into proofs

Validation of proofs and contracts generally involves getting transactions based on a UTXO that they spent. This is a very costly operation since this detail is not indexed in the Bitcoin core. Adding the txid into proofs helps validation (the validator downloads that tx and checks that it really spends the UTXO)

Sign-to-contract or pay-to-contract?

Maybe we should consider using pay-to-contract to explicitly create some "rgb-only" addresses. The downside is that by losing the commitment part of a pay-to-contract address, you will loose your bitcoins forever. On the other end, by using sign-to-contract you will have access to the bitcoins and just loose the tokens.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.