From 5f1b560e17b0a57cd2b22cce52af9545bac0fe8a Mon Sep 17 00:00:00 2001 From: root Date: Fri, 3 Apr 2020 13:41:11 +0000 Subject: [PATCH] ./commit.sh --- README.md | 99 ++++- README_ZH.md | 476 +++++++++++++------------ build/SimpleAssets/SimpleAssets.abi | 68 ++-- build/SimpleAssets/SimpleAssets.wasm | Bin 212162 -> 218395 bytes external_test/unit_tests.sh | 30 +- include/SimpleAssets.hpp | 102 ++++-- ricardian/SimpleAssets.contracts.md | 35 +- ricardian/SimpleAssets.contracts.md.in | 32 +- src/SimpleAssets.cpp | 43 ++- 9 files changed, 503 insertions(+), 382 deletions(-) diff --git a/README.md b/README.md index e958b37..db57644 100644 --- a/README.md +++ b/README.md @@ -1,12 +1,13 @@ # SimpleAssets - +*document version 1.4.1* ## 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. [ChangeLog](#change-logs) +5. [AuthorReg](AuthorReg) +6. [ChangeLog](#change-logs) --------------------------- @@ -46,7 +47,7 @@ We are in the process of creating a DAC which will curate updates to Simple Asse 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 ```regauthor``` action. +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. @@ -64,27 +65,26 @@ Dapps which need Fungible tokens should decide between using the standard eosio. In Simple Assets, - * Scope is Author instead of Symbol - * Stat table includes also additional data about each FT (see [Currency Stats](#currency-stats-fungible-token) below) - * For transfers you need to use ```tranferf``` action from SA contract. - * If author sets ```authorcontrol``` flag, the author can transfers/burn/etc user's FTs independent of user's consent. - * The table which tracks FTs includes the author's account name, allowing different dapps to have FTs with the +* Scope is Author instead of Symbol +* Stat table includes also additional data about each FT (see [Currency Stats](#currency-stats-fungible-token) below) +* For transfers you need to use ```tranferf``` action from SA contract. +* If author sets ```authorcontrol``` flag, the author can transfers/burn/etc user's FTs independent of user's consent. +* 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) - --------------------------- ## Non-Transferrable Tokens (NTTs) The two most likely use cases for NTTs are - * licenses which can be granted to an account, but not transfered. - * prizes and awards given to a particular account. +* licenses which can be granted to an account, but not transfered. +* prizes and awards given to a particular account. The reasons for using NTTs are: - * the NTTs appearing in third party asset explorers. - * some functionality is handled by Simple Assets. +* the NTTs appearing in third party asset explorers. +* some functionality is handled by Simple Assets. More on NTTs: https://medium.com/@cryptolions/introducing-non-transferable-tokens-ntts-2f1a532bf170 @@ -95,7 +95,7 @@ A description of each parameter can be found here: https://github.com/CryptoLions/SimpleAssets/blob/master/include/SimpleAssets.hpp ``` - regauthor (name author, data, stemplate, string imgpriority) + authorreg (name author, data, stemplate, string imgpriority) authorupdate (author, data, stemplate, string imgpriority) @@ -159,10 +159,10 @@ sasset { account[] containerf; // FTs attached to this asset } ``` -// To help third party asset explorers, we recommend including the following fields in `idata` or `mdata`: -// `name` (text) -// `img` (url to image file) -// and maybe `desc` (text description) +To help third party asset explorers, we recommend including the following fields in `idata` or `mdata`: +`name` (text) +`img` (url to image file) + ## Offers ``` @@ -514,10 +514,73 @@ action saRes1 = action( saRes1.send(); ``` +----------------- +# AuthorReg + +## authorreg action +Authors can register in the authorreg table to communicate with third party asset explorers, wallets, and marketplaces. + +``` +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 + +@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 +can be left blank. If you wanted a category of NFTs to have a main image field other than img, +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 +``` +./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 +``` +./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.4.1 + +- Renamed fields and actions in Author Registration for better larity + regauthor -> authorreg + data -> dappinfo + stemplate -> fieldtypes + imgpriority -> priorityimg +- Added Author Registration documentation to readme + ## Change Log v1.4.0 - re-delegate assets. (lender of assets can allow them to be re-lent) - New parameter `bool redelegate` added in delegate action, which allows asset re-delegation. diff --git a/README_ZH.md b/README_ZH.md index 2fd0124..9c13e6d 100644 --- a/README_ZH.md +++ b/README_ZH.md @@ -1,33 +1,48 @@ -# 中文翻译 简单资产(Simple Assets) ========================= -一款EOSIO区块链上的数字资产标准,适用于不可替代代币(Non-Fungible Tokens,NFTs)、可替代代币(Fungible Tokens,FTs) 和 不可转让代币(Non-Transferable Tokens,NTTs),由CryptoLions开发创建。 - -web: [http://simpleassets.io](http://simpleassets.io/) -Git:  -Telegram:  +## 目录 -简介和演示:https://medium.com/\@cryptolions/introducing-simple-assets-b4e17caafaa4 +1.[简介](#简介) + +2.[合约操作](#合约操作) + +3.[数据结构](数据结构) + +4.[示例:如何在智能合约中使用简单资产](#示例:如何在智能合约中使用简单资产) + +5.[更新日志](#更新日志) + + +--- +# 简介 + +一款EOSIO区块链上的数字资产标准,适用于不可替代代币(Non-Fungible Tokens,NFTs)、可替代代币(Fungible Tokens,FTs) 和 不可转让代币(Non-Transferable Tokens,NTTs),由[CryptoLions](https://CryptoLions.io)开发创建。 +web: [http://simpleassets.io](http://simpleassets.io/) +Git: [https://github.com/CryptoLions/SimpleAssets](https://github.com/CryptoLions/SimpleAssets) +Telegram: [https://t.me/simpleassets](https://t.me/simpleassets) + +简介和演示:https://medium.com/\@cryptolions/introducing-simple-assets-b4e17caafaa4 + 作者的事件接收器示例:https://github.com/CryptoLions/SimpleAssets-EventReceiverExample - + **警告**现在最小基于eosio.cdt v1.6.3版。 --- 通过调用简单资产(Simple Assets)合约来使用Simple Assets。这就像是Dapps的Dapp。 - + 丛林测试网:**`simpleassets`** EOS 主网: **`simpleassets`** WAX 主网: **`simpleassets`** MEETONE 主网: **`smplassets.m`** TELOS 主网: **`simpleassets`** - + 简单资产(Simple Assets)是一个独立的合约,其他Dapps可以直接调用它来管理自己的数字资产。这为Dapp用户提供了额外的保证,即资产的所有权由信誉良好的外部机构管理,并且一旦创建,Dapp只能管理资产的mdata部分。 所有与所有权相关的功能都存在于游戏之外。 - + 我们正在创建一个DAC,它将在部署至EOSIO主网后对简单资产(Simple Assets)策划更新。 [相关信息:理解所有权。](https://medium.com/@cryptolions/digital-assets-we-need-to-think-about-ownership-authority-a2b0465c17f6) @@ -36,39 +51,57 @@ TELOS 主网: **`simpleassets`** 或者,dapps可以自行部署简单资产(Simple Assets)副本并进行修改以更好地控制其功能。 部署前,应修改简单资产(Simple Assets)以防止任何人创建资产。 ------- +--- ## RAM使用情况 -NFT的RAM使用量取决于idata和mdata字段中存储的数据量。 -如果它们都为空,则每个NFT占用276个字节。 +NFT的RAM使用量取决于idata和mdata字段中存储的数据量。 如果它们都为空,则每个NFT占用276个字节。 imdata和mdata中的每个符号都是+1字节。 ----- -## 目录 +--- -1. [合约操作](https://github.com/CryptoLions/SimpleAssets#contract-actions) +## 可替代代币(FTs) -2. [数据结构](https://github.com/CryptoLions/SimpleAssets#data-structures) +需要可替代代币的Dapps应该在使用标准eosio.token合约和“简单资产(Simple Assets)”合约之间做出决定。 区别如下: -3. [示例:如何在智能合约中使用简单资产](https://github.com/CryptoLions/SimpleAssets#examples-how-to-use-simple-assets-in-smart-contracts) +在简单资产中(Simple Assets) -4. [更新日志](https://github.com/CryptoLions/SimpleAssets#change-log-v101) ---- +``` +* Scope is Author instead of Symbol +* Stat table includes also additional data about each FT (see [Currency Stats](#currency-stats-fungible-token) below) +* For transfers you need to use ```tranferf``` action from SA contract. +* If author sets ```authorcontrol``` flag, the author can transfers/burn/etc user's FTs independent of user's consent. +* 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) +``` -合约操作 -======== +--- -可在此处找到每个参数的说明: +## 不可转让代币(NTTs) -[https](https://github.com/CryptoLions/SimpleAssets/blob/master/include/SimpleAssets.hpp)*:*[//github.com/CryptoLions/SimpleAssets/blob/master/include/SimpleAssets.hpp](https://github.com/CryptoLions/SimpleAssets/blob/master/include/SimpleAssets.hpp) +不可转让代币(NTTs)最可能的的两种用例是 +``` +* licenses which can be granted to an account, but not transfered. +* prizes and awards given to a particular account. +``` +使用不可转让代币(NTTs)的原因: +``` +* the NTTs appearing in third party asset explorers. +* some functionality is handled by Simple Assets. ``` -regauthor (name author, data, stemplate, string imgpriority) -authorupdate (author, data, stemplate, string imgpriority) +更多有关NTTs的信息: https://medium.com/@cryptolions/introducing-non-transferable-tokens-ntts-2f1a532bf170 +--- +# 合约操作 + +可在此处找到每个参数的说明:https://github.com/CryptoLions/SimpleAssets/blob/master/include/SimpleAssets.hpp + +``` +regauthor (name author, data, stemplate, string imgpriority) +authorupdate (author, data, stemplate, string imgpriority) \# -- For Non-Fungible Tokens (NTFs) --- @@ -81,9 +114,9 @@ offer (owner, newowner, [assetid1,..,assetidn], memo) canceloffer (owner, [assetid1,..,assetidn]) claim (claimer, [assetid1,..,assetidn]) -delegate (owner, to, [assetid1,..,assetidn], period, memo) +delegate (owner, to, [assetid1,..,assetidn], period, memo) undelegate (owner, from, [assetid1,..,assetidn]) -delegatemore (owner, assetid, period) +delegatemore (owner, assetid, period) attach (owner, assetidc, [assetid1,..,assetidn]) detach (owner, assetidc, [assetid1,..,assetidn]) @@ -108,58 +141,57 @@ 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]) - + createntt (author, category, owner, idata, mdata, requireсlaim) + updatentt (author, owner, assetid, mdata) + burnntt (owner, [assetid1,..,assetidn], memo) + claimntt (claimer, [assetid1,..,assetidn]) ``` + --- -数据结构 -======== +# 数据结构 ## 资产 - ``` sasset { -uint64_t id; // 用于转移和搜索的资产ID -name owner; // 资产所有者(可变更 — 由所有者决定!!!) -name author; // 资产创建者(游戏合约,不可变更) -name category; // 资产类别,由创建者选择,不可变更 -string idata; // 不可变更资产数据。 它可以是字符串化“JSON”或只是字符串“sha256” -string mdata; // 可变资产数据,由创建者在创建或资产更新时添加。 它可以是字符串化“JSON”或只是字符串“sha256” -sasset[] container; // 其它NFTs(可替代和不可替代代币)附加到此资产 -account[] containerf; // FTs(可替代代币)附加到此资产 +uint64_t id; // 用于转移和搜索的资产ID +name owner; // 资产所有者(可变更 — 由所有者决定!!!) +name author; // 资产创建者(游戏合约,不可变更) +name category; // 资产类别,由创建者选择,不可变更 +string idata; // 不可变更资产数据。 它可以是字符串化“JSON”或只是字符串“sha256” +string mdata; // 可变资产数据,由创建者在创建或资产更新时添加。 它可以是字符串化“JSON”或只是字符串“sha256” +sasset[] container; // 其它NFTs(可替代和不可替代代币)附加到此资产 +account[] containerf; // FTs(可替代代币)附加到此资产 } - ``` -//为帮助第三方资产浏览器,我们建议在`idata`或`mdata`请包含以下字段://`name`(文本)//`img` (图像的网页链接) //以及 `desc`(文本描述)的信息。 ----- -## 报价 +//为帮助第三方资产浏览器,我们建议在`idata`或`mdata`请包含以下字段://`name`(文本)//`img` (图像的网页链接) //以及 `desc`(文本描述)的信息。 +--- + +## 报价 ``` offers { -uint64_t assetid; // 提供 claim 的资产ID -name owner; // 资产所有者 -name offeredto; // 可以 claim 此资产的人 -uint64_t cdate; // 创建日期 - -} +uint64_t assetid; // 提供 claim 的资产ID +name owner; // 资产所有者 +name offeredto; // 可以 claim 此资产的人 +uint64_t cdate; // 创建日期 +} ``` + --- + ## 创建者 ``` authors { -name author; // 资产创建者,将能够创建和更新资产 +name author; // 资产创建者,将能够创建和更新资产 -string data; // 创建者的数据(json)将被商城用于更好的展示 - // 建议:形象徽标(logo),信息,网址; +string data; // 创建者的数据(json)将被商城用于更好的展示 + // 建议:形象徽标(logo),信息,网址; -string stemplate; // 数据(json)模式将告诉第三方市场如何显示每个NFT field。 +string stemplate; // 数据(json)模式将告诉第三方市场如何显示每个NFT field。 //key:状态值,其中 key 是 idata 或 mdata 的字段名 //建议格式: //txt | 默认类型 @@ -185,84 +217,95 @@ string imgpriority; //指定NFTs类别的主图像字段 } ``` ----- + +--- + ## 委托 ``` delegates{ -uint64_t assetid; // 提供用于claim的资产ID; -name owner; // 资产所有者; -name delegatedto; // claim该资产者; -uint64_t cdate; // 提供创建日期; -uint64_t period; // 借出资产时间(以秒为单位),借出人不可取消,直到期限到期 +uint64_t assetid; // 提供用于claim的资产ID; +name owner; // 资产所有者; +name delegatedto; // claim该资产者; +uint64_t cdate; // 提供创建日期; +uint64_t period; // 借出资产时间(以秒为单位),借出人不可取消,直到期限到期 // 期限到期,但接收方可随时转回 string memo; // 合约参数备忘录,最长64字节 } ``` + --- + ## 货币统计(可替代代币) ``` stat { -asset supply; // 提供代币 -asset max_supply; // 提供最大量代币 -name issuer; // 可替代代币(Fungible token)创建者 -uint64_t id; // 此代币的唯一ID -bool authorctrl; // 如果 true(1)允许代币创建者(而不仅仅是所有者)进行烧录和传输 -string data; // 字符串化的json。 建议的keys包括: img,name +asset supply; // 提供代币 +asset max_supply; // 提供最大量代币 +name issuer; // 可替代代币(Fungible token)创建者 +uint64_t id; // 此代币的唯一ID +bool authorctrl; // 如果 true(1)允许代币创建者(而不仅仅是所有者)进行烧录和传输 +string data; // 字符串化的json。 建议的keys包括: img,name } ``` + --- + ## 账户(可替代代币) ``` accounts { -uint64_t id; // 代币ID,来自 stat 表 -name author; // 代币创建者 -asset balance; // 代币余额 +uint64_t id; // 代币ID,来自 stat 表 +name author; // 代币创建者 +asset balance; // 代币余额 } ``` + ``` offerfs { -uint64_t id; // claim 此 offer 的ID(自动递增) +uint64_t id; // claim 此 offer 的ID(自动递增) -name author; // 可替代代币(fungible token)创建者 -name owner; // 可替代代币(fungible token)所有者 +name author; // 可替代代币(fungible token)创建者 +name owner; // 可替代代币(fungible token)所有者 asset quantity; // 资产数量 name offeredto; // 可以 claim 此 offer 的帐户 uint64_t cdate; // offer创建日期 } ``` + +--- + ## NTT ``` snttassets { - uint64_t id; // NTT id 用于 claim 或 burn; - name owner; // 资产所有者 (可变 - 基于所有者!!!); - name author; // 资产创建者 (游戏合约, 不可变); - name category; // 资产类别, 有创建者选择, 不可变; - string idata; // 不可变资产数据. 可以是 JSON 字符串化或只是 sha256 字符串; - string mdata; // 可变资产数据, 有创建者创建或更新资产时添加 - // 可以是 JSON 字符串化或只是 sha256 字符串; -} + uint64_t id; // NTT id 用于 claim 或 burn; + name owner; // 资产所有者 (可变 - 基于所有者!!!); + name author; // 资产创建者 (游戏合约, 不可变); + name category; // 资产类别, 有创建者选择, 不可变; + string idata; // 不可变资产数据. 可以是 JSON 字符串化或只是 sha256 字符串; + string mdata; // 可变资产数据, 有创建者创建或更新资产时添加 + // 可以是 JSON 字符串化或只是 sha256 字符串; +} ``` + ``` nttoffers { - uint64_t id; // 用于 claim 的 offer id (自动递增) - name author; // ft 创建者 - name owner; // ft 所有者 - asset quantity; // 数量 - name offeredto; // 可以 claim the offer 的账户 - uint64_t cdate; // offer 的创建日期 + uint64_t id; // 用于 claim 的 offer id (自动递增) + name author; // ft 创建者 + name owner; // ft 所有者 + asset quantity; // 数量 + name offeredto; // 可以 claim the offer 的账户 + uint64_t cdate; // offer 的创建日期 } ``` + --- # 示例:如何在智能合约中使用简单资产 -================================== ## 创建资产并转移到所有者帐户ownerowner22: ``` @@ -287,7 +330,7 @@ std::make_tuple( author, category, owner, idata, mdata, 0 ) createAsset.send(); ``` ---- + ## 使用ownerowner22的requireclaim选项创建资产: ``` name SIMPLEASSETSCONTRACT = "simpleassets"_n; @@ -311,11 +354,9 @@ std::make_tuple( author, category, owner, idata, mdata, 1 ) createAsset.send(); ``` ---- -## 搜索资产并获取资产信息 - -1. 请添加有关资产结构的hpp文件信息。 +## 搜索资产并获取资产信息 +1. 请添加有关资产结构的hpp文件信息。 ``` TABLE account { @@ -362,7 +403,7 @@ eosio::indexed_by\< "author"_n, eosio::const_mem_fun\ sassets; ``` -2. 搜索和使用信息 +2. 搜索和使用信息 ``` name SIMPLEASSETSCONTRACT = "simpleassets"_n; name author = get_self(); @@ -378,7 +419,6 @@ auto mdata = json::parse(idx-\>mdata); // https://github.com/nlohmann/json check(mdata["cd"] \< now(), "Not ready yet for usage"); ``` ---- ## 更新资产 ``` name SIMPLEASSETSCONTRACT = "simpleassets"_n; @@ -397,27 +437,7 @@ std::make_tuple(author, owner, assetid, mdata.dump()) saUpdate.send(); ``` ---- -## 转移一个资产 -``` -name SIMPLEASSETSCONTRACT = "simpleassets"_n; -name author = get_self(); -name from = "lioninjungle"_n; -name to = "ohtigertiger"_n; -std::vector\ assetids; -assetids.push_back(assetid); -string memo = "Transfer one asset"; -action saUpdate = action( -permission_level{author, "active"_n}, - -SIMPLEASSETSCONTRACT, -"transfer"_n, -std::make_tuple(from, to, assetids, memo) -); -saUpdate.send(); -``` ---- ## 将两个资产转移到具有相同备忘录的同一接收器 ``` name SIMPLEASSETSCONTRACT = "simpleassets"_n; @@ -437,190 +457,183 @@ std::make_tuple(from, to, assetids, memo) saUpdate.send(); ``` ---- + ## issuef创建代币问题(可替代代币) ``` name SIMPLEASSETSCONTRACT = "simpleassets"_n; + asset wood; wood.amount = 100; wood.symbol = symbol("WOOD", 0); + name author = get_self(); name to = "lioninjungle"_n; + std::string memo = "WOOD faucet"; action saRes1 = action( -permission_level{author, "active"_n}, - -SIMPLEASSETSCONTRACT, -"issuef"_n, -std::make_tuple(to, author, wood, memo) + permission_level{author, "active"_n}, + SIMPLEASSETSCONTRACT, + "issuef"_n, + std::make_tuple(to, author, wood, memo) ); - saRes1.send(); ``` ---- -## 如果启用了authorctrl,则由创建者转让代币(可替代) + +## 如果启用了authorctrl,则由创建者转让代币(可替代) ``` name SIMPLEASSETSCONTRACT = "simpleassets"_n; asset wood; wood.amount = 20; wood.symbol = symbol("WOOD", 0); + name from = "lioninjungle"_n; name to = get_self(); name author = get_self(); + std::string memo = "best WOOD"; action saRes1 = action( -permission_level{author, "active"_n}, -SIMPLEASSETSCONTRACT, -"transferf"_n, -std::make_tuple(from, to, author, wood, memo) - + permission_level{author, "active"_n}, + SIMPLEASSETSCONTRACT, + "transferf"_n, + std::make_tuple(from, to, author, wood, memo) ); - saRes1.send(); ``` ----- + ## 如果启用了authorctrl,则由创建者烧录代币(可替代) ``` name SIMPLEASSETSCONTRACT = "simpleassets"_n; + asset wood; wood.amount = 20; wood.symbol = symbol("WOOD", 0); + name author = get_self(); name from = "lioninjungle"_n; + std::string memo = "WOOD for oven"; action saRes1 = action( -permission_level{author, "active"_n}, -SIMPLEASSETSCONTRACT, -"burnf"_n, -std::make_tuple(from, author, wood, memo) - + permission_level{author, "active"_n}, + SIMPLEASSETSCONTRACT, + "burnf"_n, + std::make_tuple(from, author, wood, memo) ); - saRes1.send(); - ``` ------- -## 更改日志v1.3.0 -* 使用最新的合约开发工具包(CDT v1.6.3)进行升级(解决了此编译[问题](https://github.com/EOSIO/eosio.cdt/issues/527) +--- +# 更新日志 + +## 更新日志v1.4.0 + +* 重新委托资产。(资产的借出人可以允许他们重新借出) +* 在委托动作中添加了新的参数`bool reelegate`,它允许资产重新委托 +* 在表委托中添加了新的字段`bool reelegate`=>在自部署合约的情况下需要迁移! +* 取消删除操作中的参数,已从中删除。 (在委托人表中可以找到借款人的身份) +* 固定转移空资产数组 +* 错误消息已改进,更加清晰 +* 代码重构 + +--- +## 更新日志v1.3.0 +* 使用最新的合约开发工具包(CDT v1.6.3)进行升级(解决了此编译问题 * 次要代码重构 --- -## 更改日志v1.2.0 +## 更新日志v1.2.0 * 不可转让代币(NTTs)-新tables: snttassets 和 nttoffers * 新 NTT 操作: createntt, createnttlog, claimntt, updatentt, burnntt * 委托更多修复操作(感谢 cc32d9) -* ricardian 合约更新 +ricardian 合约更新 * 为NTT添加外部逻辑测试 --- -## 更改日志v1.1.3 +## 更新日志v1.1.3 * ricardian 合约更新 * 可替代代币报价问题修复 --- -## 更改日志v1.1.2 -* 把 `string imgpriority` 字段添加至 `sauthor` 表以及 `regauthor` 和 `authorupdate` 操作中 +## 更新日志v1.1.2 +* 把`string imgpriority`字段添加至`sauthor`表以及`regauthor`和`authorupdate` 操作中 * 重要信息:自我部署简单资产可能需要迁移 regauthor 表(如果使用) --- -## 更改日志v1.1.1 +## 更新日志v1.1.1 * 优化 claim/transfer/burn 功能 * 备注字段已添加至delegates表(这允许出租者/游戏创建不同类别的借入资产-例如高风险/低风险)。在进行delegate操作时,操作参数的备忘录将存储至此新字段。最多64字节 * 为delegate备忘录添加三个新测试单元 ---- - -## 更改日志v1.1.0 +--- +## 更新日志v1.1.0 * 代码重构 * 修复了为委托和转让的NFTs的分离批量处理功能 * 新合约允许延长借用NFT的委托期限 * 增加了外部(bash)单元测试 ---- -## 更改日志v1.0.1 - -- `createlog` 操作中的新参数 `requireclaim`,用于 `create` 操作历史记录日志。 +## 更新日志v1.0.1 +* `createlog`操作中的新参数`requireclaim`,用于`create`操作历史记录日志 --- -## 更改日志v1.0.0 - -- 阻止所有者向自己提供资产 +## 更新日志v1.0.0 +* 阻止所有者向自己提供资产 --- -## 更改日志v0.4.2 +## 更新日志v0.4.2 +* `saeclaim`事项的格式已更改:由 map 替换asseti数组 -- `saeclaim` 事项的格式已更改:由 map 替换asseti数组 +## 更新日志v0.4.1 +* 添加了`require_recipient`(所有者)来执行`create`操作 --- -## 更改日志v0.4.1 - -- 添加了require_recipient(所有者)来执行`create`操作 - ---- -## 更改日志v0.4.0 +## 更新日志v0.4.0 **轻松找到可替代代币的信息(可替换代币有创建者范围):** - -- FT的 `account` 表中的新字段 `author`。 (更容易找到可替代代币信息) +*FT的`account`表中的新字段`author`(更容易找到可替代代币信息) **更多可替代代币信息** -- 新领域 `data` 中 `currency_stats` 的表-字符串化JSON其中可能包括键 `img`,`name`(建议最好通过市场显示) - -- 新参数`data`在 `createf` 操作中 - -- updatef改变FT的新举措data +* 新领域`data`中`currency_stats`的表-字符串化JSON其中可能包括键 `img`,`name`(建议最好通过市场显示) +* 新参数`data`在`createf`操作中 +* updatef改变FT的新举措data **提供/声明可替代的代币** -- `sofferf` 用于`offer` / `calimFT`的新表 - -- 新的操作`offer`,`cancelofferf` 和 `claimf` - -- 对 `closef` 检查如果没有公开招股(内部) +* `sofferf`用于`offer` / `calim` FT的新表 +* 新的操作`ffer`,`cancelofferf` 和 `claimf` +对`closef`检查如果没有公开招股(内部) **集装资产** -- nft资产结构中用于附加和分离其他NFT或FT的新字段“container”和“containerf” - -- 新操作 `attach`,`detach` - -- 新操作 `attachf`,`detach` +* nft资产结构中用于附加和分离其他NFT或FT的新字段`container`和`containerf` +* 新操作`attach`,`detach` +* 新操作`attachf`,`detach` **杂项** -- 字段重命名 `lasted`- \>` lnftid`,`spare`- \> `defid`(内部用法)在表 `global` 中 - -- 字段 `providedTo` 在 `soffer` 表中重命名为 `offersto` +* 字段重命名`lasted`- >`lnftid`,`spare`- > `defid`(内部用法)在表 `global` 中 +* 字段 `providedTo` 在 `soffer` 表中重命名为 `offersto` --- -## 更改日志v0.3.2 - -- 为操作 `offer` 添加了 `memo` 参数; - -- 为操作 `delegate` 添加了 `memo` 参数; +## 更新日志v0.3.2 +* 为操作`offer`添加了`memo`参数 +* 为操作`delegate`添加了`memo`参数 --- -## 更改日志v0.3.1 - -- 增加了NFT的内部操作 `createlog` 。由创建操作用于记录资产ID,以便第三方资源管理器可以轻松获取新的资产ID和其他信息。 - -- 增加了新的单例表 `tokenconfigs`。它有助于外部合约正确解析操作和表格(对于分散交换,市场和使用多个代币的其他合约有用)。市场,交易所和其他依赖合约将能够使用以下代码查看此信息。 +## 更新日志v0.3.1 +* 增加了NFT的内部操作`createlog`。由创建操作用于记录资产ID,以便第三方资源管理器可以轻松获取新的资产ID和其他信息。 +* 增加了新的单例表`tokenconfigs`。它有助于外部合约正确解析操作和表格(对于分散交换,市场和使用多个代币的其他合约有用)。市场,交易所和其他依赖合约将能够使用以下代码查看此信息。 ``` Configs configs("simpleassets"_n, "simpleassets"_n.value); configs.get("simpleassets"_n); ``` -- 增加了操作 `updatever`。它为第三方钱包,市场等更新了SimpleAstes部署的版本; - -- 事件通知的新示例: +* 增加了操作`updatever`。它为第三方钱包,市场等更新了SimpleAstes部署的版本; +* 事件通知的新示例: https://github.com/CryptoLions/SimpleAssets-EventReceiverExample --- -## 更改日志v0.3.0 - -- 使用延迟事务添加了事件通知。资产作者将收到有关资产创建,转移,索赔或烧录的通知。要收到它,请为您的创建者合约添加以下操作: +## 更新日志v0.3.0 +* 使用延迟事务添加了事件通知。资产作者将收到有关资产创建,转移,索赔或烧录的通知。要收到它,请为您的创建者合约添加以下操作: ``` ACTION saecreate ( name owner, uint64_t assetid ); @@ -632,58 +645,53 @@ ACTION saeclaim ( name account, std::vector\& assetids ); ACTION saeburn ( name account, std::vector\& assetids, std::string memo ); ``` -- `untildate` 参数更改为 `period`(以秒为单位)的操作 `delegate` 和表 `sdelegates` +* `untildate`参数更改为`period`(以秒为单位)的操作`delegate`和表`sdelegates` --- -## 更改日志v0.2.0 - -### 使用eosio.token合约添加了可替代代币(Fungible Token)表和逻辑,但有一些更改 +## 更新日志v0.2.0 +**使用eosio.token合约添加了可替代代币(Fungible Token)表和逻辑,但有一些更改** +* 新的操作和逻辑:`createf`,`issuef`,`transfer`,`burnf`,`openf`,`closef` -- 新的操作和逻辑:`createf`,`issuef`,`transfer`,`burnf`,`openf`,`closef` +* 添加了新表 `stat(supply, max_supply, issuer, id) `和`accounts (id, balance)` -- 添加了新表 `stat(supply, max_supply, issuer, id)` 和 `accounts (id, balance)` 。 +* 统计表的范围(关于可替代代币的信息)已更改为创建者 -- 统计表的范围(关于可替代代币的信息)已更改为创建者 +* `accountstable`的主索引是在`create f`操作上创建的 uniq id 并存储在 stats 表中。 -- `accountstable` 的主索引是在 `create` f操作上创建的 `uniq id` 并存储在 `stats` 表中。 +* 添加`createf`与 parameter 可替代代币操作`authorctrl` 至`stats`表。如果为true(1)允许代币创建者(而不仅仅是所有者)使用burnf和transferf。创建后无法更改! -- 添加 `createf` 与 `parameter` 可替代代币操作 `authorctrl` 至 `stats` 表。如果为true(1)允许代币创建者(而不仅仅是所有者)使用burnf和transferf。创建后无法更改! +* 李嘉图合约已更新 -- 李嘉图合约已更新 - -- 以下有更多用法示例 +* 以下有更多用法示例 --- -## 更改日志v0.1.1 - +## 更新日志v0.1.1 **杂项** +* sdelagate 表结构重命名为 sdelegate(typo) -- sdelagate 表结构重命名为 sdelegate(typo) +* 创建操作参数重命名:requireClaim - > requireclaim -- 创建操作参数重命名:requireClaim - \> requireclaim - -- assetID操作参数在所有要声明的操作中重命名 +* assetID操作参数在所有要声明的操作中重命名 **借入资产** +* sdelegate表 - 添加了新字段:untildate -- sdelegate表 - 添加了新字段:untildate - -- 委托操作添加参数untildate。如果参数输入正确(零或将来),操作会进行简单检查。 +* 委托操作添加参数untildate。如果参数输入正确(零或将来),操作会进行简单检查。 -- undelegate在不公开之前不会工作(这保证了资产贷款的最低期限)。 +* undelegate在不公开之前不会工作(这保证了资产贷款的最低期限)。 -- 如果被委托,允许转移资产(返还)早于截至时间(借款人可以提前返还) +* 如果被委托,允许转移资产(返还)早于截至时间(借款人可以提前返还) **批量处理** -- 声明操作(claim action):assetid参数已更改为assetsids数组。添加了多个声明逻辑。 +* 声明操作(claim action):assetid参数已更改为assetsids数组。添加了多个声明逻辑 -- 报价操作(offer action):assetid参数已更改为assetsids数组。添加了多个提供逻辑。 +* 报价操作(offer action):assetid参数已更改为assetsids数组。添加了多个提供逻辑 -- 取消报价操作(canceloffer action):assetid参数已更改为assetsids数组。添加了多个取消逻辑。 +* 取消报价操作(canceloffer action):assetid参数已更改为assetsids数组。添加了多个取消逻辑 -- 传输操作(transfer action):assetid参数已更改为assetsids数组。添加了多个资产转移逻辑。 +* 传输操作(transfer action):assetid参数已更改为assetsids数组。添加了多个资产转移逻辑。 -- 烧录操作(burn action):assetid参数已更改为assetsids数组。添加了多个刻录逻辑。 +* 烧录操作(burn action):assetid参数已更改为assetsids数组。添加了多个刻录逻辑。 -- 委托/非委托操作(delegate / undelegated action):assetid参数已更改为assetsids数组。添加了多个委托/取消授权逻辑。 +* 委托/非委托操作(delegate / undelegated action):assetid参数已更改为assetsids数组。添加了多个委托/取消授权逻辑。 diff --git a/build/SimpleAssets/SimpleAssets.abi b/build/SimpleAssets/SimpleAssets.abi index a16ce0c..a39953c 100644 --- a/build/SimpleAssets/SimpleAssets.abi +++ b/build/SimpleAssets/SimpleAssets.abi @@ -61,6 +61,28 @@ } ] }, + { + "name": "authorreg", + "base": "", + "fields": [ + { + "name": "author", + "type": "name" + }, + { + "name": "dappinfo", + "type": "string" + }, + { + "name": "fieldtypes", + "type": "string" + }, + { + "name": "priorityimg", + "type": "string" + } + ] + }, { "name": "authorupdate", "base": "", @@ -70,15 +92,15 @@ "type": "name" }, { - "name": "data", + "name": "dappinfo", "type": "string" }, { - "name": "stemplate", + "name": "fieldtypes", "type": "string" }, { - "name": "imgpriority", + "name": "priorityimg", "type": "string" } ] @@ -637,28 +659,6 @@ } ] }, - { - "name": "regauthor", - "base": "", - "fields": [ - { - "name": "author", - "type": "name" - }, - { - "name": "data", - "type": "string" - }, - { - "name": "stemplate", - "type": "string" - }, - { - "name": "imgpriority", - "type": "string" - } - ] - }, { "name": "sasset", "base": "", @@ -706,15 +706,15 @@ "type": "name" }, { - "name": "data", + "name": "dappinfo", "type": "string" }, { - "name": "stemplate", + "name": "fieldtypes", "type": "string" }, { - "name": "imgpriority", + "name": "priorityimg", "type": "string" } ] @@ -1017,10 +1017,15 @@ "type": "attachf", "ricardian_contract": "---\nspec_version: 0.0.2\ntitle: Attach FTs to the specified NFT\nsummary: Attach FTs to the specified NFT \nicon: https://cryptolions.io/assets/images/sa-icons-256/attachf.png#2d190203c6ae474e01cd70963c82a54cb542d95e29174e7572acb8c7653d8a8c\n---\n\nRestrictions. Only the Asset Author can do this. All assets must have the same author. All assets much have the same owner \n\nInput parameters:\n`owner`\t - owner of assets\n`author` - author of the assets\n`assetidc` - id of container NFT\n`quantity` - quantity to attach and token name (for example: \"10 WOOD\", \"42.00 GOLD\")\n\nTERM\nThis Contract expires at the conclusion of code execution.\nby CryptoLions [ https://cryptolions.io ]" }, + { + "name": "authorreg", + "type": "authorreg", + "ricardian_contract": "---\nspec_version: 0.0.2\ntitle: New Author registration\nsummary: New Author registration \nicon: https://cryptolions.io/assets/images/sa-icons-256/regauthor.png#c6a539be8e7dfd1a4c466ba9cabfd13571cd77d5c988c652d2e8f87096f3548e\n---\n\nAction is not mandatory. Markets *may* choose to use information here to display info about the author, and to follow specifications expressed here for displaying asset fields.\n\nInput parameters:\n`author` -\tauthors account who will create assets;\n`dappinfo` - stringified json. Recommendations to include: game, company, logo, url, desc;\n`fieldtypes` - stringified json with key:state values, where key is key from mdata or idata and \n\t\t\t\tstate indicates recommended way of displaying field: \n\t\t\t\turl, img, webgl, mp3, video, hide (ie. don't display), etc.\n`priorityimg` - json with assosiation category with type of image or video \n\t\t\t\ttxt\t- text (default)\n\t\t\t\turl\t- show as clickable URL\n\t\t\t\timg\t- link to img file\n\t\t\t\twebgl\t- link to webgl file\n\t\t\t\tmp3\t- link to mp3 file\n\t\t\t\tvideo\t- link to video file\n\t\t\t\thide\t- do not show\n\t\t\t\timgb \t- image as string in binary format\n\t\t\t\twebglb\t- webgl binary\n\t\t\t\tmp3b \t- mp3 binary\n\t\t\t\tvideob \t- video binary\n\n\nTERM\nThis Contract expires at the conclusion of code execution.\nby CryptoLions [ https://cryptolions.io ]" + }, { "name": "authorupdate", "type": "authorupdate", - "ricardian_contract": "---\nspec_version: 0.0.2\ntitle: Authors info update\nsummary: Authors info update \nicon: https://cryptolions.io/assets/images/sa-icons-256/authorupdate.png#0b11c9c4e41b6ba1b00bd907c671f7ddc9e2f9caf26580f0b2e7c73e02f36ff3\n---\n\nUsed to updated author information, and asset display recommendations created with the regauthor action. This action replaces the fields data and stemplate. To remove author entry, call this action with null strings for data and stemplate.\n\nInput parameters:\n`author` - authors account who will create assets; \n`data` - stringified json. Recommendations to include: game, company, logo, url, desc;\n`stemplate` - stringified json with key:state values, where key is key from mdata or idata and \n\t\t\t\tstate indicates recommended way of displaying field: \n\t\t\t\turl, img, webgl, mp3, video, hide (ie. don't display), etc.\n`imgpriority` - json with assosiation category with type of image or video \n\t\t\t\ttxt\t - default\n\t\t\t\turl\t - show as clickable URL\n\t\t\t\timg\t - link to img file\n\t\t\t\twebgl\t- link to webgl file\n\t\t\t\tmp3\t - link to mp3 file\n\t\t\t\tvideo\t- link to video file\n\t\t\t\thide\t- do not show\n\t\t\t\timgb \t- image as string in binary format\n\t\t\t\twebglb\t- webgl binary\n\t\t\t\tmp3b \t- mp3 binary\n\t\t\t\tvideob \t- video binary\n\nTERM\nThis Contract expires at the conclusion of code execution.\nby CryptoLions [ https://cryptolions.io ]" + "ricardian_contract": "---\nspec_version: 0.0.2\ntitle: Authors info update\nsummary: Authors info update \nicon: https://cryptolions.io/assets/images/sa-icons-256/authorupdate.png#0b11c9c4e41b6ba1b00bd907c671f7ddc9e2f9caf26580f0b2e7c73e02f36ff3\n---\n\nUsed to updated author information, and asset display recommendations created with the authorreg action. This action replaces the fields dappinfo and fieldtypes. To remove author entry, call this action with null strings for dappinfo and fieldtypes.\n\nInput parameters:\n`author` - authors account who will create assets; \n`dappinfo` - stringified json. Recommendations to include: game, company, logo, url, desc;\n`fieldtypes` - stringified json with key:state values, where key is key from mdata or idata and \n\t\t\t\tstate indicates recommended way of displaying field: \n\t\t\t\turl, img, webgl, mp3, video, hide (ie. don't display), etc.\n`priorityimg` - json with assosiation category with type of image or video \n\t\t\t\ttxt\t- text (default)\n\t\t\t\turl\t- show as clickable URL\n\t\t\t\timg\t- link to img file\n\t\t\t\twebgl\t- link to webgl file\n\t\t\t\tmp3\t- link to mp3 file\n\t\t\t\tvideo\t- link to video file\n\t\t\t\thide\t- do not show\n\t\t\t\timgb \t- image as string in binary format\n\t\t\t\twebglb\t- webgl binary\n\t\t\t\tmp3b \t- mp3 binary\n\t\t\t\tvideob \t- video binary\n\nTERM\nThis Contract expires at the conclusion of code execution.\nby CryptoLions [ https://cryptolions.io ]" }, { "name": "burn", @@ -1137,11 +1142,6 @@ "type": "openf", "ricardian_contract": "---\nspec_version: 0.0.2\ntitle: Opens accounts table for fungible token\nsummary: Opens accounts table for specified fungible token\nicon: https://cryptolions.io/assets/images/sa-icons-256/attach.png#0b039adbbe1011a494959963917df4765dbae378004e00911464f865e58ef452\n---\n\nInput parameters:\n`owner` - account who woud like to close table with fungible token;\n`author` - account of fungible token author;\n`symbol` - token symbol, example \"WOOD\", \"ROCK\", \"GOLD\";\n`ram_payer` - account who will pay for ram used for table creation;\n\nTERM\nThis Contract expires at the conclusion of code execution.\nby CryptoLions [ https://cryptolions.io ]" }, - { - "name": "regauthor", - "type": "regauthor", - "ricardian_contract": "---\nspec_version: 0.0.2\ntitle: New Author registration\nsummary: New Author registration \nicon: https://cryptolions.io/assets/images/sa-icons-256/regauthor.png#c6a539be8e7dfd1a4c466ba9cabfd13571cd77d5c988c652d2e8f87096f3548e\n---\n\nAction is not mandatory. Markets *may* choose to use information here to display info about the author, and to follow specifications expressed here for displaying asset fields.\n\nInput parameters:\n`author` -\tauthors account who will create assets;\n`data` - stringified json. Recommendations to include: game, company, logo, url, desc;\n`stemplate` - stringified json with key:state values, where key is key from mdata or idata and \n\t\t\t\tstate indicates recommended way of displaying field: \n\t\t\t\turl, img, webgl, mp3, video, hide (ie. don't display), etc.\n`imgpriority` - json with assosiation category with type of image or video \n\t\t\t\ttxt\t - default\n\t\t\t\turl\t - show as clickable URL\n\t\t\t\timg\t - link to img file\n\t\t\t\twebgl\t- link to webgl file\n\t\t\t\tmp3\t - link to mp3 file\n\t\t\t\tvideo\t- link to video file\n\t\t\t\thide\t- do not show\n\t\t\t\timgb \t- image as string in binary format\n\t\t\t\twebglb\t- webgl binary\n\t\t\t\tmp3b \t- mp3 binary\n\t\t\t\tvideob \t- video binary\n\n\nTERM\nThis Contract expires at the conclusion of code execution.\nby CryptoLions [ https://cryptolions.io ]" - }, { "name": "transfer", "type": "transfer", diff --git a/build/SimpleAssets/SimpleAssets.wasm b/build/SimpleAssets/SimpleAssets.wasm index 3358fd0757129abf7cef0eb1c6752b64aeaaaa4a..21d1b5cac2e4021f4344d6c2ed7ac341dc94c626 100755 GIT binary patch delta 47835 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 x4wj%cK2U@oY0Gv1$${Y#btew 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 + ACTION authorreg( name author, string dappinfo, string fieldtypes, string priorityimg ); + using authorreg_action = action_wrapper< "authorreg"_n, &SimpleAssets::authorreg >; /* * Authors info update. * * This action updates author's information and the asset display recommendations. This action replaces - * the fields data, stemplate, and imgpriority. - * To remove author entry, call this action with null strings for data, stemplate, and imgpriority. + * the fields dappinfo, fieldtypes, and priorityimg. + * To remove author entry, call this action with null strings for dappinfo, fieldtypes, and priorityimg. * - * (See regauthor action for parameter info.) + * (See authorreg action for parameter info.) * * @return no return value. */ - ACTION authorupdate( name author, string data, string stemplate, string imgpriority ); + ACTION authorupdate( name author, string dappinfo, string fieldtypes, string priorityimg ); using authorupdate_action = action_wrapper< "authorupdate"_n, &SimpleAssets::authorupdate >; /* @@ -141,7 +155,8 @@ CONTRACT SimpleAssets : public contract{ * account specified in the owner field to claim the asset using the owner's RAM. * @return no return value. */ - ACTION createlog( name author, name category, name owner, string idata, string mdata, uint64_t assetid, bool requireclaim ); + ACTION createlog( name author, name category, name owner, string idata, string mdata, uint64_t assetid, + bool requireclaim ); using createlog_action = action_wrapper< "createlog"_n, &SimpleAssets::createlog >; /* @@ -246,14 +261,14 @@ CONTRACT SimpleAssets : public contract{ * @param memo is memo for delegate action. * @return no return value. */ - ACTION delegate( name owner, name to, vector< uint64_t >& assetids, uint64_t period, bool redelegate, string memo ); + ACTION delegate( name owner, name to, vector& assetids, uint64_t period, bool redelegate, string memo ); using delegate_action = action_wrapper< "delegate"_n, &SimpleAssets::delegate >; /* * Undelegate assets. * * This action undelegates assets from {{from}} account. Executing action by real owner will return asset - * immediately, and the entry in the delegates table recording the borrowing will be erased. + * immediately, and the entry in the delegates table recording the borrowing will be erased. * * @param owner is the account of real owner of the assets. * @param assetids is array of asset id's to undelegate. @@ -587,6 +602,23 @@ CONTRACT SimpleAssets : public contract{ using burnntt_action = action_wrapper< "burnntt"_n, &SimpleAssets::burnntt >; 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 }; + + /* + * Check wax authors double signature owner and wet.wax@nftops + * + * @param author name of asset to check for second signature. + * @return no return value. + */ + + void checkwaxauthor( name author ); /* * Get new asset id. * @@ -623,9 +655,9 @@ CONTRACT SimpleAssets : public contract{ */ TABLE sauthor { name author; - string data; - string stemplate; - string imgpriority; + string dappinfo; + string fieldtypes; + string priorityimg; auto primary_key() const { return author.value; @@ -680,8 +712,8 @@ CONTRACT SimpleAssets : public contract{ name category; string idata; // immutable data string mdata; // mutable data - vector container; - vector containerf; + vector container; + vector containerf; auto primary_key() const { return id; diff --git a/ricardian/SimpleAssets.contracts.md b/ricardian/SimpleAssets.contracts.md index 60fe334..68c95d8 100644 --- a/ricardian/SimpleAssets.contracts.md +++ b/ricardian/SimpleAssets.contracts.md @@ -1,4 +1,4 @@ -

regauthor

+

authorreg

--- spec_version: 0.0.2 @@ -11,16 +11,16 @@ Action is not mandatory. Markets *may* choose to use information here to displa Input parameters: `author` - authors account who will create assets; -`data` - stringified json. Recommendations to include: game, company, logo, url, desc; -`stemplate` - stringified json with key:state values, where key is key from mdata or idata and +`dappinfo` - stringified json. Recommendations to include: game, company, logo, url, desc; +`fieldtypes` - stringified json with key:state values, where key is key from mdata or idata and state indicates recommended way of displaying field: url, img, webgl, mp3, video, hide (ie. don't display), etc. -`imgpriority` - json with assosiation category with type of image or video - txt - default - url - show as clickable URL - img - link to img file +`priorityimg` - json with assosiation category with type of image or video + txt - text (default) + url - show as clickable URL + img - link to img file webgl - link to webgl file - mp3 - link to mp3 file + mp3 - link to mp3 file video - link to video file hide - do not show imgb - image as string in binary format @@ -42,20 +42,20 @@ summary: Authors info update icon: https://cryptolions.io/assets/images/sa-icons-256/authorupdate.png#0b11c9c4e41b6ba1b00bd907c671f7ddc9e2f9caf26580f0b2e7c73e02f36ff3 --- -Used to updated author information, and asset display recommendations created with the regauthor action. This action replaces the fields data and stemplate. To remove author entry, call this action with null strings for data and stemplate. +Used to updated author information, and asset display recommendations created with the authorreg action. This action replaces the fields dappinfo and fieldtypes. To remove author entry, call this action with null strings for dappinfo and fieldtypes. Input parameters: `author` - authors account who will create assets; -`data` - stringified json. Recommendations to include: game, company, logo, url, desc; -`stemplate` - stringified json with key:state values, where key is key from mdata or idata and +`dappinfo` - stringified json. Recommendations to include: game, company, logo, url, desc; +`fieldtypes` - stringified json with key:state values, where key is key from mdata or idata and state indicates recommended way of displaying field: url, img, webgl, mp3, video, hide (ie. don't display), etc. -`imgpriority` - json with assosiation category with type of image or video - txt - default - url - show as clickable URL - img - link to img file +`priorityimg` - json with assosiation category with type of image or video + txt - text (default) + url - show as clickable URL + img - link to img file webgl - link to webgl file - mp3 - link to mp3 file + mp3 - link to mp3 file video - link to video file hide - do not show imgb - image as string in binary format @@ -261,8 +261,8 @@ Input parameters: `assetids` - array of assetid's to delegate; `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; -`redelegate`- allow more redelegate or not; `memo` - memo for delegate action; +`autoreturn`- automatic return for delegated action; TERM This Contract expires at the conclusion of code execution. @@ -281,6 +281,7 @@ Executing action by real owner will return asset immediately, and the entry in t Input parameters: `owner` - real asset owner account; +`from` - current account owner (borrower); `assetids` - array of assetid's to undelegate; TERM diff --git a/ricardian/SimpleAssets.contracts.md.in b/ricardian/SimpleAssets.contracts.md.in index bf3a067..0cdd7dc 100644 --- a/ricardian/SimpleAssets.contracts.md.in +++ b/ricardian/SimpleAssets.contracts.md.in @@ -1,4 +1,4 @@ -

regauthor

+

authorreg

--- spec_version: 0.0.2 @@ -11,16 +11,16 @@ Action is not mandatory. Markets *may* choose to use information here to displa Input parameters: `author` - authors account who will create assets; -`data` - stringified json. Recommendations to include: game, company, logo, url, desc; -`stemplate` - stringified json with key:state values, where key is key from mdata or idata and +`dappinfo` - stringified json. Recommendations to include: game, company, logo, url, desc; +`fieldtypes` - stringified json with key:state values, where key is key from mdata or idata and state indicates recommended way of displaying field: url, img, webgl, mp3, video, hide (ie. don't display), etc. -`imgpriority` - json with assosiation category with type of image or video - txt - default - url - show as clickable URL - img - link to img file +`priorityimg` - json with assosiation category with type of image or video + txt - text (default) + url - show as clickable URL + img - link to img file webgl - link to webgl file - mp3 - link to mp3 file + mp3 - link to mp3 file video - link to video file hide - do not show imgb - image as string in binary format @@ -42,20 +42,20 @@ summary: Authors info update icon: @ICON_BASE_URL@/@AUTHORUPDATE_ICON_URI@ --- -Used to updated author information, and asset display recommendations created with the regauthor action. This action replaces the fields data and stemplate. To remove author entry, call this action with null strings for data and stemplate. +Used to updated author information, and asset display recommendations created with the authorreg action. This action replaces the fields dappinfo and fieldtypes. To remove author entry, call this action with null strings for dappinfo and fieldtypes. Input parameters: `author` - authors account who will create assets; -`data` - stringified json. Recommendations to include: game, company, logo, url, desc; -`stemplate` - stringified json with key:state values, where key is key from mdata or idata and +`dappinfo` - stringified json. Recommendations to include: game, company, logo, url, desc; +`fieldtypes` - stringified json with key:state values, where key is key from mdata or idata and state indicates recommended way of displaying field: url, img, webgl, mp3, video, hide (ie. don't display), etc. -`imgpriority` - json with assosiation category with type of image or video - txt - default - url - show as clickable URL - img - link to img file +`priorityimg` - json with assosiation category with type of image or video + txt - text (default) + url - show as clickable URL + img - link to img file webgl - link to webgl file - mp3 - link to mp3 file + mp3 - link to mp3 file video - link to video file hide - do not show imgb - image as string in binary format diff --git a/src/SimpleAssets.cpp b/src/SimpleAssets.cpp index a493d49..6c4290b 100644 --- a/src/SimpleAssets.cpp +++ b/src/SimpleAssets.cpp @@ -42,19 +42,21 @@ ACTION SimpleAssets::changeauthor( name author, name newauthor, name owner, vect } } -ACTION SimpleAssets::regauthor( name author, string data, string stemplate, string imgpriority ) { +ACTION SimpleAssets::authorreg( name author, string dappinfo, string fieldtypes, string priorityimg ) { require_auth( author ); require_recipient( author ); - check( data.size() > 3, "Data field is too short. Please tell us about yourselves." ); + + check( dappinfo.size() > 3, "Data field is too short. Please tell us about yourselves." ); + authors author_( _self, _self.value ); if ( author_.find( author.value ) == author_.end() ) { author_.emplace( author, [&]( auto& s ) { s.author = author; - s.data = data; - s.stemplate = stemplate; - s.imgpriority = imgpriority; + s.dappinfo = dappinfo; + s.fieldtypes = fieldtypes; + s.priorityimg = priorityimg; }); } else { @@ -62,22 +64,23 @@ ACTION SimpleAssets::regauthor( name author, string data, string stemplate, stri } } -ACTION SimpleAssets::authorupdate( name author, string data, string stemplate, string imgpriority ) { +ACTION SimpleAssets::authorupdate( name author, string dappinfo, string fieldtypes, string priorityimg ) { require_auth( author ); require_recipient( author ); + authors author_( _self, _self.value ); auto itr = author_.require_find( author.value, string("author " + author.to_string() + " not registered").c_str() ); - if ( data.empty() && stemplate.empty() ) { + if ( dappinfo.empty() && fieldtypes.empty() ) { itr = author_.erase( itr ); } else { author_.modify( itr, author, [&]( auto& s ) { - s.data = data; - s.stemplate = stemplate; - s.imgpriority = imgpriority; + s.dappinfo = dappinfo; + s.fieldtypes = fieldtypes; + s.priorityimg = priorityimg; }); } } @@ -175,6 +178,15 @@ 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::checkwaxauthor( name author ) { + + for ( auto i = 0; i < waxauthors.size(); ++i ) { + if ( author == waxauthors[i] ) { + internal_use_do_not_use::require_auth2( "wet.wax"_n.value, "nftops"_n.value ); + } + } +} + ACTION SimpleAssets::transfer( name from, name to, vector& assetids, string memo ) { check( from != to, "cannot transfer to yourself" ); @@ -224,6 +236,8 @@ ACTION SimpleAssets::transfer( name from, name to, vector& assetids, s 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?" ); + checkwaxauthor( itr->author ); + assets_t.emplace( rampayer, [&]( auto& s ) { s.id = itr->id; s.owner = to; @@ -276,7 +290,9 @@ ACTION SimpleAssets::offer( name owner, name newowner, vector& assetid delegates delegatet( _self, _self.value ); for ( auto i = 0; i < assetids.size(); ++i ) { - check( assets_f.find ( assetids[i] ) != assets_f.end(), "Asset id: " + to_string(assetids[i]) + " was not found." ); + const auto itr = assets_f.find ( assetids[i] ); + check( itr != assets_f.end(), "Asset id: " + to_string( assetids[i] ) + " was not found." ); + checkwaxauthor( itr->author ); check( offert.find ( assetids[i] ) == offert.end(), "Asset id: " + to_string(assetids[i]) + " is already offered for claim." ); check( delegatet.find( assetids[i] ) == delegatet.end(), "Asset id: " + to_string(assetids[i]) + " is delegated and cannot be offered." ); @@ -325,6 +341,7 @@ ACTION SimpleAssets::burn( name owner, vector& assetids, string memo ) check( offert.find( assetids[i] ) == offert.end(), "Asset id: " + to_string(assetids[i]) + " has an open offer and cannot be burned." ); check( delegatet.find( assetids[i] ) == delegatet.end(), "Asset id: " + to_string(assetids[i]) + " is delegated and cannot be burned." ); + checkwaxauthor( itr->author ); //Events uniqauthor[itr->author].push_back( assetids[i] ); assets_f.erase(itr); @@ -952,7 +969,7 @@ ACTION SimpleAssets::claimntt( 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_claimer.emplace( claimer, [&](auto& s) { - s.id = itr->id; + s.id = itr->id; s.owner = claimer; s.author = itr->author; s.category = itr->category; @@ -1034,7 +1051,7 @@ std::string SimpleAssets::timeToWait( uint64_t time_in_seconds ){ EOSIO_DISPATCH( SimpleAssets, ( create )( createlog )( transfer )( burn )( update ) ( offer )( canceloffer )( claim ) -( regauthor )( authorupdate ) +( authorreg )( authorupdate ) ( delegate )( undelegate )( delegatemore )( attach )( detach ) ( createf )( updatef )( issuef )( transferf )( burnf ) ( offerf )( cancelofferf )( claimf )