Skip to content

Latest commit

 

History

History

web_p2p_exchange

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Simple Everscale web application

Audience

Novice blockchain developers, who prefer to learn by doing.

Content Table

What are we building?

We will build an application in which one person can sell crystals to another. Fiat funds are transferred outside the blockchain and all disputed cases are resolved by a moderator.

Setup

$ git clone git@github.com:tonlabs/sdk-samples.git
$ cd sdk-samples/demo/web_p2p_exchange
$ npm i

Run tests to check integrity

Prerequisites:

Evernode SE installed and listening on 127.0.0.1:80

If you are running Evernode SE on a custom IP or port, please change the TON_SERVER_ADDRESS variable in /src/config.js accordingly.

npm test

If test passes you can go directly to the Run the App section, else check Troubleshooting section.

Blockchain net.ton.dev and Evernode SE

By default this application is configured to use a standalone blockchain Evernode SE, which helps you quickly debug and test your application.

Evernode SE is twenty times faster than a net.ton.dev blockchain, so it's a real time saver. It's very easy to install Evernode SE if you already have Docker installed

If your choice is Evernode SE, you are ready to run the application

You can run this application on net.ton.dev blockchain, but you must have your own "Giver" smart contract. See next section

Tokens

Each participant of our application must have their own wallet with crystals.

In real life, your wallet is only yours, but in our example, the wallets of all participants are initially filled from another smart contract, called a Giver

How many tokens does this Giver have? It depends if you are using Evernode SE or net.ton.dev

  • Evernode SE.

    There are 1.5 billion test tokens in your Giver contract and everything is ready to run the app

  • net.ton.dev.

    You should have your own 'Giver' smart contract (see src/ton-contracts/giver.package.js) with some crystals on its balance. If so, just fill in the following variables in src/config.js:

     GIVER_ADDRESS = <your_wallet_contract_addres>
     GIVER_PUBLIC_KEY = <your_wallet_contract_public_key>
     GIVER_SECRET_KEY = <your_wallet_contract_secret_key>
    

    Of course you should never do this in a real application. Exposing your keys to the frontend is crazy!

    If you don't have a wallet yet - see Appendix A

Run the App

Our App doesn't need a backend, but needs to serve .html and .js files, so let's start a http server provided by webpack:

$ npm run start

To be both seller and buyer, you need to open http://localhost:4000/ in separate tabs.

Wait for your wallet to be deployed. Now you can place your first offer (of course no more than the balance of your wallet)

Rules

  • To sell crystals, Seller deploys a special "Offer" smart-contract, see src/ton-contracts/Offer.sol
  • The deal is made for the entire offered volume of crystals. There is no partial sale / purchase.
  • Buyers find offers by querying GraphQL by Offer contract hash code.
  • To start a deal, the Buyer must transfer the specified number of crystals to the Offer contract as a security deposit.
  • After transferring the deposit, the buyer must transfer the fiat money off-chain.
  • From the moment of receiving the insurance deposit, it's impossible for the Seller to withdraw crystals. Before this moment, it's possible at any time
  • The Seller, after receiving the off-chain payment, sends a confirmation to the Offer contract, after which the crystals and the security deposit are transferred to the Buyer's account and the contract is deleted

Moderator's key pair was generated in advance, and:

  • The secret key is kept by a person who becomes the moderator
  • The public key has been hardcoded into the Offer contract.
  • The code_hash of the compiled offer contract has been hardcoded into the application code.

Thus anyone can deploy such contract but no one can change it without changing contract code hash.

Sample deal

Step 1. The seller has just placed an offer to sell 50 crystals for $ 85

At this moment the seller can discard this offer at his will.

Unfortunately, there is no way to deploy a contract with an exact amount, and as we can see, the exact amount is slightly less than 50 Crystals.


Step 2. Buyer sees offers


Step 3. Buyer has pressed "Send deposit" button

You can see now the balance of his wallet is decreased to (500 - 2) crystals. Now the buyer has two options:

  • click Discard - to cancel the deal and lose his deposit
  • OR make a $85 transfer out of chain and click SetTransferRequestFlagto emphasize that fact


Step 4. Seller sees that deposit has been paid

Now Seller has two options:

  • If he has not received fiat money within a reasonable period of time, he can click setDiscardFlag. This is a signal to the moderator that the Seller claims to cancel deal.
  • Click Transfer. In this case, the entire balance of the contract (51.96) will be transferred to the Buyer's wallet.


Step 5. Seller has clicked Transfer to send cristals to the Buyer

Buyer's wallet balance has increased to 500 + 50 crystals


To fully understand the workflow and how a moderator can resolve disputes, see the algorithm below.

Algorithm

Conslusion

In the next part we will add a DeBot to make our application immediately available to all Surf users.

Troubleshooting

If you choose to use Evernode SE, then this application requires Evernode SE ver >= 0.25. Run everdev se info to see current version

Appendix A

How to get a wallet with crystals

The easiest way to get Crystals is to install the Surf Mobile App and get 100 tokens to your Surf wallet.

When you have got crystals you need:

  1. To deploy a 'Giver' smart contract (see src/ton-contracts/giver.package.js) with some Crystals on its balance
  2. To fill next variables in src/config.js:
 GIVER_ADDRESS = <your_wallet_contract_addres>
 GIVER_PUBLIC_KEY = <your_wallet_contract_public_key>
 GIVER_SECRET_KEY = <your_wallet_contract_secret_key>

Of course you should never expose your keys in a real application!