📜 ⬆️ ⬇️

Learn to write Waves smart contracts for RIDE and RIDE4DAPPS. Part 1 (Multiplayer Wallet)


Hello!


More recently, Waves Labs announced a competition for developers dedicated to the release of the RIDE4 Ride4Dapps smart contract language expansion contract expansion network!


We chose the DAO case, as Ventuary plans to develop a dApp with social functions: voting, fundraising, trust management, etc.


We started with a simple example in a Q & A session and in a RIDE IDE , an example with a common wallet .


Let's analyze this example, test the hypotheses and consider some oddities:


Let us have Alice - dApp Owner
Boob and Cooper are partners of Alice, co-founders of Alice-BC DAO
Neli is a business owner who needs financing.
Bank - a bank that distributes tokens


Stage 1. Initialization of balances


In order to receive tokens in the waves test network, you need to contact the faucet and indicate the address to which tokens should be sent.


Address can be found in the IDE, revealing account information.


Select the Bank 10 WAVES. After we check that they are received through the block and transaction browser : the browser


Now let's distribute tokens from the bank to the other participants. (Notes: All transactions on the waves network are not free, so a minimum positive balance is required for all participants to complete transactions).


1 WAVES = 100000000 units (wavelets), since amounts can only be integer
0.01 WAVES (Transaction Fee) = 1,000,000

Bank -> [3 WAVES] -> Alice, via TransferTransaction (Type: 4).


We check that env.SEED, from which transactions are signed, corresponds to our Bank:




If you do not have matching seed phrases, simply switch to it in the Accounts tab and check again.


After that we create, announce and sign a transaction on the transfer of 3 WAVES Alice.
Alice's data can also be obtained through the variable env.accounts. The numbering starts from 0, respectively, Alice is env.accounts [1].



broadcast(transfer({recipient:address(env.accounts[1]), amount: 300000000, fee: 1000000})) 

The result can also be seen in the browser, a link to it will be returned to us immediately after the execution of the transaction .


We are convinced that the balance of Alice is replenished by 3 WAVES, and 10 - 3 - 0.01 = 0.699 are left on the balance of the bank.




We send Boob and Cooper for 3 WAVES, and Neli, Xena and Mark for 0.2 WAVES in the same way.
(Notes: We made a mistake by one sign and sent Neli 0.02 WAVES. Be careful!)


 broadcast(transfer({recipient:address(env.accounts[4]), amount: 20000000, fee: 1000000})) 

After replenishing the balance of all participants, we see:



Stage 2. Create a dApp account


We agreed that the creator and owner of the decentralized application will be Alice.
In the Accounts, go install it as SEED and check env.SEED matches Alice.


Let's try to install on the Alice account the simplest script (contract) possible.
Waves smart contacts are predicates that prohibit or allow any type of outgoing transaction to be executed under certain conditions. In this case, this condition is ALWAYS. The contract code is true. Call deploy ().



Fee for setScript transaction 1400000/100000000 = 0.014 WAVES. Alice has 2.986 WAVES on balance.


Now let's try to install on the Alice account the more complex logic of the smart contract described in the example.


Ride4Dapps now includes 2 new types of annotations:
  1. @Callable (i) - takes as a parameter i, data about which account triggered / signed the transaction. It is the result of this function that determines the change in the status of the dApp account. Other accounts can create transactions and execute functions with this annotation and change the status of the dApp account.
  2. @Verifier (tx) - A transaction verifier with a transaction tx parameter. Corresponds to the predicate logic from RIDE. It is in this expression that you can allow or prohibit further changes in the logic of smart contracts on a dApp account.
    Be careful! The important point is that, by default, the script on the account is not true , but uses the signature comparison and allows only the signature holder to make transactions.
     sigVerify(tx.bodyBytes, tx.proofs[0], tx.senderPk) 


    Without such verification, anyone can make transactions from the account!

Let's make a dApp account as a common wallet for all participants.



To check which contract is currently active on your account, you can copy the base64 code of the smart contract in the block browser and recognize it through the decompiler ( for example )





Make sure the logic of the smart contract matches what we expect.
Alice has 2.972 WAVES on balance.


This dApp keeps a record of how much each participant contributes to the general fund through the data transaction - DataEntry (currentKey, newAmount) mechanism , where currentKey is the account that calls the deposit function, and newAmount is the recharge value.


Boob and Cooper make their deposits on the dApp account for 1 WAVES.



We make a mistake and the transaction fails. Since we, despite the fact that we were convinced that we are doing a transaction on behalf of Bob, made a mistake in the index and indicated a Bank account on which there is no smart contract. Here it is worth noting an important point - for unsuccessful attempts to initiate a transaction, the commission is not removed! Alice has 2.972 WAVES on balance. At Bob 3 WAVES.


Bob sent 1 WAVES to the dApp Account.


 broadcast(invokeScript({dappAddress: address(env.accounts[1]), call:{function:"deposit",args:[]}, payment: [{amount: 100000000, asset:null }]})) 


Bob has 1.99 WAVES left. That is, Bob paid a 0.01 waves commission



Alice had 2.972 WAVES on her balance, it became 3.972. A transaction has also been registered on the Alice account, however, no fee was charged to the dApp Account (Alice).
After Cooper also replenished Alice’s account, the balance was 4.972 WAVES.



You can find out about how many WAVES in the general wallet belong to the block browser in the Data tab.


Cooper decided not to keep the amount of 1 WAVES on the general wallet and decided to withdraw half the affinity. To do this, it must call the function withdraw.



However, we again made a mistake, since the withdraw function has completely different parameters, a different signature. When designing smart contracts for RIDE4DAPPS, pay attention to this point.



Cooper had 2.48 WAVES on balance. Correspondingly, 3 WAVES - 1 - 0.01, and then + 0.5 - 0.01. Each call to deposit and withdraw costs about 0.01 WAVES. As a result, the entries in the dApps table of owners have changed as follows.



Bob also decided to withdraw some amount from the general wallet, but was mistaken and tried to extract 1.5 WAVES.



However, the smart contract included a check for this situation.


Xena - a crook, tried to withdraw 1 WAVES from the general bill.



She also failed.


In the next part, we will look at more difficult issues related to the imperfection of the Alice dApp Account.


')

Source: https://habr.com/ru/post/447790/


All Articles