就是要学社区 QQ群组:646854445
你并非已无懈可击,所以你不能逃避问题,拒绝学习!

145孤荷凌寒自学第0231天_区块链第145天NFT042继续自己的NFT合约与前端

|阅读量:131 |发布于2021-04-13 08:13:03


正文内容

笔记合集在github上:

https://github.com/lhghroom/Self-learning-blockchain-from-scratch


【主要内容】

今天继续修改完善智能合约代码,共耗时30分钟。

(此外整理作笔记花费了约26分钟)

详细学习过程见文末学习过程屏幕录像。


【搞清楚了数组的一些知识】

https://blog.csdn.net/qq_33764491/article/details/80394739

https://www.jianshu.com/p/8e3da36fe587

1.添加memory的关键字的内存数组,不会记录到区块中,只存在于内存中,因此:

(1)尽量声明成定长数组

声明方法

uint[5] a;

方括号里必须是一个常数,而不能是变量之类的。

(2)也可以声明为变长数组,但必须在声明后明确初始化,一旦初始化,数组的长度Length又被固定了,再也不能修改,也就又成为了定长数组。

但在初始化时,使用New关键字的时候,就可以使用变量来指定长度了。

于是最终写法是这样的

c是一个整数型变量

```

       uint256[] memory idlst=new uint[](c);

```

这样就完成了一个memory类型的数组的初始化,这个数组将拥有c个元素。后面数组的元素个数(就是它的Length)就再也不能修改了。

3.只要在智能合约的函数中的数组使用了storage关键字,这个函数方法就是一个必须 付gas的方法。此外的发现,如果在函数内声明一个数组,既不使用storage关键字,也不使用memory关键字,则也是要求付gas的,这儿尚且不明白,难道默认声明数组就是storage吗?

【今天修改后的用于读取合约中已经被注销的NFT的ID列表的函数】

```

 //这儿还应当有一个方法:把已经被节点自己注销的NFT的ID信息查询出来 ,返回所有已被注销的NFT资产的ID数组

 function getdestroyid() public view returns (uint256[]){

     //这里不能返回字符串数组,

     //https://blog.csdn.net/weixin_34242819/article/details/89695922

     uint intc = _assetsIds.length;

     uint c = 0; //第一步读取出有多少个NFT 是被注销的

     if(intc > 0){

       uint i = 0;

       uint256 id = 0;

       for(i = 0;i < intc;i++){

         id=_assetsIds[i];

         if(_holderOf[id]==0){

           //===拥有者为零的nft就是已经被注销掉的

           c=c+1; ///这一次只是在计数

         }

       }


       uint256[] memory idlst=new uint[](c);

       //https://www.jianshu.com/p/8e3da36fe587

       //定长数组的定义,方括号里只能是常量,不能是变量,所以使用new 关键字来指明 初始化值

       //重新获取 具体的ID

       uint k = 0;

       for(i=0;i<intc;i++){

         id=_assetsIds[i];

         if(_holderOf[id]==0){

           //===拥有者为零的nft就是已经被注销掉的

           k=k+1;

           if(k<=c){

             idlst[k-1] = id;

           }

         }

       }

       

       return idlst;


     }

 }

```

已经测试通过。


【最终完成的文件:StandardAssetRegistryTest.sol】

已部署测试成功。

```

pragma solidity ^0.4.18;


import './FullAssetRegistry.sol';

//这个合约是最终可供部署的合约

//第一次部署完成这个合约的地址 0x61b84673A5768Fd046c98e69251C8f5493B44497   第一次部署时,使用的基准sol文件是:exchange.sol

//第二次部署完成的这个合约的地址 0xeD4202E35c63EDfDC38Fff34100Ac86217960DD3   第二次部署时,使用的基准sol文件就是本合约文件

//第三次部署完成的这个合约的地址 0xCDBc486981014948e87F8A53b8F754405F1fA5E8   第三次部署时,使用的基准sol文件与第二次一样,本次文件作了大量的修改

//第四次部署完成的这个合约的地址 0x487866047aF2078A0dB86E2217539898c0E9c7c3

//第五次部署完成的这个合约地址 0x66f39DBAc585457B57540ebA5eF92aaBE4a0fa8F

//第六次部署完成的这个合约地址 0x4896caDbd8633661ca988f9cb0b21d4b5C5Ea79b

contract StandardAssetRegistryTest is FullAssetRegistry {


 constructor() public {

   _name = "ghlhNft"; //给nft命名

   _symbol = "GHLH"; //标识代号

   _description = "ghlh's nft assets"; //描述

   addowner=msg.sender; //指明了谁是这个合约的部署者,目前的设想是:合约的拥有者可以把已被原资产拥有者主动销毁的资产重新分配给新的节点地址;合约拥有者可以获得一定交易手续费

 }


 //下面的方法检查某个节点地址是不是一个合约地址-------------------------

 function isContractProxy(address addr) public view returns (bool) {

   return _isContract(addr); //在基类合约 ERC721Base.sol 中定义的一个仅供合约内部调用的方法

 }


 //生成一个新资产,这个函数已被孤荷凌寒修改。 这个方法供外部调用。beneficiary是受益人节点地址,也就是把指定ID的NFT资产登记到beneficiary节点名下

 function generate(address beneficiary,string data) public {

   uint256 assetId = _getnewfreeassetid(); //获取一个新的ID,在基类合约 ERC721Base.sol 中定义的一个仅供合约内部调用的方法

   _generate(assetId, beneficiary); //登记这个新的NFT资产在基类合约 ERC721Base.sol 中定义的一个仅供合约内部调用的方法

   //下面是孤荷凌寒补充的,增加这个ID资产的URL

   _update(assetId,data); //这个方法是个仅供内部调用的方法在文件ERC721Metadata.sol中定义的

 }


 //让指定ID的NFT资产(由形参assetId指定)从现在的拥有在手中 脱离(转移开),就是使其现拥有者不再拥有这个NFT资产,

 //这这时候只有assetId的拥有节点可以执行销毁操作

 function destroy(uint256 assetId) public {

   _destroy(assetId); //在基类合约 ERC721Base.sol 中定义的一个仅供合约内部调用的方法

 }


 //合约拥有者可以把已经注销的NFT资产进行恢复,并指定给另一个节点

 //只有合约拥有者可以操作

 function recovery(uint256 assetId,address newadd) public {

   _recovery(newadd,assetId);

 }


 //这儿还应当有一个方法:把已经被节点自己注销的NFT的ID信息查询出来 ,返回所有已被注销的NFT资产的ID数组

 function getdestroyid() public view returns (uint256[]){

     //这里不能返回字符串数组,

     //https://blog.csdn.net/weixin_34242819/article/details/89695922

     uint intc = _assetsIds.length;

     uint c = 0; //第一步读取出有多少个NFT 是被注销的

     if(intc > 0){

       uint i = 0;

       uint256 id = 0;

       for(i = 0;i < intc;i++){

         id=_assetsIds[i];

         if(_holderOf[id]==0){

           //===拥有者为零的nft就是已经被注销掉的

           c=c+1; ///这一次只是在计数

         }

       }


       uint256[] memory idlst=new uint[](c);

       //https://www.jianshu.com/p/8e3da36fe587

       //定长数组的定义,方括号里只能是常量,不能是变量,所以使用new 关键字来指明 初始化值

       //重新获取 具体的ID

       uint k = 0;

       for(i=0;i<intc;i++){

         id=_assetsIds[i];

         if(_holderOf[id]==0){

           //===拥有者为零的nft就是已经被注销掉的

           k=k+1;

           if(k<=c){

             idlst[k-1] = id;

           }

         }

       }

       

       return idlst;


     }


 }



 // Problematic override on truffle 转移资产的方法

 function safeTransfer(address from, address to, uint256 assetId, bytes data) public {

   return _doTransferFrom(from, to, assetId, data, true); //在基类合约 ERC721Base.sol 中定义的一个仅供合约内部调用的方法//这个仅供合约内部使用的函数才是真正的实现NFT资产转移 的函数过程

 }

}



```


github: https://github.com/lhghroom/Self-learning-blockchain-from-scratch


【同步语音笔记】

https://www.ximalaya.com/keji/19103006/366823278


【学习过程屏幕录屏】

https://www.bilibili.com/video/BV1Hf4y1q7v9/


【就是要学】社区
一个平等,纯粹的社群
本社群旨在为真正愿意不断学习,终身成长的朋友提供一个平等互助互相鼓励的清洁纯粹的学习交流的平台。
加入社群将获得
1、与真正终身学习者为伍
2、在榜样带领下坚持每天学习,终身成长
3、养成记录时间日志,成功日记的习惯


【就是要学】社区QQ群:646854445





【返回首页】