KomodoPlatform / komodo-defi-framework

This is the official Komodo DeFi Framework repository
https://komodoplatform.com/en/docs/komodo-defi-framework/
103 stars 94 forks source link

Add support for SLP tokens on the BCH network (Bitcoin colored coins) #701

Closed damascene closed 1 year ago

damascene commented 4 years ago

SLP tokens are Bitcoin colored coins on the BCH network. SLP stands for Simple Ledger Protocol. SLP tokens are growing in popularity, Tether is now available as a Standard Ledger Protocol token on the Bitcoin Cash network.

image

SLP tokens are cheap to trade, they benefit from BCH simple and low transfer cost ($0.0012). I've noticed that most stable currencies on the AtomicDEX are Ethereum based which makes it a bit expensive to trade, I think SLP tokens can solve this issue and benefit the project.

I'm opening this issue after a suggestion by KomodoWorld on reddit.

ca333 commented 4 years ago

thanks for opening this @damascene - we have additional protocol integrations on our post-RC roadmap (starting 2021) - however, there might be option to add SLP support as a 3rd party/community contribution before RC. Our core lead developer @artemii235 can provide you details/references ref. this topic. Thanks!

damascene commented 4 years ago

@artemii235 would like to hear your input on this, is it technically possible?

artemii235 commented 4 years ago

@damascene Hi! It's unclear for me now whether it's possible to implement an HTLC for SLP so I'm not able to say if the integration is 100% possible. To answer this question we should do a research on this topic, but we don't have resources for it right now.

But community contributions are always welcome. I think that we possibly can assign a bounty for such initial research, also there is Flipstarters BCH program that can be also used to fund such research and then integration if research shows that it is technically possible.

artemii235 commented 4 years ago

I'm glad to announce that HTLC proof of concept for SLP on Rust is eligible for 1000 KMD bounty! The requirements to receive it are as follows:

  1. The proof of concept must be implemented on pure Rust with pure Rust dependencies.
  2. The PoC should contain tests demonstrating creation of HTLC transaction for SLP of BCH testnet and then redeeming using secret and refunding the HTLC when time lock is expired (so there must be at least 2 tests).
  3. PoC must use Electrum client so the demo does not require local BCH testnet daemon configuration and sync.
  4. Using existing AtomicDEX-API code (e.g. for Electrum client implementation) is encouraged but not mandatory. AtomicDEX-API team can provide limited support to the developer who will be implementing the PoC in regards to this item.
molecular commented 4 years ago

I'm glad to announce that HTLC proof of concept for SLP on Rust is eligible for 1000 KMD bounty!

I'll throw in another 560 USD worth of BCH to whoever gets this bounty.

damascene commented 4 years ago

These resources could be useful for developers:

Rust libraries https://crates.io/crates/bitcoin-cash https://crates.io/crates/bitcoin-cash-slp

SLP Rust project Onchain trading console written in Rust that allows users to auction SLP tokens for bitcoin cash https://github.com/EyeOfPython/slpagora More info and a video here

More SLP resources: https://simpleledger.cash/get-started/ https://slp.dev/get-started/

Mint tokens online: https://mint.bitcoin.com

blockparty-sh commented 3 years ago

The SLP Foundation would like to add another $1000 in Bitcoin Cash to the bounty for a HTLC proof of concept for SLP.

We are also happy to assist in any questions related to SLP in building this POC. You can contact me directly on Telegram @blockparty_sh or tag me on GitHub.

dagurval commented 3 years ago
  1. The PoC should contain tests demonstrating creation of HTLC transaction for SLP of BCH testnet and then redeeming using secret and refunding the HTLC when time lock is expired (so there must be at least 2 tests).

Do these tests for HTLC transaction creation + refunding of any other UTXO-based coins exist? Something like “we want this, but it needs to support SLP”.

SLP tokens are client-validated. To know if we’re working with a valid token UTXO using electrum, we need to traverse its transaction DAG back to the token genesis transaction. To solve this issue, is this validation required, or can we assume we’re working with a valid SLP utxo?

artemii235 commented 3 years ago

@dagurval

Do these tests for HTLC transaction creation + refunding of any other UTXO-based coins exist? Something like “we want this, but it needs to support SLP”.

There are tests using komodod daemon in Docker: https://github.com/KomodoPlatform/atomicDEX-API/blob/mm2/mm2src/docker_tests.rs#L351. The common code building HTLC transactions for UTXO-based coins can be found at https://github.com/KomodoPlatform/atomicDEX-API/blob/mm2/mm2src/coins/utxo/utxo_common.rs#L537

SLP tokens are client-validated. To know if we’re working with a valid token UTXO using electrum, we need to traverse its transaction DAG back to the token genesis transaction. To solve this issue, is this validation required, or can we assume we’re working with a valid SLP utxo?

We can assume that we're working with valid SLP utxo, I think that we can omit the validation for PoC.

damascene commented 3 years ago

@EyeOfPython have offered to do it in for $4000. We have successfully added $2000 to the bounty in this Flipstarter https://flipstarter.googol.cash/ Hopefully we can get this done very soon :)

EyeOfPython commented 3 years ago

Hey, I can do it. I'm the author of the above mentioned libraries.

EyeOfPython commented 3 years ago

@artemii235 One question. I‘m using the secp256k1 library on Rust, which links to the libsecp256k1 library written in C. I have feature flags to switch over to the pure-Rust equivalent written by Parity, but I don't trust it as much regarding side channel attacks etc.

Would using secp256k1 defy your "pure Rust dependencies" requirement?

EyeOfPython commented 3 years ago

Also, could you provide a link to an Electrum client for Rust?

molecular commented 3 years ago

https://flipstarter.googol.cash/

that site doesn't load for me.

What about the 560 USD I pleged above? Should I "cancel" that pledge and "move" it to this flipstarter?

damascene commented 3 years ago

@molecular page is archived now. https://archive.is/O9HXr Don't cancel your pledge. The Flipstarter was to get extra fund for the project.

molecular commented 3 years ago

@damascene I see, thanks. Ping me when I should pay.

Thanks @EyeOfPython for offering to do this.

dth88 commented 3 years ago

ouch, I was actually working on this past week, almost ready...

EyeOfPython commented 3 years ago

Great news! I was able to finish the HTLC SLP PoC in Rust.

You can find the code here:

https://github.com/EyeOfPython/slp-htlc

SLP Hash Timelock Contract

Nomenclature and (modified) script taken from https://github.com/bitcoin/bips/blob/master/bip-0199.mediawiki.

Usage

Setup

Note: Apart from the RPC configuration, the below commands for the setup can also be done in the GUI. They are done via the commandline for reproducability here.

  1. Install Electron Cash SLP Edition (https://simpleledger.cash/project/electron-cash-slp-edition/) and locate its executable (assumed to be ./electron-cash from here on).
  2. Run ./electron-cash --testnet setconfig rpcport 7777 to set the JSON RPC port.
  3. Run these commands and keep the username and password ready:
    • ./electron-cash --testnet getconfig rpcuser
    • ./electron-cash --testnet getconfig rpcpassword
  4. Create the Seller wallet (seller is the party that will receive the SLP tokens, and presumably sell some other cryptoasset of value, e.g. ETH or BTC):
    • ./electron-cash --testnet create_slp -w ./sellerwallet
  5. Create the Buyer wallet (buyer is the party that sends the SLP tokens, and presumably buy some other cryptoasset of value, e.g. ETH or BTC):
    • ./electron-cash --testnet create_slp -w ./buyerwallet
  6. Run Electron Cash SLP edition either as daemon or GUI:
    • Either: ./electron-cash --testnet (GUI, for testing)
    • Or: ./electron-cash --testnet daemon (no GUI, for servers)
  7. In a new terminal, run ./electron-cash --testnet daemon load_wallet -w ./sellerwallet to switch to Seller's wallet.
  8. Get the address from seller's wallet:
    • Run curl --data-binary '{"id":0,"method":"getunusedaddress"}' http://<rpcuser>:<rpcpassword>@127.0.0.1:7777, where rpcuser and rpcpassword are the values from above, and keep the generated address ready.
    • Also send some tBCH to that address for the 'gas' for txs. 0.00010000 tBCH suffices. You might need to convert the address to bchtest for this.
    • Run curl --data-binary '{"id":0,"method":"slp_add_token","params":{"token_id":"<token_id>"}}' http://<rpcuser>:<rpcpassword>@127.0.0.1:7777, where token_id is the token you want to send.
  9. Run ./electron-cash --testnet daemon load_wallet -w ./buyerwallet to switch to Buyer's wallet.
  10. Fund the buyer's wallet:
    • Run curl --data-binary '{"id":0,"method":"getunusedaddress"}' http://<rpcuser>:<rpcpassword>@127.0.0.1:7777.
    • Send some SLP tokens to that address (prefix is "slptest"; if prefix is "bchtest", you loaded a non-SLP wallet previously; restart Electron Cash SLP in this case and load the daemon wallet anew).
    • Also send some tBCH to that address for the 'gas' for txs. 0.00010000 tBCH suffices. You might need to convert the address to bchtest for this.
    • Run curl --data-binary '{"id":0,"method":"slp_add_token","params":{"token_id":"<token_id>"}}' http://<rpcuser>:<rpcpassword>@127.0.0.1:7777, where token_id is the token you've sent.
  11. Setup complete!

Fund HTLC

From the setup above, you should have these values ready:

Also, you should be switched to Buyer's wallet.

Now we can fund the HTLC:

  1. Clone this repository (git clone https://github.com/EyeOfPython/slp-htlc.git)
  2. Run cargo run -- gen-secret and keep the secret and secret hash ready (this would happen on Sellers's computer). Example output:
    secret: eb5078d1f306784715040d1846871adfb476e848e7e7c6aaec1822bce35311dd
    secret hash: 6af9c9b8635b453c9ce522bf44a11f0afcd8ad9d
  3. Run the following command:
    cargo run -- \
        send-htlc \
        --token-id <token-id> \
        --amount <amount> \
        --seller-address <seller-address> \
        --secret-hash <secret-hash> \
        --timeout <timeout> \
        --uri <uri>

    Where:

    • token-id: token you've sent
    • amount: amount of the token you want to lock into the HTLC
    • seller-address: address from Seller we've previously generated
    • secret-hash: the secret hash Seller has provided us for this setup (from gen-secret)
    • timeout: UNIX timestamp for when this HTLC expires
    • uri: JSON RPC URI Example:
      $ cargo run -- \
      send-htlc \
      --token-id bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7 \
      --amount 1 \
      --seller-address slptest:qrzurumzwn7kwtcszk3jgpgfgecp4ws8wcvvxgnrts \
      --secret-hash 6af9c9b8635b453c9ce522bf44a11f0afcd8ad9d \
      --timeout 1607333086 \
      --uri http://<rpcuser>:<rpcpassword>@127.0.0.1:7777
      buyer address: slptest:qqcjtkw3a3mdh26y0ryrtfmxf4y2jhle6y72nalmlq
      timeout: 1607333086
      contract UTXO: 6912c3a61f715dba3067e0a17e5613f9d19edeea593b9456f952bd34de06faa5:1
  4. Keep keep the buyer address, timeout and contract UTXO handy (this would be sent to Seller).
  5. HTLC funded!

Redeem HTLC

From the fund step above, you should have these values ready:

  1. Run ./electron-cash --testnet daemon load_wallet -w ./sellerwallet to switch to Seller's wallet.
  2. Run the following command:
    $ cargo run -- \
        redeem-htlc \
        --contract-utxo <contract-utxo> \
        --buyer-address <buyer-address> \
        --secret <secret> \
        --timeout <timeout> \
        --seller-address <seller-address> \
        --uri <uri>

    Example:

    $ cargo run -- \
        redeem-htlc \
        --contract-utxo 6912c3a61f715dba3067e0a17e5613f9d19edeea593b9456f952bd34de06faa5:1 \
        --buyer-address slptest:qqcjtkw3a3mdh26y0ryrtfmxf4y2jhle6y72nalmlq \
        --secret eb5078d1f306784715040d1846871adfb476e848e7e7c6aaec1822bce35311dd \
        --timeout 1607333086 \
        --seller-address slptest:qrzurumzwn7kwtcszk3jgpgfgecp4ws8wcvvxgnrts \
        --uri http://<rpcuser>:<rpcpassword>@127.0.0.1:7777
    contract_amount: 10000
    token_id: TokenId(Sha256d(bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7))
    57d3446c56b3557825cbb8b7f618d0ccef0fd26bef217e30d838ec413dcd2d86
  3. HTLC redeemed!

Timeout HTLC

Run the Fund HTLC section again to generate a new HTLC.

This will give you these values:

Example:

$ cargo run -- gen-secret
secret: e51e578fd319d8a1b8b55256b3a0c9773a931252398f13847b89d789b9835e00
secret hash: 82fa07e4ee949640eb4eb5ed509c8a8732640b97
$ ./electron-cash --testnet daemon load_wallet -w ./buyerwallet
$ cargo run -- \
    send-htlc \
    --token-id bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7 \
    --amount 1 \
    --seller-address slptest:qq49s69jttj8ay9fuqknttrwxesztm88vqfrk4c040 \
    --secret-hash 82fa07e4ee949640eb4eb5ed509c8a8732640b97 \
    --timeout 1607334641 \
    --uri http://<rpcuser>:<rpcpassword>@127.0.0.1:7777
buyer address: slptest:qqcjtkw3a3mdh26y0ryrtfmxf4y2jhle6y72nalmlq
timeout: 1607334641
contract UTXO: ef44a5ee9e481b8eb2343d8e46417281a90a02051f3bc1ef901229fcab5b555f:1
  1. Run the following command:
    $ cargo run -- \
        timeout-htlc \
        --contract-utxo <contract-utxo>
        --seller-address <seller-address>
        --secret-hash <secret-hash>
        --timeout <timeout>
        --buyer-address <buyer-address>
        --uri <uri>

    Example:

    $ cargo run -- \
        timeout-htlc \
        --contract-utxo ef44a5ee9e481b8eb2343d8e46417281a90a02051f3bc1ef901229fcab5b555f:1 \
        --seller-address slptest:qq49s69jttj8ay9fuqknttrwxesztm88vqfrk4c040 \
        --secret-hash 82fa07e4ee949640eb4eb5ed509c8a8732640b97 \
        --timeout 1607334641 \
        --buyer-address slptest:qqcjtkw3a3mdh26y0ryrtfmxf4y2jhle6y72nalmlq \
        --uri http://<rpcuser>:<rpcpassword>@127.0.0.1:7777
    contract_amount: 10000
    token_id: TokenId(Sha256d(bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7))
    dff9d9964d5276794d82f5e930aeb9f3a2088dd34744a6d815e89e19d6fd4203
  2. Wait for MTP timeout to arrive.
  3. HTLC refunded!
artemii235 commented 3 years ago

Hi @EyeOfPython, please excuse me for long response, I was offline on weekend.

One question. I‘m using the secp256k1 library on Rust, which links to the libsecp256k1 library written in C. I have feature flags to switch over to the pure-Rust equivalent written by Parity, but I don't trust it as much regarding side channel attacks etc. Would using secp256k1 defy your "pure Rust dependencies" requirement?

It is fine to use the libsecp256k1 written in C, we were using the pure Rust version from Parity too, but already switched back some MM2 subcrates back to secp256k1 C bindings.

Also, could you provide a link to an Electrum client for Rust?

The code is here: https://github.com/KomodoPlatform/atomicDEX-API/blob/mm2.1/mm2src/coins/utxo/rpc_clients.rs, it is planned to publish it as separate crate one day, but as I can see you were able to complete a PoC without it.

Great news! I was able to finish the HTLC SLP PoC in Rust. You can find the code here: https://github.com/EyeOfPython/slp-htlc

Great! I need some time to check and test the code, will post a comment tomorrow in regards to this, thanks!

artemii235 commented 3 years ago

@EyeOfPython Hi! I've started checking the PoC and noticed that I don't know any SLP token on BCH testnet. Could you please send some to following addresses and give the corresponding token_id? qr7rn5l339y50hy8ls0hx5czz6jxuhpmss6mmqp3wh qp572pj0nhfvrsau8493cl9vzxt50atr5ca0lm42pf

Could you please also provide info on how I can convert the above addresses to the bchtest? Would be best if you can add the code of such conversion to the PoC repo.

EyeOfPython commented 3 years ago

I send 10 Fake USD to each of those addresses! Token ID is bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7.

Btw, minting SLP tokens is really easy in Electron Cash SLP, but I would say overkill for this.

Tell me if you need more tokens, they're literally worthless.

artemii235 commented 3 years ago

I send 10 Fake USD to each of those addresses! Token ID is

Thanks a lot!

Could you please also provide info on how I can convert the addresses to bchtest: prefixed addresses? I guess SLP has a different address generation algorithm and it is not quite clear to me now how I can convert them without digging too much into the code.

dth88 commented 3 years ago

@artemii235 you can try https://trest.bitcoin.com/#/slp/convert

artemii235 commented 3 years ago

@dathbezumniy Thanks! That's what I was looking for :slightly_smiling_face:

artemii235 commented 3 years ago

Well, Electron Cash wallet also allows this conversion, I used this in CLI mode only so didn't notice it.

artemii235 commented 3 years ago

Can someone send me some tBCH to following addresses please? bchtest:qr7rn5l339y50hy8ls0hx5czz6jxuhpmssp0ummxu2 bchtest:qp572pj0nhfvrsau8493cl9vzxt50atr5cxmcq0an5

I was able to find a working faucet, but it sent too low amount which seems to be not sufficient to test the HTLC transactions.

EyeOfPython commented 3 years ago

I sent 3 tBCH to each address. Should be enough for tens of thousands of txs. If you think you don't need them anymore, you can send it to a child in need or back to me: bchtest:qpxe6keqxxeuucquep58yread0ljyglefszmpm70tu

artemii235 commented 3 years ago

Perfect, thanks a lot! I have everything set up now, will continue a test tomorrow and get back here.

EyeOfPython commented 3 years ago

Awesome. If there are any errors or something wrong let me know. The slpvalidate command can be a bit unreliable at times, we might need to switch at some point.

artemii235 commented 3 years ago

Good news, I have been able to successfully send SLP HTLC transactions using the provided PoC code!

HTLC 1: https://explorer.bitcoin.com/tbch/tx/26adf2466d270cb02118d6bf62db52ed98f5822cdbdb9bbe6a74aea1cfcd3113 HTLC 1 Refund (timeout): https://explorer.bitcoin.com/tbch/tx/5e958d2c9f6ed594085d33e898a32ff394640c211b1e050c233ffd49111f62a2

HTLC 2: https://explorer.bitcoin.com/tbch/tx/475e97da892a6ffba706a13140a6f975fada8933f43fb5ca06f2cb024a5f2f6e HTLC 2 redeem: https://explorer.bitcoin.com/tbch/tx/4800fef53866322eaf2fb1fc9c03ccd1ffe745c1403df383351c076cf885cfd3

I need a bit more time to dig into code and understand it better. I will have some questions maybe, but it shouldn't take too much time, so I guess I will make a final approval on the bounty on this week.

EyeOfPython commented 3 years ago

That‘s great to hear! I thought about adding comments, as especially the contract code requires some knowledge of how the bitcoin-cash crate works, but unfortunately I‘m quite busy this week. I‘ll answer all the questions you have though.

Cryptovato1 commented 3 years ago

Hello guys, in case you wanna try RFND token (SLP token) for testing, let me know at @Cryptovato1 on Telegram or Twitter. Whatever we can do for you, let me know.

EyeOfPython commented 3 years ago

Hey @artemii235 any updates? Any way I can help?

artemii235 commented 3 years ago

Hi @EyeOfPython, please excuse me for the delay, we had a major AtomicDEX stress test event 1 week ago, so I have been busy with preparations for it. I had some rest afterward on the previous week. I will continue with the PoC code review tomorrow and get back to you. Thanks for following up!

artemii235 commented 3 years ago

Everything looks good and quite clear! I have only 1 question: for send_htlc you make requests to Electron cash API to generate and sign a transaction, https://github.com/EyeOfPython/slp-htlc/blob/master/src/send_htlc.rs#L50. For redeem_htlc and timeout_htlc you generate and sign a transaction using TxBuilder without additional calls to Electron cash. Do I understand correctly that the same tx generation code can be used in send_htlc too?

EyeOfPython commented 3 years ago

Yes, that is correct. I’m using payto_slp because it’s quite a bit shorter, and it adds the inputs for me already.

For redeeming the HTLC, I have to use TxBuilder, since Electron Cash SLP doesn’t have that built-in, so I have to build the transaction manually. For send_htlc, I don’t have to do that, since it’s just a P2SH output, which Electron Cash SLP knows how to handle.

artemii235 commented 3 years ago

@EyeOfPython

Thanks for the explanation! We can consider the proof of concept as done, thanks for your work on this! Could you please provide your KMD address to send you the 1000 KMD bounty? You can DM it to me at Komodo Discord (https://discord.com/invite/VG7uDgAhwa), my Discord tag is artem.pikulin#0794.

@damascene @molecular @blockparty-sh You can release the Flipstarter and other additional BCH bounties too.

I need to discuss the further SLP integration steps with the team, will post a comment here in regards to this soon.

molecular commented 3 years ago

@EyeOfPython looks like you're receiving the bounty. Thanks for your awesome work.

As per my promise above I owe you 560 USD worth of BCH. Please give me an address (either publicly or privately. In case you do it privately can you please acknowledge reception of the funds here publicly once you received them?)

damascene commented 3 years ago

@artemii235 Thank you and thanks to your team for your efforts. We are looking forward to your response. @EyeOfPython thank you for doing the PoC. I've contacted you on Telegram to get your BCH address.

EyeOfPython commented 3 years ago

@artemii235 I sent you my KMD address on Discord. My handle is Tobi#5433.

EyeOfPython commented 3 years ago

Got the coins. Thanks @artemii235 and @damascene!

@molecular could you send me your telegram handle so I can send you the address?

molecular commented 3 years ago

@EyeOfPython I fail to find you on tg, can't DM you on twitter or here. So I wrote an email to your be.cash contact address, hoping it's going to be you reading that.

molecular commented 3 years ago

@EyeOfPython i got an address via tg. Can you confirm that's you?

EyeOfPython commented 3 years ago

Yep! That’s me

molecular commented 3 years ago

@EyeOfPython ok thanks, I sent 540 USD in BCH to the address you gave me via telegram.

EDIT: just noticed I didn't send enough. 20 USD missing. Will send those, too.

EyeOfPython commented 3 years ago

Thanks to @blockparty-sh and @molecular. Got all promised payments now. Merry Christmas everyone and a happy new year!

damascene commented 3 years ago

"AtomicDEX SLP integration" flipstarter have been fully funded!

https://slp.flipstarter.atomicdex.cash/ Archived copy: https://archive.is/pZ8yi

artemii235 commented 3 years ago

"AtomicDEX SLP integration" flipstarter have been fully funded!

Yeah, we have noticed it too, thanks! We will make a development plan for the full SLP integration next week and start working on this no later than April 1st (hopefully earlier). I will keep everyone posted about the progress.

artemii235 commented 3 years ago

Here is the development plan for April:

artemii235 commented 3 years ago

Report about integration progress in April. The implementation start was delayed as I had to finish other planned tasks prior to the SLP.

  1. Researched the SLP documentation.
  2. Setup local regtest BCH node (not dockerized yet). Added unit test minting the token on it (GENESIS transaction).
  3. Started implementation of the SLP OP_RETURN script parser to get the balance of the token.
  4. WIP PR merged to the dev branch: https://github.com/KomodoPlatform/atomicDEX-API/pull/925. Current working branch to be merged this week: https://github.com/KomodoPlatform/atomicDEX-API/tree/mm2.1-slp-arrr

Development plan for May:

  1. Finish what was planned for April. Dockerize BCH regtest, finish OP_RETURN script parser, implement balance retrieval and withdraw unit tests.
  2. Integrate HTLC transactions based on the PoC code with unit tests.
  3. Start integrating SLP unit test data (https://github.com/simpleledger/slp-unit-test-data/) into our tests.