Very basic question but I just can't figure out why token transfers on EOS are stored in (expensive) RAM and not just simply in the blockchain?
Please help me understand!
Very basic question but I just can't figure out why token transfers on EOS are stored in (expensive) RAM and not just simply in the blockchain?
Please help me understand!
I don't think the other answers clarify this aspect, so I'll post this as well:
I just can't figure out why token transfers on EOS are stored in (expensive) RAM and not just simply in the blockchain?
Token transfers are stored in the blockchain, not in RAM. The balances for tokens are stored in RAM for the reasons mentioned in other answers, but the transfers are not. If two accounts with already existing balances for a token transfer between each other, there is no RAM needed to pay for the transfers.
The tokens are stored in RAM which is the expensive data storage since smart contracts a.k.a. dApps only have access to info in RAM.
This is the design choice of EOSIO and helps keep up the performance of this blockchain type since RAM is the fastest memory type to access by the computer of the block producers. This allows processing up to 4000 transactions per second on a single thread and this figure is about to be improved with future advancements in the EOSIO code base.
To answer this question, you should look at in the code. Normally, to get index of new data, contract owner should store index key in RAM (faster access), that why "do token transfer" need ram in the first time because it store index of new balance.
void token::add_balance( account_name owner, asset value, account_name ram_payer )
{
accounts to_acnts( _self, owner );
auto to = to_acnts.find( value.symbol.name() );
if( to == to_acnts.end() ) {
// pay ram in first time to add new balance
to_acnts.emplace( ram_payer, [&]( auto& a ){
a.balance = value;
});
} else {
// no required ram to modify balance
to_acnts.modify( to, 0, [&]( auto& a ) {
a.balance += value;
});
}
}
Additional information for somebody.
Look at quota before transfer and after.
quota: 4.075 MiB used: 3.683 KiB
quota: 4.075 MiB used: 3.901 KiB
executed transaction: 3b5b0d6c3aa8e303d062a77b63ba761846cfd172183324da9bd6e94378651afa 136 bytes 547 us
# eosio.token <= eosio.token::transfer {"from":"pdb","to":"pda","quantity":"0.5000 LIN","memo":"Alloha"}
# pdb <= eosio.token::transfer {"from":"pdb","to":"pda","quantity":"0.5000 LIN","memo":"Alloha"}
# pda <= eosio.token::transfer {"from":"pdb","to":"pda","quantity":"0.5000 LIN","memo":"Alloha"}
warning: transaction executed locally, but may not be confirmed by the network yet ]
quota: 4.075 MiB used: 4.042 KiB
quota: 4.075 MiB used: 3.901 KiB
quota: 4.075 MiB used: 4.042 KiB
quota: 4.075 MiB used: 3.901 KiB
executed transaction: b3646e23aa230976c14532ec8641e237be41c9d5c3859ea8cba08c801318d321 136 bytes 521 us
# eosio.token <= eosio.token::transfer {"from":"pdb","to":"pda","quantity":"0.5000 LIN","memo":"Alloha"}
# pdb <= eosio.token::transfer {"from":"pdb","to":"pda","quantity":"0.5000 LIN","memo":"Alloha"}
# pda <= eosio.token::transfer {"from":"pdb","to":"pda","quantity":"0.5000 LIN","memo":"Alloha"}
warning: transaction executed locally, but may not be confirmed by the network yet ]
quota: 4.075 MiB used: 4.042 KiB
quota: 4.075 MiB used: 3.901 KiB
quota: 4.075 MiB used: 4.042 KiB
quota: 4.075 MiB used: 3.901 KiB
executed transaction: 2082898a762f2b54bd85d0408d3898138d31d1b883bdbc348ba72efc873d40dc 136 bytes 691 us
# eosio.token <= eosio.token::transfer {"from":"pdb","to":"pda","quantity":"0.5000 LIN","memo":"Alloha"}
# pdb <= eosio.token::transfer {"from":"pdb","to":"pda","quantity":"0.5000 LIN","memo":"Alloha"}
# pda <= eosio.token::transfer {"from":"pdb","to":"pda","quantity":"0.5000 LIN","memo":"Alloha"}
warning: transaction executed locally, but may not be confirmed by the network yet ]
quota: 4.075 MiB used: 4.042 KiB
quota: 4.075 MiB used: 3.901 KiB
Ram increases only first time. :)