Skip to content

Latest commit

 

History

History
351 lines (270 loc) · 9.63 KB

README_cn.md

File metadata and controls

351 lines (270 loc) · 9.63 KB

通用加密资产代币(UCAT-Universal Crypto Asset Token)

概述

UCAT是一个通用资产代币协议

简介

非同质化代币(NFT)是区块链发展的重要产物,以下内容将包含运行于EOS/IOST/ETH有关于UCAT的智能合约描述,包含UCAT的发行、转移、交易跟踪等技术内容。 UCAT定义下的加密资产,主要应用于游戏场景,例如:

收藏品-独一无二或者有限数量的线上艺术品

特有装备或道具-在游戏中有唯一标识或是数量有限的装备、道具

UCAT协议下的加密资产,应有如下特征:

1,唯一性

每一个资产应有发行方的唯一编号,并能确保发行数量在有限的范围内。

2,可转移

每一个UCAT资产应该可以由用户自由转移

3,资产映射

每一个UCAT资产归属于拥有人,可以在不同的游戏中实现映射;若发行方不希望发行后的UCAT资产被其它游戏映射,发行时应加以说明,并在合约中声明。

备注:

The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119.

协议

最新更新

增加面值,等级,质量字段

#include <eosio/eosio.hpp>
#include <eosio/asset.hpp>
#include <eosio/singleton.hpp>
#include <string>
#include <math.h>

#define max(a,b) (a>b?a:b)


namespace eosiosystem {
   class system_contract;
}

using namespace eosio;

#define SYSPARAM_TOKEN_COUNT		1
#define SYSPARAM_CONTRACT_ENABLE	2

#define SYSPARAM_ADMIN_ACCOUNT		4
#define CONTRACT_NAME			    6
#define CONTRACT_LOGO			    7


#define HTML_TEMPLATE			10
#define SYSPARAM_VERSION		11



class [[eosio::contract("eosnft")]] eosnft : public contract
{   

public:

   using contract::contract;

   TABLE sysparam{
        uint64_t	id;
        std::string	tag;
        std::string	val;

        uint64_t primary_key() const { return id; }
   };
   typedef multi_index<"sysparams"_n, sysparam> sysparam_index;
    
 
    TABLE accounts {
        name id;

        uint64_t count;

        uint64_t primary_key() const { return id.value; }
    };
    typedef multi_index<"accounts"_n, accounts> account_index;


    TABLE token {
        uint64_t id;
	std::string uuid;
        std::string title;
        name        owner;
        std::string imageUrl;
        std::string category;
        std::string ext;
        std::string meta;
        bool	    lock;

        //--ext-prop for this contract
        uint64_t	level;
        uint64_t    quality;
        asset		parvalue;
        time_point_sec	stackexpire;  

        uint64_t minepower(){
            return 0;
        }      
	    

        uint64_t primary_key() const { return id; }
	uint64_t get_secondary_1() const { return owner.value;}
        uint64_t get_secondary_2() const { return level;}
    };
   typedef multi_index<"tokens"_n, token, 
        indexed_by<"byowner"_n, const_mem_fun<token, uint64_t, &token::get_secondary_1>>,
        indexed_by<"bylevel"_n, const_mem_fun<token, uint64_t, &token::get_secondary_2>> > token_index;


    TABLE logs {
        uint64_t id;
        name from;
        name to;
        std::string memo;
        uint64_t acttime;
        uint64_t tokenId;
        uint64_t primary_key() const { return id; }
    };
    typedef multi_index<"logs"_n, logs> log_index;


 private:

     double stringtodouble(std::string str) {
        double dTmp = 0.0;
        int iLen = str.length();
        int iPos = str.find(".");
        std::string strIntege = str.substr(0,iPos);
        std::string strDecimal = str.substr(iPos + 1,iLen - iPos - 1 );
        for (int i = 0; i < iPos;i++)
        {
        if (strIntege[i] >= '0' && strIntege[i] <= '9')
        {
        dTmp = dTmp * 10 + strIntege[i] - '0';
        }
        }
        for (int j = 0; j < strDecimal.length(); j++)
        {
        if (strDecimal[j] >= '0' && strDecimal[j] <= '9')
        {
        dTmp += (strDecimal[j] - '0') * pow(10.0,(0 - j - 1));
        }
        }
        return dTmp;
     }


     name get_admin() const {
         const std::string adminAccount = getsysparam(SYSPARAM_ADMIN_ACCOUNT);
         if (adminAccount.empty()) {
             return _self;
         }
         else {
             return name(adminAccount.c_str());
         }
     }

     void require_auth_admin() const { require_auth(get_admin()); }

     void require_auth_contract() const { require_auth( _self );}
     
     inline std::string getsysparam(const uint64_t& key) const {
        sysparam_index sysparams(_self, _self.value);
        auto iter = sysparams.find(key);
        if(iter == sysparams.end()){
                return std::string("");
        }else{
                return iter->val;
        }
    }

    
    inline void setsysparam(const uint64_t& id, const std::string& tag, const std::string& val){
	    sysparam_index sysparams(_self, _self.value);
	    auto iter = sysparams.find(id);
	    if(iter == sysparams.end()){
		    sysparams.emplace(_self, [&](auto& p) {
		        p.id  = id;
		        p.val = val;
			p.tag = tag;
		    });
	    }else{
		    sysparams.modify(iter, _self, [&](auto& p) {
			    p.val = val;
			    p.tag = tag;
		    });
	    }
    }

    inline void addaccounttoken(const name user) {
	    account_index accounts(_self, _self.value);
        auto iter = accounts.find(user.value);
        if (iter == accounts.end()) {
            accounts.emplace(_self, [&](auto& p) {
                p.id = user;
                p.count = 1;
                });
        }
        else {
            accounts.modify(iter, _self, [&](auto& p) {
                p.count += 1;
            });
        }
    }

    inline void subaccounttoken(const name user) {
        account_index accounts(_self, _self.value);
            auto iter = accounts.find(user.value);
            if (iter == accounts.end()) {
                return ;
            }
            
        if(iter->count > 1){
                accounts.modify(iter, _self, [&](auto& p) {
                    if (p.count > 1){
                        p.count -= 1;
                    }
            });
            }else{
        accounts.erase(iter);
        }
    }
    
    inline uint64_t toInt(const std::string& str) {
        if (str.empty() || str == "") {
            return 0;
        }
        else {
            std::string::size_type sz = 0;
            return std::stoull(str, &sz, 0);
        }
    }
    
    void log(const uint64_t& id, const name& oldowner, const name& newowner, const std::string& opcode, const std::string& ext);

    
    inline uint64_t gettokencount(){
	    return toInt(getsysparam(SYSPARAM_TOKEN_COUNT));
    }


    inline void addtokencount(){
	    setsysparam(SYSPARAM_TOKEN_COUNT, "SYSPARAM_TOKEN_COUNT", std::to_string(gettokencount() + 1));
    }

    inline void subtokencount(){
        uint64_t tokencount = gettokencount();
        if(tokencount > 0){
            setsysparam(SYSPARAM_TOKEN_COUNT, "SYSPARAM_TOKEN_COUNT", std::to_string(tokencount - 1));
        }
    }



 public:

     [[eosio::action]]
    void init(const std::string adminacc, const std::string title, const std::string image){
        require_auth_contract();
        setsysparam(SYSPARAM_ADMIN_ACCOUNT, "SYSPARAM_ADMIN_ACCOUNT", adminacc);
        setsysparam(CONTRACT_NAME, "CONTRACT_NAME", title);	
        setsysparam(CONTRACT_LOGO, "CONTRACT_LOGO", image);	
    }
 
    [[eosio::action]]
    void assign(const uint64_t id, const name owner, const name newowner);

    [[eosio::action]]
    void reassign(const uint64_t id, const name owner, const name newowner);
       
    [[eosio::action]]
    void create(const uint64_t id, const name owner, std::string title, std::string cate, std::string imageUrl, const bool lock, const uint64_t level, const uint64_t quality , const asset parvalue);

    [[eosio::action]]
    void updatemeta(const uint64_t id, const name owner, const std::string title, const std::string category, const std::string imageUrl, const std::string meta);

    [[eosio::action]]
    void updatelock(const uint64_t id, const name owner, const bool lock);

    [[eosio::action]]
    void updateext(const uint64_t id, const name owner, const std::string ext);

    [[eosio::action]]
    void transfer(const uint64_t id, const name from, const name to, const std::string memo);

    [[eosio::action]]
    void transmk(const uint64_t id, const name from, const name to, const std::string memo);

    [[eosio::action]]
    void setparam(const uint64_t id, const std::string tag, const std::string val){
	    require_auth_contract();
	    setsysparam(id,tag,val);
    }

    [[eosio::action]]
    void burn(const uint64_t id, const name owner){
        require_auth_admin();
        rmtoken_(id, owner);
    }

    //---- for debug 
    
    [[eosio::action]]
    void rmtoken(const uint64_t id, const name owner){
        require_auth_contract();
        rmtoken_(id, owner);
    }

    [[eosio::action]]
    void rmaccount(const name acc){
        require_auth_contract();
        account_index accounts(_self, _self.value);
        accounts.erase(accounts.find(acc.value));
    }

    [[eosio::action]]
    void rmparam(const uint64_t id){
        require_auth_contract();
        sysparam_index sysparams(_self, _self.value);
        sysparams.erase(sysparams.find(id));
    }

private:
    void rmtoken_(const uint64_t id, const name& owner){	
	token_index tokens(_self, owner.value);
	auto iter = tokens.find(id);
	check(iter != tokens.end(), "token not found");

	tokens.erase(iter);

	subtokencount();
	subaccounttoken(iter->owner);

	log(id, _self, _self, "BURN", "");
    }

    void notify(const name& to){
	    require_recipient(to);
    }

    void clearlog();
};