Our team is pleased to present you a fully decentralized infrastructure for two-way exchange between the following blockchains / tokens:
Free TON <-> Ethereum
Free TON <-> ERC20 Token (currently USDT supported)
Free TON <-> Bitcoin in progress…
The exchange is based on HTLC Smart Contracts on each blockchain. This type of contracts allows exchanges between blockchains with guaranteed atomicity - that is, the exchange will either take place, or you will receive your funds back.
At the moment, HTLC smart contracts have been implemented for the following blockchains:
Bitcoin Script for Hashlock & Timelock (built into js library)
To place / search for orders, as well as synchronize the exchange between participants, an order book based on a smart contract in the TON network is used. It allows you to place orders for both buy and sell tokens with an indication of the volume range, exchange rate and maximum time for blocking funds.
Work with a smart contract is carried out by depositing TON CRYSTALS to the account of the order book contract, after which the funds are blocked for the duration of the exchange. This makes it possible to guarantee the receipt of funds by the buyer, and prevents the placement of a large number of fake orders.
Since there is no intermediary when exchanging through the Free TON smart contract, you do not need to pay commissions for the exchange, only commissions for the transactions themselves. When you make a deposit, the amount required to cover the storage fees of the smart contract data is debited from you (after the automatic calculation of the storage cost function is implemented, this amount will not exceed 0.001 TON CRYSTAL).
User support can be provided on a paid basis as an additional service (which is often found in the open source world).
https://youtu.be/cYRapYvWuFo - This video demonstrates the automatic exchange between USDT <-> TON CRYSTAL with comments (on test networks ropsten and net.ton.dev). Links to transactions are provided in the video description.
Implementation and demonstration smart contracts of Atomic Swaps:
Ton Crystal, Native Ether, Ethereum ERC20, Bitcoin
Develop an infrastructure that allows users to perform transactions between different blockchains without escrow in an untrusted environment. It will make the exchange market around TON Crystal more secure for OTC transactions.
Atomic Swap — a smart contract technology enables the exchange of one cryptocurrency for another without using centralized intermediaries (such as exchanges).
I’ve learned two ways of swaps:
By using Hashed TimeLock Contract
By using Simplified Payment Verification.
HTLC — the most simple. It requires supporting common hash function (e.g. sha256) from blockchain and TimeLock contract functionality. + Сan be fully decentralised - Requires side communication between participants and locking money on specific time
SPV requires from one of two blockchains supporting runnig complex smart contracts (e.g. Ethereum or Ton) to verify transaction’s Merke Proof of transfer. + Transfer can be fast and automatic - Requires solution to identify the source of the transaction: mainnet / testnet / side blockchain by using oracles smart contracts / supporting SPV verification by validators.
I chose HTLC, because:
Time of contest is limited to 3 weeks
High transmission speed can be achieved through automation Atomic Swap Wallet, which supports SPV verification different blockchains off-chain.
FreeTon: TON-Solidity-Compiler, Solidity, JS for testing Ethereum: Truffle, Solidity, JS for testing Bitcoin (Work in progress): bitcoinjs-lib, JS
./ton - Atomic Swap Contracts for FreeTon blockchain ./eth - Atomic Swap Contracts for Ethereum blockchain ./btc - Atomic Swap Contracts for Bitcoin blockchain ./app - App for demostrating working of Smart Contracts at testnets. Not used in production, only for learning purpose
Part A have to generate the secret limited by 32 bytes and store it securely. Next, Part Ainitiate and create contract with hash of secret and participant’s address. In this contract the locktime should be doubled to avoid scam (e. g. 24h * 2 = 48h). After that, Part A have to send transaction or smart contract address to Part B.
Part B have to verify Part A’s contract: participant’s address, lockTime, amount, hash of code. If everything is OK — Part B should participate and create contract with Part A’s secret hash, otherwise Part B can do nothing. Part B should be careful, lockTime should be less Part A’s lockTime at the moment of creating contract. After, Part B have to send transaction or smart contract address to Part A.
Part A have to verify Part B’s contract. If everything is OK — Part A can redeem from Part B’s contract and reveal secret, otherwise Part A can wait timeLock and refund his transfer.
Part B should extract secret and redeem from Part A’s contract.
The most part of steps can be automated by wallet, with the exception of exchange address and transactions
contract AtomicSwap - This contract implements Hashed TimeLock Contract. Lock ton crystals until lock time or redeem by secret.
constructor(address initiator, address participant, uint128 amount, uint32 timeLock) public - Constructor for creating Atomic Swap. Initiator must ptovide all required params. Constructor can be called in two ways: by external or external message. At first case, initator should send a small amount ton crystals to UNINIT account before deploying with bounce=false. After deploying initiator must send rest ton crystals. At second case, internal message, initiator must send required amount of ton crystals with internal deploy message.
function redeem(bytes secret) external; - Redeem Atomic Swap by participant before time lock. Emit Redeemed event to reveal secret. Sender must be participant. Destruct contract after execution.
function refund() external; - Refund Atomic Swap by initiator after time lock. Sender must be initiator. Destruct contract after execution.
function params() public view returns (address initiator, address participant, uint32 timeLock, uint32 now, uint256 secretHash, uint128 amount, uint256 balance) - Fetch params of Atomic Swap to verify it.
Bitcoin Atomic Swap Smart Contract
Here is implementation of Hashed TimeLock Contract for Bitcoin using Script. This library doesn’t interact with blockchain and don’t implement wallet logic. Using this lib you can create raw transactions or calculate p2sh address of Atomic Swap. For interacting with bitcoin blockchain you should use your wallet, but I reccomend bitcoin-core.
Command line interface for testing bitcoin Atomic Swap contracts on regtest. To run it you should run regtest bitcoin network and send bitcoins to Alice’s and Dave’s p2wpkh addresses. In this exmaple Dave want to transfer btc to Alice using Atomic Swap.
node ./test/AtomicSwapTest.js create - creates p2sh address of Atomic Swap contract. Next you should send required bitcoins to this address using your bitcoin-core wallet from Dave p2wpkh address. At this step we store params, secretHash adn etc. in file ./test/db.json to avoid passing them through cli.
node ./test/AtomicSwapTest.js verify <p2shAddress> - Alice should verify that p2shAdress have right params. Participant and Initiator public keys, secretHash, timeLock.
node ./test/AtomicSwapTest.js redeem <tx-id> <tx-vout> <tx-hex> - to redeem Atomic Swap you need to provide params of transaction, that was send with bitcoins to p2shAddress. You can use bitcoin-core to get it. This command returns hex of transaction that you need to send using sendrawtransaction in bitcoin-core. After this step Atomic Swap transfer is redeemed by Alice.
node ./test/AtomicSwapTest.js refund <tx-id> <tx-vout> <tx-hex> - to refund Atomic Swap you need to provide params of transaction, that was send with bitcoins to p2shAddress. You can use bitcoin-core to get it. This command returns hex of transaction that you need to send using sendrawtransaction in bitcoin-core. After this step Atomic Swap transfer is refunded by Dave.
This contract implements Hashed TimeLock Contract. Lock bitcoins until lock time or redeem by secret. I’ve used in contract OP_CHECKLOCKTIMEVERIFY and OP_SHA256.
function createAtomicSwapScript(secretHash, initiatorPubKey, participantPubKey, lockTime) - creates an atomic swap contract using Bitcoin Script.
function createAtomicSwapRedeemScript(signature, participantPubKey, secret) - creates an atomic swap redeem script. Can be used together with #createAtomicSwapScript.
function createAtomicSwapRefundScript(signature, initiatorPubKey) - creates an atomic swap redeem script. Can be used together with #createAtomicSwapScript.
contract AtomicSwap - implements Hashed TimeLock Contract. Lock native ethers or ERC20 tokens until lock time or redeem by secret. Everyone can deploy this contract or use already deployed contract by another person.
function createSwap(uint256 secretHash, address participant, uint256 value, uint256 timeLock) external payable - creates Atomic Swap transfer from sender to participant. Lock native ether value until timeLock or redeem. secretHash is unique identifier for Atomic Swap. Be careful while generating secret.
function createSwapErc20(uint256 secretHash, address participant, uint256 alue, uint256 timeLock, address tokenAddr) external - creates Atomic Swap transfer from sender to participant. Lock erc20 tokens value until timeLock or redeem. secretHash is unique identifier for Atomic Swap. Be careful while generating secret. tokenAddr is address of ERC20 compatible smart contract.
function redeem(bytes calldata secret) external - redeem Atomic Swap by participant before time lock. Emit Redeemed event to reveal secret. Sender must be participant.
function refund(uint256 secretHash) external - refund Atomic Swap by initiator after time lock. Sender must be initiator.
function params(uint256 secretHash) public view returns (address initiator, address participant, uint256 timeLock, uint256 currTime, uint256 value, address tokenAddr, SwapType swapType) - fetch params of Atomic Swap to verify it.
2 users participate in this example: 0-Alice and 1-Bob. Alice has ton rubins and want to buy Ether. Bob has Ether, want to buy ton rubins.
I will use Atomic Swap cli interface.
Atomic Swap cli help message:
$ node ./app/app.js -h
Usage: app [options] [command]
-V, --version output the version number
-u, --user <number> user id, can be used to specify user (default: 0)
-h, --help display help for command
ton command for freeton blockchain
eth command for ethereum blockchain
btc command for bitcoin blockchain
reset reset keys and wallets
help [command] display help for command
Need to check users have working wallets and positive balances. Deploy wallet if need.
-u 0 - parameter for Alice -u 1 - parameter for Bob
The only drawback, as it seems to me, is that there is little originality in this competition, everyone went the same way and uses HTLC. Perhaps the next competition will be for the implementation of Bitcoin SPV, as mentioned in the link above . I have just worked out in this direction, the code turns out to be really more complex.
Tell me, is any of the works production-ready?
Personally, I make my own just so that I can use it myself later. If there are ready-made ones, I would use them for exchanges. And if not, what are the plans to bring the contest works to working condition?
Is it possible to verify Ethereum’s Merkle tree with keccak256 and check ethash PoW in TON VM?
Or verify TON Ed25519 signature in Ethereum VM?
HTLC require only the presence of a sha256, which is found in many blockchains. In this sense it is much more versatile.
I can only say for our project. It is not production-ready, it will take several months to complete.
Improvement is required not only in the part of the UI, but also a number of problems need to be solved, for example, the possibility of loss of funds, which I wrote about in an article on Medium (only in Russian)
idk, to my shame. That’s why I didn’t plan to integrate with Ethereum at first. In any case, this would be too expensive for SPV due to more frequent transactions. So for a combined BTC-ETH contest, the HTLC seems the only right solution, agree.
One of the tough conditions for implementation was this:
Tell me, which of you added this functionality to your solution?
Please do not be angry if I was inconsiderate and did not see this in your submission. Just answer. Thank.
Here I see some lack of specifics in the assignment. Who is a broker? The presence of the owner person, in the sense that he is the only one organizing the exchange, makes the solution partially centralized, and the owner - the main point of failure. This means that the service cannot be highly reliable. The arrest and shutdown of some centralized mixers and exchanges is a clear confirmation of this.
Therefore, we designed our solution with decentralization in mind. There is no “owner” here, only the “creator”. Which deploys a TON Orderbook smart contract and that’s it. He does not incur any operating costs and does not receive any fees. In our solution, the broker is a smart contract. It collects a constant fee when depositing (see the receive () function in tonorderbook.sol) to cover the smc storage fee (it is also constant).
This is the same approach as in uniswap and other contract-based exchanges. And it is very reliable.
Of course, we could make it possible to collect fees for the creator. However, it doesn’t make any sense. Since all sources are distributed under a free license, anyone can deploy the same smart contract except that it does not charge a fee. And users will prefer it.
If Satoshi charged his own fee in every Bitcoin transaction, how quickly would the fork appear without it?
My second question is how long will it take for you to get a stable solution into production?
approx. 3-5 months.
The most difficult tasks that need to be implemented for a production-ready solution are the ability to complete the last part of the transaction by a third party and the ability to buy crystals by a person who does not have them.
Yes, this feature is implemented. On the TON / Ethereum contracts you can see the contract parameters
The platform address is the address of the “organizer of the trade”. In the case of a successful withdraw call, the (amount - fee amount) will be sent to the target address and the rest of the funds will be sent to the platform address.
To add the broker reward in case of Bitcoin, all you need is to implement the additional output on the withdraw transaction, which sends the reward to the broker Bitcoin address.
Good afternoon, thank you for being involved in the process. We are so sorry for late response.
Answering the first question about the broker’s commission, I would like to say about a number of points.
To begin with, I note that the main idea of creating a service was open distribution and maximum decentralization. We deliberately did not add exchange features to contracts such as order books or ratings, simply because the technology itself requires the absence of any third parties, minimizing the cost of interacting with contracts and transparency in execution. The technology does not imply additional functions such as finding a deal partner and so on, and in our case, all the staff to help users find deal partners is carried out on the side of the final service. In general, the implementation of contracts directly is aimed at ensuring that everyone can create their own services with their own functions, features, etc. Isn’t that what decentralization is all about? From our point of view, ideologically, any extra features in addition to the main technology are implemented and lie on the shoulders of those who will implement it into their ready-made products.
If we deviate a little from our ideology and hit slightly into the technique, there are the following points:
Atomic swap, as I already said, is a technology that does not imply third parties. The very architecture of the technology contradicts the charging of any additional payment in addition to transaction fees and a certain number of tokens to support the execution of the contract.
From a technological point of view, the implementation of such a commission in the “when you take - pay the commission” format is extremely difficult to implement, if at all realizable, within the BTC framework. If we cannot make a polymorphic model for all currencies, it turns out that someone must always pay. Or you need to look for some other ways, the specification of which is a separate task. In fact, in any case, a person buying BTC will have additional profit relative to his opponent, since the exchange of TON in BTC can only pay to the broker with TON, and the exchange of TON - ETH can be paid by both parties.
Commissions of networks are already high enough. If you look a little into the future, paying additional commissions will force people to either make a fork or simply not use the service at all, since an atomic swap without a broker’s commission is often more expensive than a regular centralized exchange exchange, where there are practically no commissions for transfers other than brokerage. Plus, the translation of the broker fee itself is also an expense that someone should incur.
On the other hand, the implementation of this requirement is literally 4-5 lines of code for each of the networks which support fee stuff, provided that a clear criterion of functionality is defined, for example
at what moment the money is sent to the broker’s account
who pays the commission for this transfer
whether a commission is charged if the transaction did not take place
In any case, the architecture and implementation of our solution more than allows us to realize the broker’s commission. The question is solely about necessity, ideology and usability.
Answering the question about the production-ready solution. We are still working on the service, at the moment the design mentioned in the presentation is being implemented, automated tests are being added, and so on. The bottleneck, in our understanding, of any financial technology is security, therefore it is important to conduct a correct audit of contracts and their mandatory formal verification, which will take the most time. We estimate the work before the stable release as 2-3 months of work. We plan to carry out the first tests in combat networks not earlier than in 2-3 weeks.
There was mistake with time period. At the forum submission period is 31 August 2020 - 20 September 2020. For me it means time period 3 weeks, 21 days. It was clearly for me that finish at the end of Sunday… But at Sunday I saw that contest’s contract already moved to the next stage and I couldn’t submit my proposal, because the end was 1 day before, at Saturday. So I publish work only at the forum, because I did it for FreeTon.
От имени своей команды хочу высказаться по поводу ситуации с @nailkhaf.
Я сам лично чуть не наступил на эти грабли – планировал подавать заявку 20-го числа. И спасла только паранойя «так конкурс до 20-го включительно или нет?». Если как минимум 2 человека ошиблись, это, вероятно, не случайность. Но я здесь не для поиска виновных.
Ознакомившись с работой @nailkhaf, могу сказать, что он в одиночку сделал довольно много. Вклад в общее дело внесён существенный, и этот вклад не может остаться без благодарности сообщества.
В связи с этим, наша команда единогласно поддержала идею направить 5% от выигрыша на компенсацию трудозатрат @nailkhaf. Если так поступят и остальные участники конкурса, наберётся на награду 4-го места. Надеюсь, они поддержат эту идею.
Я категорически не согласен с позицией – «это блокчейн, здесь строгие правила, терпите и привыкайте». Блокчейн запишет то, что мы туда запишем, и только от нас зависит, будет это безразличие или человечность.
Since this contest only had 3 submissions, the way to distribute rewards is to simply eliminate prizes 4 - 10 and distribute just the 1st 3 prizes to winners. That would normally be the case; however, in this instance, winners 1 and 2 are tied for 1st place, both with a score of 8.25. As a result. 1st and second prize should be added and divided by 2 to create an average amount of 150k tokens per winner. 3rd place is still 50k.