Skip to content

Instantly share code, notes, and snippets.

@Ayms
Last active March 7, 2023 16:14
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Ayms/029125db2583e1cf9c3209769eb2cdd7 to your computer and use it in GitHub Desktop.
Save Ayms/029125db2583e1cf9c3209769eb2cdd7 to your computer and use it in GitHub Desktop.
A Universal Coin Swap system based on Bitcoin

A Universal Coin Swap system based on Bitcoin

Note: this proposal needs to be slighltly modified since the storage limit for OP_RETURN is 80B and does not work for all cases, but the principles will remain the same and other storage solutions exist, see https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2023-February/021398.html

Then for now some transactions mentionned in that proposal are not standard (ie not relayed by the nodes) but valid (ie a miner can include them into a block)

So, after discussion with the bictoin community, see Allow several OP_RETURN in one tx and no limited size

In case this change, which looks to be admitted by the majority, is trivial and not even a soft fork, is not implemented then please see the different workarounds at the end of this proposal

Introduction

This is the continuation of A Bitcoin NFT system called [1] in what follows

Blockchains can't interoperate between each others, neither with the outside

Then if you want to transfer for example one ETH to BTC, it's just impossible

The solution is usually to use another strange name invented by the crypto folks called "Atomic Swap", which means nothing, or a wrapped token

The Atomic Swap/Wrapped token is usually a token on another chain system or a centralized system used as a pivot to transfer your ETH to BTC, ie you send ETH to the system, the system converts the value to BTC and sends it to the Bitcoin blockchain

It's useless to read all the research papers/whitepapers about Atomic swap/Wrapped tokens solutions because it's of course a very centralized system and you must trust the "system" not to steal you coins, even if some solutions prevent this, usually you must pay for the service also

Other systems are working the very same, like Tezos for example and Wrapped BTC where it's always the same story: a centralized system will get your BTCs and transfer them to Tezos wrapped BTC, you can transfer back your wrapped BTC and get BTC again

Anyway in all existing system there are some bridges/third party/tokens used to wrap from one coin to another, that you must trust, and that is always centralized

To be correct, some systems are not centralized, like Wrapped ETH, where the WETH contract stores the associated ETH and then use WETH to make transactions between ERC-20 tokens (because the Ethereum blockchain like Tezos can't do this) and at the end can send you back WETH for ETH, the problem remains that this mechanism involves several expensive transactions

We propose something different, not centralized, not expensive, with no artificial third party/tokens since the transactions occur on the native blockchain of the coins being swapped

Purpose

The purpose here is to propose a simple Coin Swap decentralized system based on Bitcoin but that works for all blockchains/tokens

The use case can be the Metaverse, but not only, example: you go from The Sandbox to Decentraland, you have SAND but no MANA, then you must be able to pay with SAND

In what follows we will take this example, SAND and MANA are based on Ethereum but let's imagine that they are coins in any existing blockchain/token

One drawback of the proposed solution is that the seller must own some Bitcoins, which is not really difficult since it's easy to swap coins in exchanges

But, then what is the interest of this proposal or Atomic Swap? You don't know very well what you will buy and what will be the price, then you are not willing to exchange SAND for MANA for some unknown amount, pay the fees and stay with your MANA, then exchange them for SAND and pay the fees again, and in fact you don't know if you are going to buy on Decentraland or other Metaverse, therefore you are not going to keep your time swapping coins in exchanges

You might also dislike using exchanges or known centralized swap systems (Uniswap for example), which again are difficult to use by the buyer since he does not know what he might buy, for what price and where

So it's not easy for the buyer to swap coins but it's easy for the seller to swap paid amounts to bitcoin for future transactions or other coins, anyway the seller must do some efforts, not the buyer

Swapping a NFT from MANA to SAND (or others)

The buyer has SAND and wants to buy in a MANA shop

He will agree on a price (number of SAND) with the seller paying with SAND (using SAND/MANA conversion price)

Or he can agree on another crypto currency he owns instead of SAND, but let's call it SAND in what follows

The seller A will then do the following transaction on Bitcoin:

From address A (the seller):
 OP_RETURN |reference||price||SAND||A SAND address||C SAND address|-signed by C (from |reference| to |C SAND address|)
 DUST (A or B) or refund to an address of yourself (A or B)

Reminder |reference| is unique for what is being bought, see [1]

Indeed the seller must again do some efforts and provide a A SAND address

The transaction is signed by A, it proves that A accepts the deal in SAND

The buyer C will make a transaction to the A SAND address with the agreed price from the C SAND address (using of course the SAND system)

C can cheat and do a transaction to A SAND address with a lower price, or no transaction, but then the deal will be invalid and the buyer has lost his SAND, same for a thief

Again, A is the one that has to do some efforts, he might keep the SANDs received or swap them in an exchange

The purpose of the C signing (note that the signing here is the SAND signing, not the Bitcoin signing) is to prove also that C did accept the deal, if not A could use a well known C SAND address (let's say Vitalik's ones for example), make transaction and then pretend that C did not respect the deal, even if it looks stupid since he has to pay the fees for the fake transactions, or replay several time the transaction with C supposedly buying different items and never paying for them

Swapping coins from MANA to SAND (or others)

The buyer C wants to convert SAND to MANA

One might say it's easy to do using an exchange but no. First you must send your MANA to the exchange and pay the network fees, then since most likely a MANA/SAND pair does not exist, you must convert your MANA to something else, paying the exchange fees, convert from "something else" to SAND, paying the exchange fees again, and then maybe send your SAND to the network, paying again the exchange fees

If you use a supposedly decentralized Exchange (DEX) that's about the same

C will agree on a price (number of MANA/number of SAND) with the seller A (using SAND/MANA conversion price)

The seller A will then do the following transaction on Bitcoin, the buyer is C:

From address A (the seller):
 OP_RETURN |nb of SAND||SAND||A SAND address||A previous MANA address||nb of MANA||MANA||C MANA address||C previous SAND address|- everything signed by |C previous SAND address|
 DUST (A or B) or refund to an address of yourself (A or B)

A and C exchange the required information and finally C sends back to A the OP_RETURN content signed by him

A and C previous addresses must be know (ie already used), as well as A bitcoin address (see why below) and must own sufficient coins

The buyer C will make a transaction from |C previous SAND address| to the A SAND address with the agreed nb of SAND

The seller A will make a transaction from |A previous MANA address| to the C MANA address with the agreed nb of MANA

A did sign the bitcoin transaction, proving that he is OK with the deal, C did sign the content of the OP_RETURN, proving also that he is OK

If A or C fail to make the correct transaction on SAND and MANA chains then one of them, or both, are thieves, which will be well known by everybody from the history of previous MANA/SAND transactions (that's why previous MANA and SAND addresses must be known, and for tracking purposes also) and further ones, then as in [1] they might assume the legal consequences

The threat model here is not worse than for example delegating the spending of wrapped coins to a central system like Opensea

A can't again replay the transaction, invent fake deals and compromise C reputation since the OP_RETURN content must be signed by C and A bitcoin address was already used, therefore A can't use a new unknown bitcoin address and must prove he has the knowledge of the private key of the A already used bitcoin address, A can't use a C address for which he does not know the private key, then a C address that he does not own, so at the end A will just compromise himself

It's not considered as good practices to reuse Bitcoin addresses but here the risk is limited since nothing can be done further with the OP_RETURN transaction (except eventually spending the DUST) since refund will go to another B address owned by A, unless A still has other unspent output not used for the transaction, that's the problem of the seller to manage this

Conclusion, license and funding

We cannot enforce all aspects like with Lightning, which we love but find difficult to use, the threat model here is more based on the reputation, you cheat, you get banned, tracked and might go to jail one day, but again it's not worse than all existing systems where at a certain point of time you must delegate trust to bridges, coins or centralized systems

What is the benefit of this proposal? It is simple, decentralized, not expensive and people understand it, if you go to Why Opensea sucks the buyer must convert to wrapped ETH, delegate the spending to Opensea, then Opensea makes you sign the final transaction to transfer the NFT to the buyer, pay you and get its fees, you don't know at all what is going on since Metamask is doing this for you, several transactions are involved from the buyer and the seller and remain quite expensive at the end, including Opensea fees, unlike here where it is quite cheap and does not rely on any centralized system with fees, of course some interface/tools centralized or not must be available so people can use it but they will know what they are doing

Why not a super sidechain instead? this is explained in this link

Same license/funding than 1 apply for this proposal

https://web.archive.org/web/20230126165203/https://gist.github.com/Ayms/029125db2583e1cf9c3209769eb2cdd7

Workaround 1 to the 80B OP_RETURN limitation

There are many ways to store things in bitcoin transactions, the taproot witness OP_FALSE OP_IF trick, where data is stored after OP_IF without any size limit since this part is ignored and therefore the script size limit of 520 B does not apply

You can put data in a 1 of m multisig transaction where only 1 is a valid key and the rest data

You can put data in scriptSig/witness like OP_PUSH data OP_DROP or others but will end up most likely with a non standard transaction (ie not relayed by nodes but still valid for miners)

The drawback of those solutions is that you need to do two transactions to unveil the data, and in our proposals we must keep in mind that things should be easy for the buyer, so two transactions do not work very well, given that you need the first one to be confirmed to perform the second one

Then you have the worse storage method with only one transaction if OP_RETURN can't do it for a standard transaction: store in addresses, this has been done in the past, you just put the data in output addresses, nobody can check this that's why it remains standard transactions, so it is stored but you will never be able to spend those outputs, therefore doing this you are burning bitcoins

Anyway, if bitcoin does not extend the OP_RETURN size limit in what follows:

OP_RETURN something

Will become:

OP_RETURN 80B |data|
p2pkh (20B) or p2pk(64B) |data| DUST
...
p2pkh (20B) or p2pk(64B) |data| DUST

Where p2pk is using uncompressed keys here on purpose so it's less expensive, leading to a 0x4+64B storage (note: compressed keys for p2pk are 0x3/0x2+32B), while p2pkh leads to only 20B (hash_160), p2pk transactions are for scriptPubKey: |public_key|OP_CHECKSIG

Depending on the use cases you can choose between both p2pk/p2pkh but for sure you will burn the DUST (because there is no private key associated to |data|), to understand this better please read https://gist.github.com/Ayms/04b3084a14ee202e707b3faec57ed26e#example-1-standard-p2pkh-pay-to-public-key-hash

This remains not expensive but not good practice at all, and a regression with the uncompressed deprecated public key concept, so let's hope that the bitcoin community will integrate the OP_RETURN change

Workaround 2 to the 80B OP_RETURN limitation

This one is less deviant than the previous workaround, the idea is to use the annex field of a Taproot transaction, which is not implemented today, please see https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2023-February/021486.html

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment