diff --git a/README.md b/README.md index 69a35ec..8d1c714 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ # SimpleAssets -*document version 14 July 2020* +*document version 29 July 2020* ## Scope: 1. [Introduction](#introduction) @@ -126,6 +126,7 @@ https://github.com/CryptoLions/SimpleAssets/blob/master/include/SimpleAssets.hpp ```bash authorreg ( name author, string dappinfo, string fieldtypes, string priorityimg ) authorupdate ( name author, string dappinfo, string fieldtypes, string priorityimg ) +setarampayer ( name author, name category, bool usearam ) # -- For Non-Fungible Tokens (NFTs)--- @@ -336,6 +337,25 @@ moredata{ } ``` +## Author RAM Payer +``` +sarampayer{ + uint64_t id; + name author; + name category; + bool usearam; + uint64_t from_id; + + auto primary_key() const { + return id; + } + + uint64_t by_author() const { + return author.value; + } + }; +``` + # EXAMPLES: how to use Simple Assets in smart contracts ## Creating Asset and transfer to owner account ownerowner22: @@ -641,6 +661,13 @@ to be the main image. ----------------- # Change Logs +## Change Log v1.6.0 +- Added author ram payer option +- Added actions setarampayer, delarampayer +- detach and detachf for author only +- Memo increased to 512 +- Code improvement + ## Change Log v1.5.2 - Re-enabled event notifications for the following actions: saeburn, saeclaim, saetransfer, saechauthor, saecreate. diff --git a/build/SimpleAssets/SimpleAssets.abi b/build/SimpleAssets/SimpleAssets.abi index 2ae1779..73270da 100644 --- a/build/SimpleAssets/SimpleAssets.abi +++ b/build/SimpleAssets/SimpleAssets.abi @@ -515,6 +515,16 @@ } ] }, + { + "name": "delarampayer", + "base": "", + "fields": [ + { + "name": "id", + "type": "uint64" + } + ] + }, { "name": "delegate", "base": "", @@ -917,6 +927,32 @@ } ] }, + { + "name": "sarampayer", + "base": "", + "fields": [ + { + "name": "id", + "type": "uint64" + }, + { + "name": "author", + "type": "name" + }, + { + "name": "category", + "type": "name" + }, + { + "name": "usearam", + "type": "bool" + }, + { + "name": "from_id", + "type": "uint64" + } + ] + }, { "name": "sasset", "base": "", @@ -1011,6 +1047,24 @@ } ] }, + { + "name": "setarampayer", + "base": "", + "fields": [ + { + "name": "author", + "type": "name" + }, + { + "name": "category", + "type": "name" + }, + { + "name": "usearam", + "type": "bool" + } + ] + }, { "name": "smoredata", "base": "", @@ -1393,6 +1447,11 @@ "type": "createnttlog", "ricardian_contract": "---\nspec_version: 0.0.2\ntitle: createlog (internal)\nsummary: createlog (internal) \nicon: https://cryptolions.io/assets/images/sa-icons-256/claimf.png#80086207646470fa9cbaf4638ba0dedec96ea0e84d5059b567adc9e4b8543c30\n---" }, + { + "name": "delarampayer", + "type": "delarampayer", + "ricardian_contract": "---\nspec_version: 0.0.2\ntitle: Action for deleting a ram payer record;\nsummary: Action for deleting a ram payer record;\nicon: https://cryptolions.io/assets/images/sa-icons-256/claim.png#8c3fdf140ea14a3cb9762a0f6ec0f0d73f8c2eeeec3ea2f109f394a9f35f472d\n---\n\nInput parameters:\n`id` - is id of a ram payer record;\n\nTERM\nThis Contract expires at the conclusion of code execution.\nby CryptoLions [ https://cryptolions.io ]" + }, { "name": "delegate", "type": "delegate", @@ -1466,7 +1525,7 @@ { "name": "saeclaim", "type": "saeclaim", - "ricardian_contract": "---\nspec_version: 0.0.2\ntitle: Internal action used for creating log\nsummary: Internal action used for creating log\nicon: https://cryptolions.io/assets/images/sa-icons-256/claim.png#8c3fdf140ea14a3cb9762a0f6ec0f0d73f8c2eeeec3ea2f109f394a9f35f472d\n---\n\nInput parameters:\n`author` - asset's author, who will able to updated asset's mdata;\n`claimer` - account claiming the asset\n`assetids` - array of assetid's to claim\n\nTERM\nThis Contract expires at the conclusion of code execution.\nby CryptoLions [ https://cryptolions.io ]" + "ricardian_contract": "---\nspec_version: 0.0.2\ntitle: Internal action used for creating log\nsummary: Internal action used for creating log\nicon: https://cryptolions.io/assets/images/sa-icons-256/claim.png#8c3fdf140ea14a3cb9762a0f6ec0f0d73f8c2eeeec3ea2f109f394a9f35f472d\n---\n\nInput parameters:\n`author` - asset's author, who will able to updated asset's mdata;\n`claimer` - account claiming the asset;\n`assetids` - array of assetid's to claim;\n\nTERM\nThis Contract expires at the conclusion of code execution.\nby CryptoLions [ https://cryptolions.io ]" }, { "name": "saecreate", @@ -1478,6 +1537,11 @@ "type": "saetransfer", "ricardian_contract": "---\nspec_version: 0.0.2\ntitle: Internal action used for creating log\nsummary: Internal action used for creating log\nicon: https://cryptolions.io/assets/images/sa-icons-256/transfer.png#23227a4901414db5cd0973d1cc5df13f9b82375b21c6315fd3402cb4acd50cbf\n---\n\nThis action is called during transfer in deferred transaction \n\nInput parameters:\n`author` - asset's author;\n`from` - account who sends the asset;\n`to` - account of receiver;\n`assetids` - array of assetid's to transfer;\n`memo` - transfers comment;\n\nTERM\nThis Contract expires at the conclusion of code execution.\nby CryptoLions [ https://cryptolions.io ]" }, + { + "name": "setarampayer", + "type": "setarampayer", + "ricardian_contract": "---\nspec_version: 0.0.2\ntitle: Action for setting a ram payer for author and category.\nsummary: Action for setting a ram payer for author and category.\nicon: https://cryptolions.io/assets/images/sa-icons-256/claim.png#8c3fdf140ea14a3cb9762a0f6ec0f0d73f8c2eeeec3ea2f109f394a9f35f472d\n---\n\nInput parameters:\n`author` - asset's author, who will able to updated asset's mdata;\n`category` - assets category;\n`usearam` - flag for on or off author is a ram payer functionaity;\n\nTERM\nThis Contract expires at the conclusion of code execution.\nby CryptoLions [ https://cryptolions.io ]" + }, { "name": "transfer", "type": "transfer", @@ -1522,6 +1586,13 @@ "key_names": [], "key_types": [] }, + { + "name": "arampayers", + "type": "sarampayer", + "index_type": "i64", + "key_names": [], + "key_types": [] + }, { "name": "authors", "type": "sauthor", diff --git a/build/SimpleAssets/SimpleAssets.wasm b/build/SimpleAssets/SimpleAssets.wasm index d22ab1d..5cd726a 100755 Binary files a/build/SimpleAssets/SimpleAssets.wasm and b/build/SimpleAssets/SimpleAssets.wasm differ diff --git a/include/SimpleAssets.hpp b/include/SimpleAssets.hpp index 20d3eda..7733953 100644 --- a/include/SimpleAssets.hpp +++ b/include/SimpleAssets.hpp @@ -1,7 +1,7 @@ /* * @file * @author (C) 2020 by CryptoLions [ https://CryptoLions.io ] - * @version 1.5.2 + * @version 1.6.0 * * @section LICENSE * @@ -809,6 +809,31 @@ CONTRACT SimpleAssets : public contract{ ACTION saeclaim( name author, name claimer, map< uint64_t, name >& assetids ); using saeclaim_action = action_wrapper< "saeclaim"_n, &SimpleAssets::saeclaim >; + /* + * Action for setting a ram payer for author and category. + * + * This action will add new record (only if regre is no same records for author and category) + * and set from_id to last avalable assetsid. It will works only for new created assets. + * + * @param author is account claiming the asset. + * @param category is asset category. + * @param usearam is flag for using ram + * @return no return value. + */ + ACTION setarampayer( name author, name category, bool usearam ); + using setarampayer_action = action_wrapper< "setarampayer"_n, &SimpleAssets::setarampayer >; + + /* + * Action for deleting a ram payer for author and category. + * + * This action will delete record for arampayer table + * + * @param id is id of arampayer record + * @return no return value. + */ + ACTION delarampayer( uint64_t id ); + using delarampayer_action = action_wrapper< "delarampayer"_n, &SimpleAssets::delarampayer >; + public: enum id_type { asset_id = 0, deferred_id = 1, offer_id = 2, md_id = 3 }; @@ -863,6 +888,9 @@ CONTRACT SimpleAssets : public contract{ } private: + const uint16_t MAX_MEMO_SIZE = 512; + const uint64_t IMPOSSIBLE_ID = 1; + /* * Get new asset id. * @@ -887,7 +915,9 @@ CONTRACT SimpleAssets : public contract{ void sub_balancef( name owner, name author, asset value ); void add_balancef( name owner, name author, asset value, name ram_payer ); void check_empty_vector( vector< uint64_t >& vector_ids, string vector_name = "assetids" ); + void check_memo_size( const string & memo ); std::string timeToWait( uint64_t time_in_seconds ); + name get_payer( name author, name category, uint64_t id ); template void sendEvent( name author, name rampayer, name seaction, const tuple &tup ); @@ -1120,6 +1150,28 @@ CONTRACT SimpleAssets : public contract{ eosio::indexed_by< "author"_n, eosio::const_mem_fun< smoredata, uint64_t, &smoredata::by_author > > > moredata; + /* + * Ram payer table + */ + TABLE sarampayer{ + uint64_t id; + name author; + name category; + bool usearam; + uint64_t from_id; + + auto primary_key() const { + return id; + } + + uint64_t by_author() const { + return author.value; + } + }; + typedef eosio::multi_index< "arampayers"_n, sarampayer, + eosio::indexed_by< "author"_n, eosio::const_mem_fun< sarampayer, uint64_t, &sarampayer::by_author > > + > arampayers; + /* * global singelton table, used for assetid building. Scope: self */ @@ -1132,7 +1184,6 @@ CONTRACT SimpleAssets : public contract{ EOSLIB_SERIALIZE( global, ( lnftid )( defid )( mdid )( spare2 ) ) }; - typedef eosio::singleton< "global"_n, global > conf; /// singleton /* @@ -1149,12 +1200,12 @@ CONTRACT SimpleAssets : public contract{ typedef singleton< "tokenconfigs"_n, tokenconfigs > Configs; private: - moredata moredatat = { _self, _self.value }; - offers offert = { _self, _self.value }; - offerfs offerft = { _self, _self.value }; - delegates delegatet = { _self, _self.value }; - authors authort = { _self, _self.value }; - nttoffers nttoffert = { _self, _self.value }; - + moredata moredatat = { _self, _self.value }; + offers offert = { _self, _self.value }; + offerfs offerft = { _self, _self.value }; + delegates delegatet = { _self, _self.value }; + authors authort = { _self, _self.value }; + nttoffers nttoffert = { _self, _self.value }; + arampayers arampayert = { _self, _self.value }; global _cstate; /// global state }; diff --git a/ricardian/SimpleAssets.contracts.md b/ricardian/SimpleAssets.contracts.md index 6f123f2..7a173de 100644 --- a/ricardian/SimpleAssets.contracts.md +++ b/ricardian/SimpleAssets.contracts.md @@ -855,8 +855,42 @@ icon: https://cryptolions.io/assets/images/sa-icons-256/claim.png#8c3fdf140ea14a Input parameters: `author` - asset's author, who will able to updated asset's mdata; -`claimer` - account claiming the asset -`assetids` - array of assetid's to claim +`claimer` - account claiming the asset; +`assetids` - array of assetid's to claim; + +TERM +This Contract expires at the conclusion of code execution. +by CryptoLions [ https://cryptolions.io ] + +

setarampayer

+ +--- +spec_version: 0.0.2 +title: Action for setting a ram payer for author and category. +summary: Action for setting a ram payer for author and category. +icon: https://cryptolions.io/assets/images/sa-icons-256/claim.png#8c3fdf140ea14a3cb9762a0f6ec0f0d73f8c2eeeec3ea2f109f394a9f35f472d +--- + +Input parameters: +`author` - asset's author, who will able to updated asset's mdata; +`category` - assets category; +`usearam` - flag for on or off author is a ram payer functionaity; + +TERM +This Contract expires at the conclusion of code execution. +by CryptoLions [ https://cryptolions.io ] + +

delarampayer

+ +--- +spec_version: 0.0.2 +title: Action for deleting a ram payer record; +summary: Action for deleting a ram payer record; +icon: https://cryptolions.io/assets/images/sa-icons-256/claim.png#8c3fdf140ea14a3cb9762a0f6ec0f0d73f8c2eeeec3ea2f109f394a9f35f472d +--- + +Input parameters: +`id` - is id of a ram payer record; TERM This Contract expires at the conclusion of code execution. diff --git a/ricardian/SimpleAssets.contracts.md.in b/ricardian/SimpleAssets.contracts.md.in index 419a13c..6e74a71 100644 --- a/ricardian/SimpleAssets.contracts.md.in +++ b/ricardian/SimpleAssets.contracts.md.in @@ -855,8 +855,42 @@ icon: @ICON_BASE_URL@/@CLAIM_ICON_URI@ Input parameters: `author` - asset's author, who will able to updated asset's mdata; -`claimer` - account claiming the asset -`assetids` - array of assetid's to claim +`claimer` - account claiming the asset; +`assetids` - array of assetid's to claim; + +TERM +This Contract expires at the conclusion of code execution. +by CryptoLions [ https://cryptolions.io ] + +

setarampayer

+ +--- +spec_version: 0.0.2 +title: Action for setting a ram payer for author and category. +summary: Action for setting a ram payer for author and category. +icon: @ICON_BASE_URL@/@CLAIM_ICON_URI@ +--- + +Input parameters: +`author` - asset's author, who will able to updated asset's mdata; +`category` - assets category; +`usearam` - flag for on or off author is a ram payer functionaity; + +TERM +This Contract expires at the conclusion of code execution. +by CryptoLions [ https://cryptolions.io ] + +

delarampayer

+ +--- +spec_version: 0.0.2 +title: Action for deleting a ram payer record; +summary: Action for deleting a ram payer record; +icon: @ICON_BASE_URL@/@CLAIM_ICON_URI@ +--- + +Input parameters: +`id` - is id of a ram payer record; TERM This Contract expires at the conclusion of code execution. diff --git a/src/SimpleAssets.cpp b/src/SimpleAssets.cpp index 937f9e5..9b14e51 100644 --- a/src/SimpleAssets.cpp +++ b/src/SimpleAssets.cpp @@ -23,9 +23,19 @@ ACTION SimpleAssets::changeauthor( name author, name newauthor, name owner, vect check( offert.find( assetids[i] ) == offert.end(), "At least one of the assets is already offered for claim. Asset id:" + to_string( assetids[i] ) ); check( delegatet.find( assetids[i] ) == delegatet.end(), "At least one of the assets is delegated and cannot be offered. Asset id: " + to_string( assetids[i] ) ); - check( itr->author == author, "Only author can update asset." ); - check( !( itr->container.size() != 0 ), "Asset has items in non-fungible container" ); - check( !( itr->containerf.size() != 0 ), "Asset has items in funible container" ); + check( itr->author == author, "Only author can update asset. Asset id: " + to_string( assetids[i] ) ); + check( !( itr->container.size() != 0 ), "Asset has items in non-fungible container. Asset id: " + to_string( assetids[i] ) ); + check( !( itr->containerf.size() != 0 ), "Asset has items in funible container. Asset id: " + to_string( assetids[i] ) ); + + auto author_index = arampayert.template get_index< "author"_n >(); + + for (auto itr_ram = author_index.find(newauthor.value); itr_ram != author_index.end(); itr_ram++) { + + check(!(itr_ram->author == newauthor && itr_ram->category == itr->category && itr_ram->usearam), + "Author: " + newauthor.to_string() + " for category: " + itr->category.to_string() + + " has usearam = true. Set usearam = false before changing author. Asset id: " + to_string(assetids[i])); + } + assets_f.modify( itr, author, [&]( auto& a ) { a.author = newauthor; @@ -136,6 +146,14 @@ ACTION SimpleAssets::claim( name claimer, vector& assetids ) { sassets assets_t( _self, claimer.value ); + const auto empty_scope = assets_t.begin() == assets_t.end(); + + if (empty_scope) { + assets_t.emplace(claimer, [&](auto& s) { + s.id = IMPOSSIBLE_ID; + }); + } + map< name, map< uint64_t, name > > uniqauthor; for ( auto i = 0; i < assetids.size(); ++i ) { @@ -149,7 +167,10 @@ ACTION SimpleAssets::claim( name claimer, vector& assetids ) { check( itrc->owner.value == itr->owner.value, "Owner was changed for asset id:" + to_string(assetids[i]) + " .Owner at offers:" + itrc->owner.to_string() + " . Owner at assets: " + itr->owner.to_string() ); - assets_t.emplace( claimer, [&]( auto& s ) { + const auto author_payer = get_payer( itr->author, itr->category, itr->id ); + const auto rampayer = author_payer == ""_n ? claimer : author_payer; + + assets_t.emplace( rampayer, [&]( auto& s ) { s.id = itr->id; s.owner = claimer; s.author = itr->author; @@ -167,6 +188,10 @@ ACTION SimpleAssets::claim( name claimer, vector& assetids ) { offert.erase( itrc ); } + if (empty_scope) { + assets_t.erase(assets_t.find(IMPOSSIBLE_ID)); + } + for ( auto uniqauthorIt = uniqauthor.begin(); uniqauthorIt != uniqauthor.end(); ++uniqauthorIt ) { name keyauthor = move( uniqauthorIt->first ); sendEvent( _self, claimer, "saeclaim"_n, make_tuple( keyauthor, claimer, uniqauthor[keyauthor] ) ); @@ -182,11 +207,16 @@ void SimpleAssets::check_empty_vector( vector& vector_ids, string vect check( !(vector_ids.size() == 0), "Please add values to parameter: " + move(vector_name) ); } +void SimpleAssets::check_memo_size( const string & memo ) { + + check( memo.size() <= MAX_MEMO_SIZE, "Size of memo cannot be bigger then " + to_string( MAX_MEMO_SIZE ) + " .You entered memo size = " + to_string( memo.size() ) ); +} + ACTION SimpleAssets::transfer( name from, name to, vector& assetids, string memo ) { check( from != to, "cannot transfer to yourself" ); check( is_account( to ), "TO account does not exist" ); - check( memo.size() <= 256, "memo has more than 256 bytes" ); + check_memo_size( memo ); check_empty_vector( assetids ); require_recipient( from ); @@ -195,7 +225,15 @@ ACTION SimpleAssets::transfer( name from, name to, vector& assetids, s sassets assets_f( _self, from.value ); sassets assets_t( _self, to.value ); - const auto rampayer = has_auth( to ) ? to : from; + const auto empty_scope = assets_t.begin() == assets_t.end(); + + auto authorized_account = has_auth(to) ? to : from; + + if ( empty_scope ) { + assets_t.emplace(authorized_account, [&](auto& s) { + s.id = IMPOSSIBLE_ID; + }); + } bool isDelegeting = false; @@ -223,11 +261,14 @@ ACTION SimpleAssets::transfer( name from, name to, vector& assetids, s require_auth( from ); } - const auto itr = assets_f.require_find( assetids[i], string("Asset id: " + to_string(assetids[i]) + " cannot be found (check ids?)").c_str() ); + const auto itr = assets_f.require_find( assetids[i], string("Asset id: " + to_string( assetids[i] ) + " cannot be found (check ids?)").c_str() ); check( from.value == itr->owner.value, "Asset id: " + to_string(assetids[i]) + " is not yours to transfer. Owner: " + itr->owner.to_string() ); check( offert.find( assetids[i] ) == offert.end(), "Asset id: " + to_string(assetids[i]) + " offered for a claim and cannot be transferred. Cancel offer?" ); + const auto author_payer = get_payer( itr->author, itr->category, itr->id ); + const auto rampayer = author_payer == ""_n ? authorized_account : author_payer; + assets_t.emplace( rampayer, [&]( auto& s ) { s.id = itr->id; s.owner = to; @@ -237,19 +278,38 @@ ACTION SimpleAssets::transfer( name from, name to, vector& assetids, s s.mdata = itr->mdata; // mutable data s.container = itr->container; s.containerf = itr->containerf; - }); //Events uniqauthor[itr->author].push_back( assetids[i] ); - assets_f.erase(itr); + assets_f.erase( itr ); + } + + if ( empty_scope ) { + assets_t.erase( assets_t.find( IMPOSSIBLE_ID ) ); } //Send Event as deferred for ( auto uniqauthorIt = uniqauthor.begin(); uniqauthorIt != uniqauthor.end(); ++uniqauthorIt ) { name keyauthor = move( uniqauthorIt->first ); - sendEvent( _self, rampayer, "saetransfer"_n, make_tuple( keyauthor, from, to, uniqauthor[keyauthor], memo ) ); + sendEvent( _self, authorized_account, "saetransfer"_n, make_tuple( keyauthor, from, to, uniqauthor[keyauthor], memo ) ); + } +} + +name SimpleAssets::get_payer( name author, name category, uint64_t id ) +{ + name result = ""_n; + auto author_index = arampayert.template get_index< "author"_n >(); + + for ( auto itr_ram = author_index.find( author.value ); itr_ram != author_index.end(); itr_ram++ ) { + if (itr_ram->author == author && itr_ram->category == category + && itr_ram->usearam && id > itr_ram->from_id) { + result = author; + break; + } } + + return result; } ACTION SimpleAssets::saetransfer(name author, name from, name to, vector& assetids, string memo) { @@ -359,9 +419,9 @@ ACTION SimpleAssets::burnlog( name owner, vector& assetids, string mem ACTION SimpleAssets::delegate( name owner, name to, vector& assetids, uint64_t period, bool redelegate, string memo ) { - check( memo.size() <= 64, "Size of memo cannot be bigger 64" ); check( owner != to, "cannot delegate to yourself" ); check_empty_vector( assetids ); + check_memo_size( memo ); require_auth( owner ); require_recipient( owner ); check( is_account( to ), "TO account does not exist" ); @@ -479,12 +539,15 @@ ACTION SimpleAssets::detach( name owner, uint64_t assetidc, vector& as check_empty_vector( assetids ); - require_auth( owner ); require_recipient( owner ); sassets assets_f( _self, owner.value ); const auto ac_ = assets_f.require_find( assetidc, string("assetidc: " + to_string(assetidc) + " cannot be found").c_str() ); + const auto author = ac_->author; + + require_auth( author ); + check( delegatet.find( assetidc ) == delegatet.end(), "Cannot detach asset id: " + to_string( assetidc ) + " is delegated." ); @@ -494,7 +557,7 @@ ACTION SimpleAssets::detach( name owner, uint64_t assetidc, vector& as for ( auto j = 0; j < ac_->container.size(); ++j ) { auto acc = ac_->container[j]; if ( assetids[i] == acc.id ) { - assets_f.emplace( owner, [&]( auto& s ) { + assets_f.emplace( author, [&]( auto& s ) { s.id = acc.id; s.owner = owner; s.author = acc.author; @@ -510,7 +573,7 @@ ACTION SimpleAssets::detach( name owner, uint64_t assetidc, vector& as } } - assets_f.modify( ac_, owner, [&]( auto& a ) { + assets_f.modify( ac_, author, [&]( auto& a ) { a.container = newcontainer; }); } @@ -565,7 +628,7 @@ ACTION SimpleAssets::issuef( name to, name author, asset quantity, string memo ) const auto sym = quantity.symbol; check( sym.is_valid(), "invalid symbol name" ); - check( memo.size() <= 256, "memo has more than 256 bytes" ); + check_memo_size( memo ); stats statstable( _self, author.value ); const auto existing = statstable.require_find( sym.code().raw(), "token with symbol does not exist, create token before issue" ); @@ -602,7 +665,7 @@ ACTION SimpleAssets::transferf( name from, name to, name author, asset quantity, check( quantity.is_valid(), "invalid quantity" ); check( quantity.amount > 0, "must transfer positive quantity" ); check( quantity.symbol == st.supply.symbol, "symbol precision mismatch" ); - check( memo.size() <= 256, "memo has more than 256 bytes" ); + check_memo_size( memo ); auto payer = has_auth( to ) ? to : from; auto checkAuth = from; @@ -626,7 +689,7 @@ ACTION SimpleAssets::offerf( name owner, name newowner, name author, asset quant check( owner != newowner, "cannot offer to yourself" ); const auto sym = quantity.symbol; check( sym.is_valid(), "invalid symbol name" ); - check( memo.size() <= 256, "memo has more than 256 bytes" ); + check_memo_size( memo ); stats statstable( _self, author.value ); const auto existing = statstable.require_find( sym.code().raw(), "token with symbol does not exist" ); @@ -696,7 +759,8 @@ ACTION SimpleAssets::burnf( name from, name author, asset quantity, string memo auto sym = quantity.symbol; check( sym.is_valid(), "invalid symbol name" ); - check( memo.size() <= 256, "memo has more than 256 bytes" ); + check_memo_size( memo ); + stats statstable( _self, author.value ); const auto existing = statstable.require_find( sym.code().raw(), "token with symbol does not exist" ); @@ -788,6 +852,7 @@ void SimpleAssets::attachdeatch( name owner, name author, asset quantity, uint64 stats statstable( _self, author.value ); const auto& st = statstable.get( quantity.symbol.code().raw() ); + require_auth( author ); require_recipient( owner ); check( quantity.is_valid(), "invalid quantity" ); @@ -795,13 +860,6 @@ void SimpleAssets::attachdeatch( name owner, name author, asset quantity, uint64 check( quantity.symbol == st.supply.symbol, "symbol precision mismatch" ); check( st.issuer == author, "Different authors. For asset " + quantity.to_string() + " issuer is " + st.issuer.to_string() + " you entered author = " + author.to_string() ); - if ( attach ) { - require_auth( author ); //attach - } - else { - require_auth( owner ); //deatach - } - const auto itr = assets_f.require_find( assetidc, string("assetid " + to_string( assetidc ) + " cannot be found").c_str() ); check( itr->author == author, "Different authors. For asset id: " + to_string( assetidc ) + " author is " + itr->author.to_string() + " you entered author = " + author.to_string() ); @@ -851,7 +909,7 @@ void SimpleAssets::attachdeatch( name owner, name author, asset quantity, uint64 sub_balancef( owner, author, quantity ); } else { - add_balancef( owner, author, quantity, owner ); + add_balancef( owner, author, quantity, author ); } } @@ -1054,6 +1112,52 @@ ACTION SimpleAssets::mdaddlog( uint64_t id, name author, string data ) { require_auth(get_self()); } +ACTION SimpleAssets::delarampayer( uint64_t id ) +{ + require_auth( get_self() ); + + auto itr = arampayert.require_find( id, + string( "Ram payer id " + to_string( id ) + " does not exist").c_str() ); + + itr = arampayert.erase( itr ); +} + +ACTION SimpleAssets::setarampayer( name author, name category, bool usearam ) +{ + require_auth( author ); + require_recipient( author ); + + auto author_index = arampayert.template get_index< "author"_n >(); + + uint64_t ram_payer_id = 0; + for ( auto itr = author_index.find(author.value); itr != author_index.end(); itr++ ) { + if ( itr->author == author && itr->category == category ) { + ram_payer_id = itr->id; + break; + } + } + + if ( ram_payer_id != 0 ) + { + auto itrrp = arampayert.require_find( ram_payer_id, + string( "Ram payer id " + to_string( ram_payer_id ) + " does not exist" ).c_str() ); + arampayert.modify( itrrp, author, [&]( auto& a ) { + a.usearam = usearam; + a.from_id = sa_getnextid(_self, asset_id) - 1; + }); + } + else + { + arampayert.emplace( author, [&](auto& s) { + s.id = getid( md_id ); + s.author = author; + s.category = category; + s.usearam = usearam; + s.from_id = sa_getnextid( _self, asset_id ) - 1; + }); + } +} + template void SimpleAssets::sendEvent( name author, name rampayer, name seaction, const tuple &adata ) { @@ -1093,7 +1197,7 @@ EOSIO_DISPATCH( SimpleAssets, ( create )( createlog )( transfer )( burn )( updat ( attachf )( detachf )( openf )( closef ) ( updatever )( createntt )( burnntt )( createnttlog )( claimntt )( updatentt )( changeauthor ) ( mdadd )( mdupdate )( mdremove )( mdaddlog ) ( burnlog ) ( burnnttlog ) ( burnflog ) -( saetransfer ) ( saeburn ) ( saechauthor ) ( saecreate ) ( saeclaim ) ) +( saetransfer ) ( saeburn ) ( saechauthor ) ( saecreate ) ( saeclaim ) ( setarampayer ) ( delarampayer ) ) //============================================================================================================