博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
在 NEO 上使用智能合约发布 NFT
阅读量:6079 次
发布时间:2019-06-20

本文共 8175 字,大约阅读时间需要 27 分钟。

作者:

用 NEO 智能合约实现 NFT

NFT 是什么

NFT(Non-Fungible Token)即非同质化代币,我们经常接触的数字货币 BTC、ETH 等都可以称为同质化代币,因为每个 BTC 都是一样的,价值和属性都一样;如果我们想用数字货币做更多事情,比如货币功能以外的资产登记、权证记录等,这时候需要的每一份“资产”都是独一无二的,它可以有自己的属性,可以单独修改,因此便有了NFT 的概念,即非同质化代币。

这里就讲讲如何在 NEO 区块链上使用智能合约实现 NFT。

需求

实现一套会员系统,成为会员后可以拥有一个 NFT 的证书,每个证书有唯一的编号标识,该证书可以记录会员的贡献值,贡献值达到一定数值可以进行升级,证书还可以转让出去,卖出后新的拥有者会享有证书附带的特权。

实现

设计合约时,可以按这个思路出发:从需求中提取合约要实现的功能,由功能来决定合约要提供的接口,然后细化每个接口的实现思路和权限等。

根据前面描述的需求,我们的证书合约需要具备发行证书、给证书加积分、证书升级、转卖证书的功能,由此可以得出合约要实现的接口:

  • 发行/购买证书:Deploy
  • 给证书加积分:AddPoint
  • 证书升级:Upgrade
  • 转卖证书:Exchange

除了以上基本功能外,我们还需要一些辅助功能,比如查询某个账户上有没有证书;所拥有的证书有多少积分,等级是多少;已经发行了多少个证书等:

  • 查询证书信息:GetNftInfo
  • 查询发行的数量:GetNftCount
  • 查询转卖信息:GetTxInfo

有了以上的设计,基本思路和实现方案已经清楚了,接下来就要开发合约了,开发前的配置准备工作可以参考 NEO 的智能合约。各接口实现代码和说明如下:

public class NFT : SmartContract    {        public static object Main(string method, object[] args)        {            var magicstr = "NFT";            if (Runtime.Trigger == TriggerType.Verification)            {                return false;            }            else if (Runtime.Trigger == TriggerType.VerificationR)            {                return true;            }            else if (Runtime.Trigger == TriggerType.Application)            {                //入口处取到调用脚本                var callscript = ExecutionEngine.CallingScriptHash;                //传入address获取nft信息                if (method == "GetNftInfo")                {                    byte[] address = (byte[]) args[0];                    if (address.Length == 0) return false;                    StorageMap addressMap = Storage.CurrentContext.CreateMap("addressMap");                    byte[] tokenId = addressMap.Get(address);                    if (tokenId.Length == 0) return false;                    return GetNftByTokenId(tokenId);                }                //传入txid 获取nft交易信息                if (method == "GetTxInfo")                {                    byte[] txid = (byte[]) args[0];                    if (txid.Length == 0) return false;                    return GetTxInfoByTxid(txid);                }                //获取已发行的nft数量                if (method == "GetNftCount")                {                    StorageMap nftCountMap = Storage.CurrentContext.CreateMap("nftCountMap");                    return nftCountMap.Get("nftCount").AsBigInteger();                }                //给一个address发行nft                if (method == "Deploy")                {                    byte[] address = (byte[]) args[0];                    if (address.Length == 0) return false;                    StorageMap addressMap = Storage.CurrentContext.CreateMap("addressMap");                    //用当前交易的交易二次hash作为nft的id                    var tokenId = Hash256((ExecutionEngine.ScriptContainer as Transaction).Hash);                    var newNftInfo = CreateNft(address, tokenId);                    if (SaveNftInfo(newNftInfo))                    {                        addressMap.Put(address, tokenId);                        AddNftCount();                        SetTxInfo(null, address, tokenId);                        return true;                    }                    return false;                }                //转手交易                if (method == "Exchange")                {                    byte[] from = (byte[]) args[0];                    byte[] to = (byte[]) args[1];                    if (from.Length == 0 || to.Length == 0)                        return false;                    StorageMap addressMap = Storage.CurrentContext.CreateMap("addressMap");                    byte[] toTokenId = addressMap.Get(to);                    byte[] fromTokenId = addressMap.Get(from);                    var fromNftInfo = GetNftByTokenId(fromTokenId);                    fromNftInfo.Owner = to;                    if (SaveNftInfo(fromNftInfo))                    {                        addressMap.Delete(from);                        addressMap.Put(to, fromTokenId);                        SetTxInfo(from, to, fromTokenId);                        return true;                    }                    return false;                }                //升级                if (method == "Upgrade")                {                    byte[] address = (byte[]) args[0];                    StorageMap addressMap = Storage.CurrentContext.CreateMap("addressMap");                    byte[] tokenId = addressMap.Get(address);                    if (tokenId.Length == 0) return false;                    var nftInfo = GetNftByTokenId(tokenId);                    nftInfo.Rank += 1;                    SaveNftInfo(nftInfo);                    return true;                }                //加分                if (method == "AddPoint")                {                    byte[] address = (byte[]) args[0];                    BigInteger pointValue = (BigInteger) args[1];                    if (address.Length == 0) return false;                    StorageMap addressMap = Storage.CurrentContext.CreateMap("addressMap");                    byte[] tokenId = addressMap.Get(address);                    if (tokenId.Length == 0) return false;                    var nftInfo = GetNftByTokenId(tokenId);                    nftInfo.Point += pointValue;                    if (SaveNftInfo(nftInfo))                        return true;                    return false;                }            }            return false;        }        //new一个新nft        public static NFTInfo CreateNft(byte[] owner, byte[] tokenId)        {            var nftInfo = new NFTInfo();            nftInfo.TokenId = tokenId;            nftInfo.Owner = owner;            nftInfo.Point= 0;            nftInfo.Rank = 1;            return nftInfo;        }        //增加已发行的数量        public static void AddNftCount()        {            StorageMap nftCountMap = Storage.CurrentContext.CreateMap("nftCountMap");            var oldCount = nftCountMap.Get("nftCount").AsBigInteger();            nftCountMap.Put("nftCount", oldCount + 1);        }        //保存nft信息        public static bool SaveNftInfo(NFTInfo nftInfo)        {            StorageMap userNftInfoMap = Storage.CurrentContext.CreateMap("userNftInfoMap");            byte[] nftInfoBytes = Helper.Serialize(nftInfo);            userNftInfoMap.Put(nftInfo.TokenId, nftInfoBytes);            return true;        }        //传入TokenID获得nft信息        public static NFTInfo GetNftByTokenId(byte[] tokenId)        {            StorageMap userNftInfoMap = Storage.CurrentContext.CreateMap("userNftInfoMap");            byte[] data = userNftInfoMap.Get(tokenId);            var nftInfo = new NFTInfo();            if (data.Length > 0)                nftInfo = data.Deserialize() as NFTInfo;            return nftInfo;        }        //保存交易信息        public static void SetTxInfo(byte[] from, byte[] to, byte[] tokenId)        {            ExchangeInfo info = new ExchangeInfo();            info.@from = from;            info.to = to;            info.tokenId = tokenId;            byte[] exInfo = Neo.SmartContract.Framework.Helper.Serialize(info);            //当前执行的ScriptContainer的Transaction Hash作为txid            var txid = (ExecutionEngine.ScriptContainer as Transaction).Hash;            StorageMap ExchangeInfoMap = Storage.CurrentContext.CreateMap("txInfoMap");            ExchangeInfoMap.Put(txid, exInfo);        }        //通过txid获取交易信息        public static ExchangeInfo GetTxInfoByTxid(byte[] txid)        {            ExchangeInfo info = new ExchangeInfo();            StorageMap ExchangeInfoMap = Storage.CurrentContext.CreateMap("txInfoMap");            var data = ExchangeInfoMap.Get(txid);            if (data.Length > 0)                info = data.Deserialize() as ExchangeInfo;            return info;        }    }    //交易信息    public class ExchangeInfo    {        public byte[] from;        public byte[] to;        public byte[] tokenId;    }    //证书信息    public class NFTInfo    {        public byte[] TokenId; //tokenid 证书ID        public byte[] Owner; //所有者 address        public BigInteger Rank; //等级        public BigInteger Point; //积分值    }复制代码

这样就实现了我们前面设计的接口,使用时编译发布合约到 NEO 网络上就可以了。

本文主要介绍如何结合 NEO 智能合约实现一个 NFT 合约以及开发 NEO 智能合约的基本思路和技术,省略了许多检查的部分,实际使用中我们可以结合需求来随意扩展,比如限制等级,控制数量,付费购买检查等。这里是一个更完善的 NEO 上 NFT 合约实现:。

转载地址:http://krhgx.baihongyu.com/

你可能感兴趣的文章
Ubuntu 问题解决汇总
查看>>
曾良 - 百度百科
查看>>
06 管理者意味着什么
查看>>
android权限大全
查看>>
微软必应借PK谷歌突围中国搜索市场
查看>>
刚子微信扯扯葱蒜
查看>>
[深入浅出Cocoa]iOS网络编程之NSStream
查看>>
HDOJ 4607 - Park Visit
查看>>
关于PHP 缓冲区
查看>>
分布式EventBus的Socket实现 - 发布订阅
查看>>
unity动态加载(翻译) .
查看>>
WIP_DISCRETE_JOBS.STATUS_TYPE
查看>>
一 VC2008环境中ICE的配置
查看>>
Win7无法添加用户的问题
查看>>
DCI:DCI学习总结
查看>>
- Shell - sort处理大文件(页 1) - ChinaUnix.net
查看>>
项目管理--执行过程组
查看>>
数据访问与sql语句的管理(一)
查看>>
前端开发框架
查看>>
风 记忆
查看>>