Cardano CL and Peer-to-Peer Trading

I’ve only been looking at this space over the past few months. So I apologize for the newbie question. Once Cardano CL is up and running, can I write a smart contract template with a multisig component to do Peer-to-Peer/OTC trading. For example, lets say I wanted to buy a large amount of ADA direct from someone on the forum to avoid all the games on the exchange. We would decide price, volume, and pair to use - Eth or BTC. Then a smart contract would be written that would execute once both counterparties signed. Lastly, the trade executes pulling from BTC or Eth address and ADA address in contract. I assume this is how it would work. Seems pretty straight forward but I would like to hear from developers on here, on whether I’m missing anything, and whether there are security issues to be concerned about in such a transaction. Many thanks!


I think it’s possible and not that hard :slight_smile:

Algorithm could go like this:

  1. You create a contract with three functions: PrepareTrade, ConfirmTrade, RevokeTrade

  2. You (Address A) and I (Address B) are negotiating a trade off-chain (on the chat, for example), and we come to a price, like: I am ready to buy your 10 BTC for 100 ETH

  3. Then you call on-chain function PrepareTrade and you send these arguments:

    1. funds - 10 BTC sent from address A
    2. price - “100 ETH”
    3. buyer - my address B
  4. Note that funds in this case is actual BTC, but price is just a number and a token ID

  5. Function locks BTC and price in internal state, and returns you a number like TradeId - you send this number to me in the chat

  6. I call on-chain function ConfirmTrade and I send these arguments:

    1. tradeId - the identifier you’ve sent me
    2. funds - 100 ETH from my address B
  7. When function executes - contract sends initial 10 BTC to my address, and my 100 ETH to your address, and closes internal state (trade is closed).

  8. If I send wrong number of ETH or from wrong address - the function ConfirmTrade just returns it to me with an error message. The same happens if I send wrong tradeId

  9. If you have locked up your BTC, but I never showed up - you can call function RevokeTrade with the same tradeId from the same address where BTC came from and this function will cancel the internal trade-state and return BTC to you.

But in the case of revoking - you will lose the money on transactions. There also could be a more complex option, where:

  1. You (as contract owner) initially send some ADA to the contract and lock it up as “deposit bank”

  2. Anyone can call functions like CheckDeposit and see that there’s some ADA

  3. When we agree on a trade - I initiate the trade by sending my 100 ETH. The function creates a trade with some timeout (couple of days or hours).

  4. You can see the resulting TradeId on the chain and confirm the trade by sending your 10 BTC

  5. But if you never show up, after timeout is over - I can call RevokeTrade and get back my ETH and some ADA from your fund to refund my losses of time and transaction payments.

In this version - there’s no trust required.

P.S. There’s a lot room for fantasy and creativity, but it’s definitely possible :slight_smile:

UPD: For now you can learn the Solidity language (for Ethereum). It will give you the basic understanding of programming for a chain. And when CL is released you will be actually able to write your Cardano contracts in Solidity, so time will definitely not be wasted )

You can find nice beginner lessons here:


You are a star vantuz-subhuman. Many thanks for the detailed response. I’ll spend some time on this to digest properly and probably come back with a follow up question or two. This could be a worthwhile project to work through once CL is running. You’d want high assurance code for this obviously. So would it be better to wait for Plutus or do you think it’s basic enough to do in Solidity without concern? You’d need this to be iron clad and unbreakable if you are moving large amounts of value. Regardless, I think I will follow your advice on learning a bit about Solidity as it will help me understand the basic structures of how to program for a chain, and what is possible.

Thanks again. I really appreciate it.


You are very welcome to do exactly this! :slight_smile:
Any questions are welcomed, since I’m also the one learning while discussing things like this.

  1. The basic version of something like this is simple enough to be verified by “by eyes” )

  2. Solidity just would be a much easier start to learn about the whole on-chain programming and execution. So, whatever your final language of choice will be, the few first versions in Solidity would be a good thing any way. Plus, for now, Solidity is only option anyways )

  3. The best option would be to wait for Blockly and implement this thing in it: :smiley:

Exactly :+1:


For the first version you could try the most simple option: a contract with a single trade at a time. The version that I have described would be able to store multiple prepared trades in the same time, that’s why it should return a TradeId. It might be useful if you negotiate multiple big trades at the same time. So while one of your trades is still locked up and is waiting for the buyer - you could already initiate another trade with someone else.

But for the first version you can create a simplest contract with just few variables, so it could store just a single trade at a time, and if you try to initiate new trade - it returns an error like “Previous trade is not yet closed.” This would be a good starting idea to work towards.

Also, you can already start experiment with code on Ethereum test-net, but instead of exchanging BTC or ADA - you will have to use some ERC-20 tokens maybe. Like, exchanging TRX for ICX, or for ETH. But it also would be a good starting point, to learn how to interact with other contracts.

When Cardano CL test-net is launched - it will support something like “sidechain tokens” (to move BTC or ETH onto Cardano chain and move it around). There are yet no specific details on how exactly it will work in Solidity, but I reckon the main principles will be somewhat similar. So then you will be able to deploy the same Solidity contract into Cardano test-net. With maybe some little changes.

I forgot to mention that, undoubtedly, it would be a worthwhile and interesting thing to work on, and I most certain that we’re a yet to see a lot of services like this. Something like a “whale exchange” :slight_smile:

Not that long ago I wrote a comment about a market-cap and mentioned exactly something like this, when off-exchange trade is necessary, but then I mentioned how it used to be done by “finding a couple of lawyers” and writing a contract. And in the blockchain era it can easily be done with a simple smart-contract, and this is beautiful :slight_smile:

Here’s the comment I’m talking about, for reference:

1 Like

Agreed. This would be optimal.

Something to consider would be the structure needs be trustless in many cases, in the sense that you do not want your counterparty to be able to use time to game the transaction by waiting to sign intentionally. If the market moves against them then they are not obligated to execute. So time of execution needs to be tight. If it’s a known party then this is less of an issue.

I wish this were available now. It looks particularly useful to newcomers like myself.

Indeed. This is the most attractive aspect of this technology to me. Contracts are only useful if you can enforce them economically. I can have a paper contract that states deliver this particular commodity at X time and Y price, but if the counterparty decides they do not want to honor the deal then I am in for significant legal costs, and lots of time wasted with no guarantees. Smart contracts as movers of value enforce delivery and take this risk off the table. This is a complete game changer - assuming it is adopted into mainstream commerce.

So you are saying each counterparty sets up a ‘deposit bank’ to cover fees and some losses. Is that right? I like this. Calculating the amounts, and lock up period deserves some consideration. Maybe it would be a margin-like calculation with estimated fees. It gets complex. This would be a good setup for someone you plan on doing multiple trades with for sure. Having fun thinking through this. :slight_smile:

1 Like

@cdufour, I think this short nice paper might be of service to you. It might help to reason about smart-contracts.

“An Ontology for Smart Contracts” Darryl McAdams (IOHK)

Yes, initially I thought something like this, but then I gave it a bit of thought and come to a conclusion that there’s probably no way to make it absolutely trust-less. At minimum, someone will have to risk a single transaction fee and gas-costs, cuz someone must to initiate the protocol (a trade-exchange), and the other agent then may just not show-up. My considerations for now:

The way I proposed it (you set up a fund in advance, and then another agent will get a refund if he initiates a trade, and you don’t show up) - of course cannot be implemented in this naive way, since:

  1. Either you will be DoS-ed by malicious agents that will initiate trades without your knowledge and then will collect refunds, making it look like you didn’t show up.
  2. Or you will need to approve a refund, which contradicts the whole idea.

At first I though that I’m gonna describe the general naive idea, and then maybe specify it afterward. But now I’m thinking that it’s actually unsolvable, until there gonna be some “free” transactions in Cardano network, but I reckon we all know Charles’ point of view about free transactions :slight_smile:

So the basic idea is that: whoever makes the first request to the contract - he is the one at risk, since the other party may just ignore the protocol. And there’s no way (known to me at this point) to lock funds in a contract in a way that would be completely trust-less and would not allow for malicious withdrawals.

To solve it in any useful way - we need to assume some minimal trust. And this minimal trust, I think, may be reduced to you initialising the trade like I’ve described in the first post (without any safe-funds). Accompanied with customisable deadlines (described further in this comment) it might be safe-enough, considering the fact that trades are big and discussed on personal level.

On the other hand, system may be designed in the other way, where client initiates the trade, but also with no safe-funds from your part. The difference is where to put trust: either you say that you trust the client, or you say that client have to trust you, since you have the service and reputation. That’s where the assumptions go.

P.S. I might eventually come up with some vague and complex system of half-trustless tx-exchanges that would initiate a kind of a everyone-at-risk state of mutual distrust that would be a kind of an optimum for the whole thing. But it most-probably will not be that much useful :slight_smile:

The PrepareTrade function may also take maxExecutionTime argument that allows you to set the deadline to honor the deal, and when it passes - you may call the RevokeTrade function to cancel the whole thing. The main thing to consider is that in the smart-contracts there’s no “actual” time, so the best way to set-up durations is in “number of slots”. Like we know there are 3 slots a minute (for now), so if you specify that a trade must be honored in 180 slots - it means that other Agent have about an hour to close the deal.

Additionally (in continuation to the previous part) - you still could actually use safe-funds to protect yourself from overdue trades. So like if the client is new and not yet trustworthy - he have to initiate the trade and lock some funds. The problem (why previous part of the post) is that he would have to trust you in this case. So some trust is still assumed in the system.

I also thought up an additional possible function for your contract :slight_smile:

You could perform a multi-party trades. Example:

  1. There are 3 parties: You, Me, and our friend Nick the Greek
  2. You have 10 BTC and want to get 100 ETH
  3. I have 100 ETH and I want to get 100’000 XRP (Assume I’ve gone mental)
  4. Nick the Greek have 100’000 XRP he bought at $2.75 and he want to get 10 BTC for them
  5. I don’t want to get BTC, if I don’t certainly get XRP for them (Completely mental)
  6. Nick the Greek don’t want to get ETH if he don’t certainly get BTC
  7. You don’t want to get XRP, cuz you’re not mental

The three of us are in a pickle. And here comes your super-contract :slight_smile:

The algorithm is kinda like this:

  1. You initiate the trade with PrepareTrade, where you put 10 BTC and say that you want to get “10 ETH” for it and set my address as buyer, and set deadline of one hour.
  2. Instead of closing the deal, I call another function, like RedirectTrade, where I send my 10 ETH and say that I want “100’000 XRP” and set Nick the Greek’s address as buyer.
  3. But my transaction does not close the trade, but instead just also locks the ETH and updates the state, so now Nick the Greek has the option to do his part. For him the trade looks like I offer 10 BTC for his Ripples. So he then calls ConfirmTrade function as usual, sending his XRP there.
  4. The “global” deadline for the whole trade remains the same, so if I’ve spend 15 minutes to send my part - Nick the Greek have only 45 minutes left.
  5. If everything gets sent as expected - the whole trade executes, so Nick’s Ripples are transferred to me, My ETH is transferred to you, and your BTC is transferred to Nick.
  6. The best part is that if Nick changes his mind and does not honor the deal - we cancel the trade and get our funds back.
  7. The best best part is that it doesn’t have to be strictly 3-party trade, so in the most general way - Nick might also call RedirectTrade and offer your BTC (that he eventually may get) to someone else in exchange for something different. So the trade is actually may chain to any length, until it’s either honored, or deadline reached.

So, as I said - many room for creativity :slight_smile:


Love the Lock, Stock and Two Smoking Barrels reference


Agreed. There are trade offs and being stuck with some minimal fees is something it seems you’d have to accept. For larger OTC decentralized trades that are off exchange like this, it might be optimal for this not to be anonymous, with some sort of KYC involved. So if someone flakes on a trade you’d know not to do business with them in the future. If it’s not peer-to-peer and more commercial the regulators are going require that anyway - if not now then in the future. The smart contract still solves some trust issues despite it’s imperfections.

You will probably end up with different contracts for customer type:

  1. Trustless 2. Semi-trusted and 3.Trusted

I didn’t think about this. You’ll have to have a very good idea about network congestion at that point in time in order to set maxExecutionTime properly. Though RevokeTrade gives some buffer for a trusted counterparty.

Lol… I had a good laugh when I read this. Kudos to making a smart contract description entertaining. That kind of transaction is called legging into a trade, and using smart contracts in a decentralized marketplace to execute that would be pretty cool.


This announcement is germane to our discussion.

I knew this was coming. But peer-to-peer outside an exchange (decentralized) is still much more attractive, as you do not have to announce your price and terms to the world.


I just found this presentation, which was quite useful to me as a layman. It laid out some of the logic and structure nicely. I’m really going down the rabbit hole here. :slight_smile: