【主要内容】
今天继续修改完善智能合约代码,共耗时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
【欢迎大家加入[就是要学]社群】
如今,这个世界的变化与科技的发展就像一个机器猛兽,它跑得越来越快,跑得越来越快,在我们身后追赶着我们。
很多人很早就放弃了成长,也就放弃了继续奔跑,多数人保持终身不变的样子,原地不动,成为那猛兽的肚中餐——当然那也不错,在猛兽的逼迫下,机械的重复着自我感觉还良好地稳定工作与生活——而且多半感觉不到这有什么不正常的地方,因为在猛兽肚子里的是大多数人,就好像大多数人都在一个大坑里,也就感觉不出来这是一个大坑了,反而坑外的世界显得有些不大正常。
为什么我们不要做坑里的大多数人?
因为真正的人生,应当有百万种可能 ;因为真正的一生可以有好多辈子组成,每一辈子都可以做自己喜欢的事情;因为真正的人生,应当有无数种可以选择的权利,而不是总觉得自己别无选择。因为我们要成为一九法则中为数不多的那个一;因为我们要成为自己人生的导演而不是*成为别人安排的戏目中的演员。
【请注意】
就是要学社群并不会告诉你怎样一夜暴富!也不会告诉你怎样不经努力就实现梦想!
【请注意】
就是要学社群并没有任何可以应付未来一切变化的独门绝技,也没有值得吹嘘的所谓价值连城的成功学方法论!
【请注意】
社群只会互相帮助,让每个人都看清自己在哪儿,自己是怎样的,重新看见心中的梦想,唤醒各自内心中的那个英雄,然后勇往直前,成为自己想要成为的样子!
期待与你并肩奔赴未来!
QQ群:646854445 (【就是要学】终身成长)
【原文地址】
https://www.941xue.com/content.aspx?k=941XUEPEXEAE81991768775335325452
【同步语音笔记】
https://www.ximalaya.com/keji/19103006/366823278
【学习过程屏幕录屏】
https://www.bilibili.com/video/BV1Hf4y1q7v9/