diff --git a/README.md b/README.md index 93d57e6..8d35d5f 100644 --- a/README.md +++ b/README.md @@ -1,13 +1,15 @@ # SimpleAssets -*document version 1.4.1* +*document version 24 June 2020* ## Scope: -1. [Introduction](#introduction) -2. [Contract actions](#contract-actions) -3. [Data Structures](#data-structures) -4. [EXAMPLES: how to use Simple Assets in smart contracts](#examples-how-to-use-simple-assets-in-smart-contracts) -5. [AuthorReg](#authorreg) -6. [ChangeLog](#change-logs) +1. [Introduction](#introduction) + - [Resources](#resources) + - [Token Types](#token-types) +2. [Contract actions](#contract-actions) +3. [Data Structures](#data-structures) +4. [EXAMPLES: how to use Simple Assets in smart contracts](#examples-how-to-use-simple-assets-in-smart-contracts) +5. [AuthorReg](#authorreg) +6. [ChangeLog](#change-logs) --------------------------- @@ -20,15 +22,6 @@ by [CryptoLions](https://CryptoLions.io) 한국어 번역: https://github.com/CryptoLions/SimpleAssets/blob/master/README_KR.md Español: https://github.com/CryptoLions/SimpleAssets/blob/master/README_ES.md - -web: http://simpleassets.io -Git: https://github.com/CryptoLions/SimpleAssets -Telegram: https://t.me/simpleassets - -Intro & Demos: https://medium.com/@cryptolions/introducing-simple-assets-b4e17caafaa4 - -Events Receiver Example for authors: https://github.com/CryptoLions/SimpleAssets-EventReceiverExample - **WARNING** The minimum dependency on eosio.cdt is now v1.6.3. --------------------------- @@ -46,23 +39,54 @@ PROTON: **simpleassets** Simple Assets is a separate contract which other Dapps can call to manage their digital assets. This serves as an additional guarantee to users of the Dapp that the ownership of assets is managed by a reputable outside authority, and that once created, the Dapp can only manage the asset's mdata. All the ownership-related functionality exists outside the game. -We are in the process of creating a DAC which will curate updates to Simple Assets after deployment to the EOSIO mainnet. - Related: understanding [ownership authority](https://medium.com/@cryptolions/digital-assets-we-need-to-think-about-ownership-authority-a2b0465c17f6). To post information about your NFTs to third-party marketplaces, use the ```authorreg``` action. -Alternatively, dapps can Deploy their own copy of Simple Assets and make modifications to have greater control of functionality. Before deploying, Simple Assets should be modified to prevent anyone from making assets. +Alternatively, dapps can Deploy their own copy of Simple Assets and make modifications to have greater control of functionality, however this may compromise compatibility with wallets and other EOSIO infrastructure. Before deploying, Simple Assets should be modified to prevent anyone from making assets. + +--------------------------- + +## Resources + +web: http://simpleassets.io +Git: https://github.com/CryptoLions/SimpleAssets +Telegram: https://t.me/simpleassets + +Intro & Demos: https://medium.com/@cryptolions/introducing-simple-assets-b4e17caafaa4 + +**(important for developers)** A detailed description of each action parameter can be found here: +https://github.com/CryptoLions/SimpleAssets/blob/master/include/SimpleAssets.hpp + +Events Receiver Example for authors: https://github.com/CryptoLions/SimpleAssets-EventReceiverExample + --------------------------- -## RAM usage +## Token Types + + +### Non-Fungible Tokens (FTs) -The RAM usage for NFTs depends on how much data is stored in the idata and mdata fields. If they both empty, each NFT takes up `276 bytes`. +NFTs are the most common type of digital assets. They are used to express unique tokens. + +#### NFT Structure + +Simple Asset NFTs are divided into **mdata** (data which the author can update at any time, regardless of ownership), and **idata** (data which is set upon the NFT's creation and can never be updated). + +Both are stringified JSONs. For example: `{\"key1\":\"some-string\", \"key2\":5}` + +**Category** is an optional field that lets you group your NFTs for convenience. Category names must be less than or equal to 12 characters (a-z, 1-5). + +**Offer/Claim** versus **Transfer** - If you transfer an NFT, the sender pays for RAM. As an alternative, you can simply offer the NFT, and the user claiming will pay for their RAM. *(Note: we are working toward a feature that allows NFT authors to reserve a lot of RAM which will spare users for paying for transfers.)* + +#### RAM usage + +RAM usage for NFTs depends on how much data is stored in the idata and mdata fields. If they both empty, each NFT takes up `276 bytes`. Each symbol in idata and mdata is +1 byte. ---------------------------- -## Fungible Tokens (FTs) + +### Fungible Tokens (FTs) Dapps which need Fungible tokens should decide between using the standard eosio.token contract, and the Simple Assets contract. Here are the differences: @@ -75,9 +99,10 @@ In Simple Assets, * The table which tracks FTs includes the author's account name, allowing different dapps to have FTs with the same name. (Example: https://bloks.io/contract?tab=Tables&table=accounts&account=simpleassets&scope=bohdanbohdan&limit=100) +*(Note: Fungible Tokens also have **offer/claim** functionality as an alternative to **transfers**. For FTs, the only time the sender would pay for RAM would be if the receiver never before held those FTs. It uses approximately 300 bytes to create the FT table.)* ---------------------------- -## Non-Transferrable Tokens (NTTs) + +### Non-Transferrable Tokens (NTTs) The two most likely use cases for NTTs are @@ -97,7 +122,7 @@ More on NTTs: https://medium.com/@cryptolions/introducing-non-transferable-token A description of each parameter can be found here: 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 ) @@ -123,6 +148,11 @@ authorupdate ( name author, string dappinfo, string fieldtypes, string priority attachf (owner, author, quantity, assetidc) detachf (owner, author, quantity, assetidc) + mdadd (author, data) + mdupdate (id, author, data) + mdremove (id) + mdaddlog (id, author, data) + # -- For Fungible Tokens (FTs) --- createf (author, maximum_supply, authorctrl, data) @@ -149,15 +179,20 @@ authorupdate ( name author, string dappinfo, string fieldtypes, string priority # Data Structures ## Assets -``` +```c++ sasset { uint64_t id; // asset id used for transfer and search; name owner; // asset owner (mutable - by owner!!!); name author; // asset author (game contract, immutable); name category; // asset category, chosen by author, immutable; - string idata; // immutable assets data. Can be stringified JSON or just sha256 string; + string idata; // immutable assets data. Can be stringified JSON (recommended) + // or just sha256 string; string mdata; // mutable assets data, added on creation or asset update by author. Can be - // stringified JSON or just sha256 string; + // stringified JSON (recommended) or just sha256 string; + // using a format other than stringified JSON will not interfere with + // simple asset functionality, but will harm compatibility with third party + // explorers attempting to diplay the asset + sasset[] container; // other NFTs attached to this asset account[] containerf; // FTs attached to this asset } @@ -168,7 +203,7 @@ To help third party asset explorers, we recommend including the following fields ## Offers -``` +```c++ offers { uint64_t assetid; // asset id offered for claim ; name owner; // asset owner; @@ -178,7 +213,7 @@ offers { ``` ## Authors -``` +```c++ authors { name author; // assets author, who will be able to create and update assets; @@ -215,12 +250,12 @@ authors { ``` ## Delegates -``` +```c++ delegates{ uint64_t assetid; // asset id offered for claim; name owner; // asset owner; name delegatedto; // who can claim this asset; - uint64_t cdate; // offer create date; + uint64_t cdate; // offer create date; uint64_t period; // Time in seconds that the asset will be lent. Lender cannot undelegate until // the period expires, however the receiver can transfer back at any time. bool redelegate; // redelegate is allow more redelegate for to account or not. @@ -230,7 +265,7 @@ delegates{ ``` ## Currency Stats (Fungible Token) -``` +```c++ stat { asset supply; // Tokens supply asset max_supply; // Max token supply @@ -242,7 +277,7 @@ stat { ``` ## Account (Fungible Token) -``` +```c++ accounts { uint64_t id; // token id, from stat table name author; // token author @@ -250,7 +285,7 @@ accounts { } ``` -``` +```c++ offerfs { uint64_t id; // id of the offer for claim (increments automatically) name author; // ft author @@ -263,19 +298,23 @@ offerfs { ## NTT -``` +```c++ snttassets { uint64_t id; // NTT id used for claim or burn; name owner; // asset owner (mutable - by owner!!!); name author; // asset author (game contract, immutable); name category; // asset category, chosen by author, immutable; - string idata; // immutable assets data. Can be stringified JSON or just sha256 string; + string idata; // immutable assets data. Can be stringified JSON (recommended) + // or just sha256 string; string mdata; // mutable assets data, added on creation or asset update by author. Can be - // stringified JSON or just sha256 string; + // stringified JSON (recommended) or just sha256 string; + // using a format other than stringified JSON will not interfere with + // simple asset functionality, but will harm compatibility with third party + // explorers attempting to diplay the asset } ``` -``` +```c++ nttoffers { uint64_t id; // id of the offer for claim (increments automatically) name author; // ft author @@ -285,11 +324,21 @@ nttoffers { uint64_t cdate; // offer creation date } ``` - + + +## More Data +```c++ +moredata{ + uint64_t id; // id of the more data + name author; // author of the more data + string data; // more data. recommended format: strigified JSON +} +``` + # EXAMPLES: how to use Simple Assets in smart contracts ## Creating Asset and transfer to owner account ownerowner22: -``` +```c++ name SIMPLEASSETSCONTRACT = "simpleassets"_n; name author = get_self(); @@ -308,7 +357,7 @@ createAsset.send(); ``` ## Creating Asset with requireclaim option for ownerowner22: -``` +```c++ name SIMPLEASSETSCONTRACT = "simpleassets"_n; name author = get_self(); @@ -330,7 +379,7 @@ createAsset.send(); ## Search asset and get assets info 1. Please add in your hpp file info about assets structure -``` +```c++ TABLE account { uint64_t id; name author; @@ -368,7 +417,7 @@ typedef eosio::multi_index< "sassets"_n, sasset, ``` 2. Searching and using info -``` +```c++ name SIMPLEASSETSCONTRACT = "simpleassets"_n; name author = get_self(); name owner = "lioninjungle"_n; @@ -389,7 +438,7 @@ check(mdata["cd"] < now(), "Not ready yet for usage"); ``` ## Update Asset -``` +```c++ name SIMPLEASSETSCONTRACT = "simpleassets"_n; auto mdata = json::parse(idxp->mdata); @@ -409,52 +458,80 @@ saUpdate.send(); ``` ## Transfer one Asset -``` +```c++ name SIMPLEASSETSCONTRACT = "simpleassets"_n; name author = get_self(); name from = "lioninjungle"_n; name to = "ohtigertiger"_n; +uint64_t assetid = 100000000000187; + std::vector assetids; assetids.push_back(assetid); string memo = "Transfer one asset"; -action saUpdate = action( - permission_level{author, "active"_n}, +action saTransfer = action( + permission_level{from, "active"_n}, SIMPLEASSETSCONTRACT, "transfer"_n, std::make_tuple(from, to, assetids, memo) ); -saUpdate.send(); +saTransfer.send(); ``` ## Transfer two Asset to same receiver with same memo -``` +```c++ name SIMPLEASSETSCONTRACT = "simpleassets"_n; name author = get_self(); name from = "lioninjungle"_n; name to = "ohtigertiger"_n; +uint64_t assetid1 = 100000000000187; +uint64_t assetid2 = 100000000000188; + std::vector assetids; assetids.push_back(assetid1); assetids.push_back(assetid2); string memo = "Transfer two asset" -action saUpdate = action( - permission_level{author, "active"_n}, +action saTransfer = action( + permission_level{from, "active"_n}, SIMPLEASSETSCONTRACT, "transfer"_n, std::make_tuple(from, to, assetids, memo) ); -saUpdate.send(); +saTransfer.send(); ``` -## issuef (fungible) issue created token +## Burn Assets +```c++ +name SIMPLEASSETSCONTRACT = "simpleassets"_n; + +name owner = "lioninjungle"_n; +uint64_t assetid1 = 100000000000187; +uint64_t assetid2 = 100000000000188; + +std::vector assetids; +assetids.push_back(assetid1); +assetids.push_back(assetid2); + +string memo = "Transfer two asset" + +action saBurn = action( + permission_level{owner, "active"_n}, + SIMPLEASSETSCONTRACT, + "transfer"_n, + std::make_tuple(owner, assetids, memo) +); +saBurn.send(); ``` + +## issuef (fungible) issue created token +```c++ name SIMPLEASSETSCONTRACT = "simpleassets"_n; asset wood; @@ -475,7 +552,7 @@ saRes1.send(); ``` ## transferf (fungible) by author if authorctrl is enabled -``` +```c++ name SIMPLEASSETSCONTRACT = "simpleassets"_n; asset wood; @@ -488,7 +565,7 @@ name author = get_self(); std::string memo = "best WOOD"; action saRes1 = action( - permission_level{author, "active"_n}, + permission_level{from, "active"_n}, SIMPLEASSETSCONTRACT, "transferf"_n, std::make_tuple(from, to, author, wood, memo) @@ -497,7 +574,7 @@ saRes1.send(); ``` ## burnf (fungible) by author if authorctrl is enabled -``` +```c++ name SIMPLEASSETSCONTRACT = "simpleassets"_n; asset wood; @@ -523,35 +600,22 @@ saRes1.send(); ## authorreg action Authors can register in the authorreg table to communicate with third party asset explorers, wallets, and marketplaces. -``` +```c++ ACTION authorreg( name author, string dappinfo, string fieldtypes, string priorityimg ); ``` @param **author** is author's account who will create assets. @param **dappinfo** is stringified JSON. Recommendations to include: - name - name of the application - company - name of the company - logo - url to image - url - url to the game's websites - info - short description of application - defaultfee - 100x the % fee you'd like to collect from marketplaces. (for 2%, 200) - -@param **fieldtypes** is stringified JSON with key:state values, where key is key from mdata or idata and -state indicates recommended way of displaying the field. Recommended values: - txt - text (default) - url - show as clickable URL - img - link to img file - webgl - link to webgl file - mp3 - link to mp3 file - video - link to video file - hide - do not show - imgb - image as string in binary format - webglb - webgl binary - mp3b - mp3 binary - videob - video binary - timestamp - unix timestamp in seconds - ipfs - ipfs link + name - name of the application + company - name of the company + logo - url to image + url - url to the game's websites + info - short description of application + defaultfee - 100x the % fee you'd like to collect from marketplaces. (for 2%, 200) + +@param **fieldtypes** is stringified JSON with key:state values, where key is key from mdata or idata and +state indicates recommended way of displaying the field. For the latest recommended values, please see [https://github.com/CryptoLions/SimpleAssets/blob/master/include/SimpleAssets.hpp](https://github.com/CryptoLions/SimpleAssets/blob/master/include/SimpleAssets.hpp). @param **priorityimg** is JSON which assosiates an NFT category with the field name from idata or mdata that specifies the main image field for that category of NFTs. This is probably a rare use case and @@ -559,22 +623,29 @@ can be left blank. If you wanted a category of NFTs to have a main image field you'd use "CATEGORY":"otherfieldname". Most likely use case is if you wanted webgls or some other format to be the main image. + ## Cleos examples of authorreg and authorupdate ### authorreg -``` +```bash ./cleos.sh.jungle push action simpleassets authorreg '["ilovekolobok", "{\"name\": \"Kolobok Breeding Game\", \"company\": \"CryptoLions\", \"info\": \"Breed your Kolobok\", \"logo\": \"https://imgs.cryptolions.io/logo_256.png\", \"url\": \"https://kolobok.io\", \"defaultfee\":200}", "{\"bdate\":\"timestamp\"},{\"cd\":\"timestamp\"},{\"img\":\"img\"},{\"st\":\"hide\"},{\"url\":\"url\"}", "{\"kolobok\":\"img\"},{\"*\":\"img\"}" ]' -p ilovekolobok ``` ### authorupdate -``` +```bash ./cleos.sh.jungle push action simpleassets authorupdate '["ilovekolobok", "{\"name\": \"Kolobok Breeding Game\", \"company\": \"CryptoLions\", \"info\": \"Breed your Kolobok\", \"logo\": \"https://imgs.cryptolions.io/logo_256.png\", \"url\": \"https://kolobok.io\", \"defaultfee\":200}", "{\"bdate\":\"timestamp\"},{\"cd\":\"timestamp\"},{\"img\":\"img\"},{\"st\":\"hide\"},{\"url\":\"url\"}", "{\"kolobok\":\"img\"},{\"*\":\"img\"}" ]' -p ilovekolobok ``` ----------------- # Change Logs +## Change Log v1.5.0 + +- Added possibility to include SimpleAssets.hpp into other projects. This helps developers to easily integrate Simple Assets into other contracts. +- Added developers function sa_getnextid to easily get id of newly created assets. +- Added more data functionality (actions mdremove, mdupdate, mdaddlog, mdadd). This offers a Simple Asset table which can store extra or repeating information for NFTs, and keep RAM usage to a minimum. + ## Change Log v1.4.1 - Renamed fields and actions in Author Registration for better larity diff --git a/README_KR.md b/README_KR.md index accab24..131f0d1 100644 --- a/README_KR.md +++ b/README_KR.md @@ -87,6 +87,11 @@ detach (owner, assetidc, [assetid1,..,assetidn]) attachf (owner, author, quantity, assetidc) detachf (owner, author, quantity, assetidc) +mdadd (author, data) +mdupdate (id, author, data) +mdremove (id) +mdaddlog (id, author, data) + # -- For Fungible Tokens --- createf (author, maximum_supply, authorctrl, data) @@ -103,6 +108,13 @@ openf (owner, author, symbol, ram_payer) closef (owner, author, symbol) ``` + # -- For Non-Transferable Tokens (NTTs) --- + +createntt (author, category, owner, idata, mdata, requireсlaim) +updatentt (author, owner, assetid, mdata) +burnntt (owner, [assetid1,..,assetidn], memo) +claimntt (claimer, [assetid1,..,assetidn]) + # 데이터 구조 ## 자산 @@ -194,6 +206,39 @@ sofferf { } ``` +## NTT +``` +snttassets { + uint64_t id; // NTT id used for claim or burn; + name owner; // asset owner (mutable - by owner!!!); + name author; // asset author (game contract, immutable); + name category; // asset category, chosen by author, immutable; + string idata; // immutable assets data. Can be stringified JSON or just sha256 string; + string mdata; // mutable assets data, added on creation or asset update by author. Can be + // stringified JSON or just sha256 string; +} +``` + +``` +nttoffers { + uint64_t id; // id of the offer for claim (increments automatically) + name author; // ft author + name owner; // ft owner + asset quantity; // quantity + name offeredto; // account who can claim the offer + uint64_t cdate; // offer creation date +} +``` + +## More Data +``` +moredata{ + uint64_t id; // id of the more data + name author; // author of the more data + string data; // more data +} +``` + # 예시: 스마트 컨트랙트에서 심플에셋 사용하기 ## 자산을 생성해 소유자 계정 ownerowner22으로 전송하기: diff --git a/README_ZH.md b/README_ZH.md index 28c1105..70ed5b5 100644 --- a/README_ZH.md +++ b/README_ZH.md @@ -127,6 +127,11 @@ detach (owner, assetidc, [assetid1,..,assetidn]) attachf (owner, author, quantity, assetidc) detachf (owner, author, quantity, assetidc) +mdadd (author, data) +mdupdate (id, author, data) +mdremove (id) +mdaddlog (id, author, data) + \# -- For Fungible Tokens (FTs)--- createf (author, maximum_supply, authorctrl, data) @@ -306,7 +311,14 @@ nttoffers { uint64_t cdate; // offer 的创建日期 } ``` - +## More Data +``` +moredata{ + uint64_t id; // id of the more data + name author; // author of the more data + string data; // more data +} +``` --- # 示例:如何在智能合约中使用简单资产 diff --git a/build/SimpleAssets/SimpleAssets.abi b/build/SimpleAssets/SimpleAssets.abi index a39953c..fc1c0c7 100644 --- a/build/SimpleAssets/SimpleAssets.abi +++ b/build/SimpleAssets/SimpleAssets.abi @@ -558,7 +558,7 @@ "type": "uint64" }, { - "name": "spare1", + "name": "mdid", "type": "uint64" }, { @@ -589,6 +589,66 @@ } ] }, + { + "name": "mdadd", + "base": "", + "fields": [ + { + "name": "author", + "type": "name" + }, + { + "name": "data", + "type": "string" + } + ] + }, + { + "name": "mdaddlog", + "base": "", + "fields": [ + { + "name": "id", + "type": "uint64" + }, + { + "name": "author", + "type": "name" + }, + { + "name": "data", + "type": "string" + } + ] + }, + { + "name": "mdremove", + "base": "", + "fields": [ + { + "name": "id", + "type": "uint64" + } + ] + }, + { + "name": "mdupdate", + "base": "", + "fields": [ + { + "name": "id", + "type": "uint64" + }, + { + "name": "author", + "type": "name" + }, + { + "name": "data", + "type": "string" + } + ] + }, { "name": "offer", "base": "", @@ -753,6 +813,24 @@ } ] }, + { + "name": "smoredata", + "base": "", + "fields": [ + { + "name": "id", + "type": "uint64" + }, + { + "name": "author", + "type": "name" + }, + { + "name": "data", + "type": "string" + } + ] + }, { "name": "snttasset", "base": "", @@ -1127,6 +1205,26 @@ "type": "issuef", "ricardian_contract": "---\nspec_version: 0.0.2\ntitle: Issue a fungible token\nsummary: This action issues a fungible token\nicon: https://cryptolions.io/assets/images/sa-icons-256/issuef.png#a40d77b2162d646cd3ce0488dfeab1cdfae8801fcc1d0c6ef1f16f2547b16551\n---\n\nInput parameters:\n`to` - account receiver;\n`author` - fungible token author;\n`quantity` - amount to issue, example \"1000.00 WOOD\";\n`memo` - transfers memo;\n\nTERM\nThis Contract expires at the conclusion of code execution.\nby CryptoLions [ https://cryptolions.io ]" }, + { + "name": "mdadd", + "type": "mdadd", + "ricardian_contract": "---\nspec_version: 0.0.2\ntitle: Create new more date\nsummary: Create new more date\nicon: https://cryptolions.io/assets/images/sa-icons-256/update.png#305b640fe614876c6e6f5fed5ac21f8157c80f7bee39f3db26228986c1fc5e0e\n---\n\nInput parameters:\n`author` - authors account;\n`data` - stringified json with mutable assets data;\n\nTERM\nThis Contract expires at the conclusion of code execution.\nby CryptoLions [ https://cryptolions.io ]" + }, + { + "name": "mdaddlog", + "type": "mdaddlog", + "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/update.png#305b640fe614876c6e6f5fed5ac21f8157c80f7bee39f3db26228986c1fc5e0e\n---\n\nInput parameters:\n`id` - is id of more data;\n`author` - authors account;\n`data` - stringified json with mutable assets data;\n\nTERM\nThis Contract expires at the conclusion of code execution.\nby CryptoLions [ https://cryptolions.io ]" + }, + { + "name": "mdremove", + "type": "mdremove", + "ricardian_contract": "---\nspec_version: 0.0.2\ntitle: Update existing more data\nsummary: Update existing more data\nicon: https://cryptolions.io/assets/images/sa-icons-256/update.png#305b640fe614876c6e6f5fed5ac21f8157c80f7bee39f3db26228986c1fc5e0e\n---\n\nInput parameters:\n`id` - is id of more data;\n\nTERM\nThis Contract expires at the conclusion of code execution.\nby CryptoLions [ https://cryptolions.io ]" + }, + { + "name": "mdupdate", + "type": "mdupdate", + "ricardian_contract": "---\nspec_version: 0.0.2\ntitle: Update existing more data\nsummary: Update existing more data\nicon: https://cryptolions.io/assets/images/sa-icons-256/update.png#305b640fe614876c6e6f5fed5ac21f8157c80f7bee39f3db26228986c1fc5e0e\n---\n\nInput parameters:\n`id` - is id of more data;\n`author` - authors account;\n`data` - stringified json with mutable assets data;\n\nTERM\nThis Contract expires at the conclusion of code execution.\nby CryptoLions [ https://cryptolions.io ]" + }, { "name": "offer", "type": "offer", @@ -1207,6 +1305,13 @@ "key_names": [], "key_types": [] }, + { + "name": "moredata", + "type": "smoredata", + "index_type": "i64", + "key_names": [], + "key_types": [] + }, { "name": "nttoffers", "type": "snttoffer", diff --git a/build/SimpleAssets/SimpleAssets.wasm b/build/SimpleAssets/SimpleAssets.wasm index 21d1b5c..96f1249 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 dae98d6..ec36cf4 100644 --- a/include/SimpleAssets.hpp +++ b/include/SimpleAssets.hpp @@ -1,6 +1,6 @@ /* * @file - * @author (C) 2019 by CryptoLions [ https://CryptoLions.io ] + * @author (C) 2020 by CryptoLions [ https://CryptoLions.io ] * @version 1.1.0 * * @section LICENSE @@ -628,17 +628,119 @@ CONTRACT SimpleAssets : public contract{ ACTION burnntt( name owner, vector< uint64_t >& assetids, string memo ); using burnntt_action = action_wrapper< "burnntt"_n, &SimpleAssets::burnntt >; + /* + * Add "more data" item. + * + * This action adds a "more data" record. More data is an optional, on-chain way + * of storing additional data about NFTs + * + * @param author is a name of data author + * @param data is stringify json + * @return no return value. + */ + ACTION mdadd( name author, string data ); + using mdadd_action = action_wrapper< "mdadd"_n, &SimpleAssets::mdadd >; + + /* + * Create a new more data log entry. This is an internal action to provide id + * + * This action can only be called by SimpleAsset contract. It creates an entry + * in transaction trace, so that that third party explorers can retrieve new ID and other + * information. + * + * @param id is id of more data + * @param author is the more data author. This account is allowed to update the more data. + * @param data is stringified JSON string with more data. It can be changed only by author. + * @return no return value. + */ + ACTION mdaddlog( uint64_t id, name author, string data ); + using mdaddlog_action = action_wrapper< "mdaddlog"_n, &SimpleAssets::mdaddlog >; + + /* + * Update "more data" item. + * + * This action updates "more data" record by id + * + * @param id is id of more data + * @param author is author of data + * @param data is stringify json + * @return no return value. + */ + ACTION mdupdate( uint64_t id, name author, string data ); + using mdupdate_action = action_wrapper< "mdupdate"_n, &SimpleAssets::mdupdate >; + + /* + * Remove "more data" item. + * + * This action removes a "more data" record by id + * + * @param id is id of more data + * @return no return value. + */ + ACTION mdremove( uint64_t id ); + using mdremove_action = action_wrapper< "mdremove"_n, &SimpleAssets::mdremove >; + + public: + enum id_type { asset_id = 0, deferred_id = 1, offer_id = 2, md_id = 3 }; + + /* + * Validate id + * + * Validate is id inside of allowed range ( asset_id = 0, deferred_id = 1, offer_id = 2, md_id = 3 ) + * + * @param type is id number must be ( asset_id = 0, deferred_id = 1, offer_id = 2, md_id = 3 ) + * @return id . + */ + + static void checkid( uint64_t type ) { + + check( false, "Wrong id_type. Value must be asset_id = 0, deferred_id = 1, offer_id = 2, md_id = 3. You entered: " + to_string( type ) ); + } + + /* + * Get next id + * + * sa_getnextid action to get next id, return id for a new asset or new fungible token or more data or deferred transaction id. + * + * @param sa_contract_name is Simple Assets contract name + * @param type is id number must be ( asset_id = 0, deferred_id = 1, offer_id = 2, md_id = 3 ) + * @return id + */ + + static uint64_t sa_getnextid( name sa_contract_name, id_type type ) { + + conf config( sa_contract_name, sa_contract_name.value ); + + global cstate = config.exists() ? config.get() : global{}; + + uint64_t result = 0; + + switch ( type ) { + case asset_id: + result = cstate.lnftid + 1; + break; + case offer_id: + case deferred_id: + result = cstate.defid + 1; + break; + case md_id: + result = cstate.mdid + 1; + break; + default: + checkid( type ); + } + + return result; + } + private: - const uint8_t FEE_PRECISION = 2; - const uint16_t FEE_PRECISION_AMOUNT = 100; - /* * List of authors that need double signatute owner and wet.wax@nftops */ const std::vector waxauthors{ "vgo.wax"_n, "irl.wax"_n, "wax"_n }; - name getPayer(name author, name originalPayer); + name getPayer( name author, name originalPayer ); /* * Check wax authors double signature owner and wet.wax@nftops @@ -648,15 +750,16 @@ CONTRACT SimpleAssets : public contract{ */ void checkwaxauthor( name author ); + /* * Get new asset id. * * This function return new asset id. * - * @param defer is flag for type of transaction true for defered; + * @param type is flag for type of transaction; * @return new asset id */ - uint64_t getid( bool defer = false ); + uint64_t getid( id_type type ); /* * Get fungible token index. @@ -672,11 +775,12 @@ 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" ); - std::string timeToWait(uint64_t time_in_seconds); + std::string timeToWait( uint64_t time_in_seconds ); template void sendEvent( name author, name rampayer, name seaction, const tuple &tup ); + public: /* * Authors table. Can be used by asset markets, asset explorers, or wallets for correct asset * data presentation. @@ -858,7 +962,7 @@ CONTRACT SimpleAssets : public contract{ > nttoffers; /* - * Delegates table keeps records about borrowed assets.Scope: self + * Delegates table keeps records about borrowed assets. Scope: self */ TABLE sdelegate { uint64_t assetid; @@ -884,6 +988,26 @@ CONTRACT SimpleAssets : public contract{ eosio::indexed_by< "delegatedto"_n, eosio::const_mem_fun< sdelegate, uint64_t, &sdelegate::by_delegatedto > > > delegates; + /* + * More data table where assets can store additional info to save RAM. Scope: self + */ + TABLE smoredata{ + uint64_t id; + name author; + string data; + + auto primary_key() const { + return id; + } + + uint64_t by_author() const { + return author.value; + } + }; + typedef eosio::multi_index< "moredata"_n, smoredata , + eosio::indexed_by< "author"_n, eosio::const_mem_fun< smoredata, uint64_t, &smoredata::by_author > > + > moredata; + /* * global singelton table, used for assetid building. Scope: self */ @@ -891,14 +1015,13 @@ CONTRACT SimpleAssets : public contract{ global() {} uint64_t lnftid = 100000000000000; uint64_t defid = 1000000; - uint64_t spare1 = 0; + uint64_t mdid = 100000000; uint64_t spare2 = 0; - EOSLIB_SERIALIZE( global, ( lnftid )( defid )( spare1 )( spare2 ) ) + EOSLIB_SERIALIZE( global, ( lnftid )( defid )( mdid )( spare2 ) ) }; typedef eosio::singleton< "global"_n, global > conf; /// singleton - global _cstate; /// global state /* * Helps external contracts parse actions and tables correctly (Usefull for decentralized exchanges, @@ -912,4 +1035,8 @@ CONTRACT SimpleAssets : public contract{ string version; }; typedef singleton< "tokenconfigs"_n, tokenconfigs > Configs; + + private: + moredata moredatat = { _self, _self.value }; + global _cstate; /// global state }; diff --git a/ricardian/SimpleAssets.contracts.md b/ricardian/SimpleAssets.contracts.md index 68c95d8..1381bbc 100644 --- a/ricardian/SimpleAssets.contracts.md +++ b/ricardian/SimpleAssets.contracts.md @@ -662,3 +662,72 @@ TERM This Contract expires at the conclusion of code execution. by CryptoLions [ https://cryptolions.io ] +

mdadd

+ +--- +spec_version: 0.0.2 +title: Create new more date +summary: Create new more date +icon: https://cryptolions.io/assets/images/sa-icons-256/update.png#305b640fe614876c6e6f5fed5ac21f8157c80f7bee39f3db26228986c1fc5e0e +--- + +Input parameters: +`author` - authors account; +`data` - stringified json with mutable assets data; + +TERM +This Contract expires at the conclusion of code execution. +by CryptoLions [ https://cryptolions.io ] + +

mdaddlog

+ +--- +spec_version: 0.0.2 +title: Internal action used for creating log +summary: Internal action used for creating log +icon: https://cryptolions.io/assets/images/sa-icons-256/update.png#305b640fe614876c6e6f5fed5ac21f8157c80f7bee39f3db26228986c1fc5e0e +--- + +Input parameters: +`id` - is id of more data; +`author` - authors account; +`data` - stringified json with mutable assets data; + +TERM +This Contract expires at the conclusion of code execution. +by CryptoLions [ https://cryptolions.io ] + +

mdupdate

+ +--- +spec_version: 0.0.2 +title: Update existing more data +summary: Update existing more data +icon: https://cryptolions.io/assets/images/sa-icons-256/update.png#305b640fe614876c6e6f5fed5ac21f8157c80f7bee39f3db26228986c1fc5e0e +--- + +Input parameters: +`id` - is id of more data; +`author` - authors account; +`data` - stringified json with mutable assets data; + +TERM +This Contract expires at the conclusion of code execution. +by CryptoLions [ https://cryptolions.io ] + +

mdremove

+ +--- +spec_version: 0.0.2 +title: Update existing more data +summary: Update existing more data +icon: https://cryptolions.io/assets/images/sa-icons-256/update.png#305b640fe614876c6e6f5fed5ac21f8157c80f7bee39f3db26228986c1fc5e0e +--- + +Input parameters: +`id` - is id of more data; + +TERM +This Contract expires at the conclusion of code execution. +by CryptoLions [ https://cryptolions.io ] + diff --git a/ricardian/SimpleAssets.contracts.md.in b/ricardian/SimpleAssets.contracts.md.in index 0cdd7dc..568a0ce 100644 --- a/ricardian/SimpleAssets.contracts.md.in +++ b/ricardian/SimpleAssets.contracts.md.in @@ -662,3 +662,72 @@ TERM This Contract expires at the conclusion of code execution. by CryptoLions [ https://cryptolions.io ] +

mdadd

+ +--- +spec_version: 0.0.2 +title: Create new more date +summary: Create new more date +icon: https://cryptolions.io/assets/images/sa-icons-256/update.png#305b640fe614876c6e6f5fed5ac21f8157c80f7bee39f3db26228986c1fc5e0e +--- + +Input parameters: +`author` - authors account; +`data` - stringified json with mutable assets data; + +TERM +This Contract expires at the conclusion of code execution. +by CryptoLions [ https://cryptolions.io ] + +

mdaddlog

+ +--- +spec_version: 0.0.2 +title: Internal action used for creating log +summary: Internal action used for creating log +icon: https://cryptolions.io/assets/images/sa-icons-256/update.png#305b640fe614876c6e6f5fed5ac21f8157c80f7bee39f3db26228986c1fc5e0e +--- + +Input parameters: +`id` - is id of more data; +`author` - authors account; +`data` - stringified json with mutable assets data; + +TERM +This Contract expires at the conclusion of code execution. +by CryptoLions [ https://cryptolions.io ] + +

mdupdate

+ +--- +spec_version: 0.0.2 +title: Update existing more data +summary: Update existing more data +icon: https://cryptolions.io/assets/images/sa-icons-256/update.png#305b640fe614876c6e6f5fed5ac21f8157c80f7bee39f3db26228986c1fc5e0e +--- + +Input parameters: +`id` - is id of more data; +`author` - authors account; +`data` - stringified json with mutable assets data; + +TERM +This Contract expires at the conclusion of code execution. +by CryptoLions [ https://cryptolions.io ] + +

mdremove

+ +--- +spec_version: 0.0.2 +title: Update existing more data +summary: Update existing more data +icon: https://cryptolions.io/assets/images/sa-icons-256/update.png#305b640fe614876c6e6f5fed5ac21f8157c80f7bee39f3db26228986c1fc5e0e +--- + +Input parameters: +`id` - is id of more data; + +TERM +This Contract expires at the conclusion of code execution. +by CryptoLions [ https://cryptolions.io ] + diff --git a/src/SimpleAssets.cpp b/src/SimpleAssets.cpp index 9d164c5..b747285 100644 --- a/src/SimpleAssets.cpp +++ b/src/SimpleAssets.cpp @@ -90,7 +90,7 @@ ACTION SimpleAssets::create( name author, name category, name owner, string idat require_auth( author ); check( is_account( owner ), "owner account does not exist" ); require_recipient( owner ); - const auto newID = getid(); + const auto newID = getid( asset_id ); name assetOwner = owner; check( !( author.value == owner.value && requireclaim == 1 ), "Can't requireclaim if author == owner." ); @@ -554,7 +554,7 @@ ACTION SimpleAssets::createf( name author, asset maximum_supply, bool authorctrl s.supply.symbol = maximum_supply.symbol; s.max_supply = maximum_supply; s.issuer = author; - s.id = getid(); + s.id = getid( asset_id ); s.authorctrl = authorctrl; s.data = data; }); @@ -664,7 +664,7 @@ ACTION SimpleAssets::offerf( name owner, name newowner, name author, asset quant } offert.emplace( owner, [&]( auto& s ) { - s.id = getid( true ); + s.id = getid( offer_id ); s.author = author; s.quantity = quantity; s.offeredto = newowner; @@ -764,24 +764,33 @@ ACTION SimpleAssets::closef( name owner, name author, const symbol& symbol ) { acnts.erase( it ); } -uint64_t SimpleAssets::getid( bool defer ) { +uint64_t SimpleAssets::getid( id_type type ) { + + conf config(get_self(), get_self().value); - // getid private action Increment, save and return id for a new asset or new fungible token. - conf config( _self, _self.value ); _cstate = config.exists() ? config.get() : global{}; - uint64_t resid; - if ( defer ) { - _cstate.defid++; - resid = _cstate.defid; - } - else { - _cstate.lnftid++; - resid = _cstate.lnftid; + uint64_t result = 0; + + switch ( type ) { + case asset_id: + result = ++_cstate.lnftid; + break; + case offer_id: + case deferred_id: + result = ++_cstate.defid; + break; + case md_id: + if ( _cstate.mdid < 100000000 ) + _cstate.mdid = 100000000; + result = ++_cstate.mdid; + break; + default: + checkid( type ); } config.set( _cstate, _self ); - return resid; + return result; } uint64_t SimpleAssets::getFTIndex( name author, symbol symbol ) { @@ -902,7 +911,7 @@ ACTION SimpleAssets::createntt( name author, name category, name owner, string i require_auth( author ); check( is_account( owner ), "owner account " + owner.to_string() + " does not exist" ); require_recipient( owner ); - const auto newID = getid(); + const auto newID = getid( asset_id ); name assetOwner = owner; check( !( author.value == owner.value && requireclaim == 1 ), "Can't requireclaim if author == owner." ); @@ -970,7 +979,7 @@ ACTION SimpleAssets::claimntt( name claimer, vector& assetids ) { auto itr = assets_owner.require_find( assetids[i], string("Cannot find asset id: " + to_string( assetids[i] ) + " that you're attempting to claim at scope: " + itrc->owner.to_string()).c_str() ); - 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() ); + 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_claimer.emplace( claimer, [&](auto& s) { s.id = itr->id; @@ -1023,13 +1032,56 @@ ACTION SimpleAssets::burnntt( name owner, vector& assetids, string mem //} } +ACTION SimpleAssets::mdadd( name author, string data ) { + require_auth( author ); + require_recipient( author ); + + const auto newID = getid( md_id ); + + moredatat.emplace( author, [&](auto& s) { + s.id = newID; + s.author = author; + s.data = data; + }); + + SEND_INLINE_ACTION(*this, mdaddlog, { {_self, "active"_n} }, { newID, author, data }); +} + +ACTION SimpleAssets::mdupdate( uint64_t id, name author, string data ) { + require_auth( author ); + require_recipient( author ); + + auto itr = moredatat.require_find( id, string( "More data item with id: " + to_string( id ) + " was not found" ).c_str() ); + + check( itr->author == author, "Only author " + itr->author.to_string() + " can update more data. You entered author " + author.to_string() ); + + moredatat.modify( itr, author, [&](auto& s) { + s.author = author; + s.data = data; + }); +} + +ACTION SimpleAssets::mdremove( uint64_t id ) { + + auto itr = moredatat.require_find( id, string( "More data item with id: " + to_string( id ) + " was not found." ).c_str() ); + + require_auth( itr->author ); + require_recipient( itr->author ); + + moredatat.erase( itr ); +} + +ACTION SimpleAssets::mdaddlog( uint64_t id, name author, string data ) { + require_auth(get_self()); +} + template void SimpleAssets::sendEvent( name author, name rampayer, name seaction, const tuple &adata ) { transaction sevent{}; sevent.actions.emplace_back( permission_level{ _self, "active"_n }, author, seaction, adata ); sevent.delay_sec = 0; - sevent.send( getid(true), rampayer ); + sevent.send( getid( deferred_id ), rampayer ); } asset SimpleAssets::get_supply( name token_contract_account, name author, symbol_code sym_code ) { @@ -1060,7 +1112,8 @@ EOSIO_DISPATCH( SimpleAssets, ( create )( createlog )( transfer )( burn )( updat ( createf )( updatef )( issuef )( transferf )( burnf ) ( offerf )( cancelofferf )( claimf ) ( attachf )( detachf )( openf )( closef ) -( updatever ) ( createntt ) ( burnntt ) ( createnttlog ) ( claimntt ) ( updatentt ) ( changeauthor ) ) +( updatever )( createntt )( burnntt )( createnttlog )( claimntt )( updatentt )( changeauthor ) +( mdadd )( mdupdate )( mdremove )( mdaddlog ) ) //============================================================================================================