Hi all!
More recently, Waves Labs
We chose the DAO case because
We started with a simple example in
Let's analyze this example, test 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 funding
Bank - a bank distributing tokens
Stage 1. Initialization of balances
In order to receive tokens in the waves test network, you need to contact
The address can be found in the IDE by revealing the account details.
Select Bank 10 WAVES. After we check that they came through the block and transaction explorer:
Now let's distribute tokens from the bank to the rest of the participants. (Notes: All transactions on the waves network are not free, so a minimum positive balance is required for all participants in order to make transactions).
1 WAVES = 100000000 units (wavelets) since amounts can only be integer
0.01 WAVES (Transaction Fee) = 1000000
Bank -> [3 WAVES] -> Alice, via TransferTransaction (Type: 4).
We check that env.SEED, from which transactions are signed, corresponds to our Bank:
οΏΌ
If you don't have matching seed phrases, just 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.
You can also find out Alice's data through the env.accounts variable. Numbering starts from 0, so Alice is env.accounts[1].
broadcast(transfer({recipient:address(env.accounts[1]), amount: 300000000, fee: 1000000}))
The result can also be observed in the browser, a link to it will be returned to us immediately after execution
We make sure that Alice's balance is replenished with 3 WAVES, and 10 - 3 - 0.01 = 0.699 remain on the bank's balance.
We send Boob and Cooper by 3 WAVES, and Neli, Xena and Mark by 0.2 WAVES in the same way.
(Notes: We made a one character mistake and sent Neli 0.02 WAVES. Be careful!)
broadcast(transfer({recipient:address(env.accounts[4]), amount: 20000000, fee: 1000000}))
After replenishing the balances of all participants, we see:
Stage 2. Creating a dApp account
We have agreed that Alice will be the creator and owner of the decentralized application.
In Accounts, go ahead and set it as SEED and check env.SEED matches Alice.
Let's try to install the simplest possible script (contract) on Alice's account.
Smart contacts in Waves are predicates that prevent or allow some type of outgoing transaction to be executed under certain conditions. In this case, that condition is ALWAYS. The contract code is true. We call deploy().
Fee per setScript transaction 1400000/100000000 = 0.014 WAVES. Alice has 2.986 WAVES left on her balance.
Now let's try to install more complex smart contract logic on Alice's account, described in
Ride4Dapps now includes 2 new annotation types:
- @Callable(i) β takes as parameter i, data about which account called/signed the transaction. It is the result of this function that determines the change in the state of the dApp account. Other accounts can create transactions and execute functions with this annotation and change the state of the dApp account.
- @Verifier(tx) β Transaction verifier with transaction tx parameter. Corresponds to the logic of predicates 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.
Let's do dapper account as a common wallet for all participants.
To check which contract is currently active on the account, you can copy the base64 code of the smart contract in the block explorer and recognize it through the decompiler (
We make sure that the logic of the smart contract matches what we expect.
Alice has 2.972 WAVES left on her balance.
This dApp keeps track of how much each of the participants contributes to the general fund through the mechanism data transaction - DataEntry(currentKey, newAmount), where currentKey is the account that calls the deposit function, and newAmount is the value of the replenished balance.
Boob and Cooper deposit 1 WAVES to the dApp account.
We make a mistake and the transaction does not go through. Since we, despite the fact that we were convinced that we were doing a transaction on behalf of Bob, made a mistake in the index and indicated a Bank account that does not have a smart contract. Here it is worth noting an important point - for unsuccessful attempts to initiate transactions, the commission not removed! Alice has 2.972 WAVES left on her balance. Bob has 3 WAVES.
Bob sent 1 WAVES to 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 0.01 WAVES commission
Alice had 2.972 WAVES on her balance, it became 3.972. A transaction was also registered on Alice's account, but no commission was charged from dApp Account (Alice).
After Cooper also replenished the account, Alice had 4.972 WAVES on her balance.
You can find out who owns how many WAVES in the general wallet in the block explorer in the Data tab.
Cooper changed his mind about leaving the amount of 1 WAVES on the general wallet and decided to withdraw half of the affinities. To do this, it must call the withdraw function.
However, we made a mistake again, because the withdraw function has completely different parameters, a different signature. When you design smart contracts on RIDE4DAPPS, you should pay attention to this point
Cooper has 2.48 WAVES on his balance sheet. Respectively 3 WAVES - 1 - 0.01, and then + 0.5 - 0.01. Accordingly, each call to deposit and withdraw costs 0.01 WAVES. As a result, the entries in the table of dApps owners changed as follows.
Bob also decided to withdraw some money from the general wallet, but he made a mistake and tried to extract 1.5 WAVES.
However, in the smart contract there was a check for such a situation.
Xena is a scammer who tried to withdraw 1 WAVES from the general account.
She also failed.
In the next part, we will consider more complex issues related to the imperfection of Alice dApp Account.
Source: habr.com