二、solidity 基础进阶(2.1)—— library 库合约《实战NFT web3 solidity(新版本0.8.+)》

《web3 solidity0.8.+版本(持续更新新版本内容) 基础到实战NFT开发》会及时更新新版本 solidity 内容,以及完成最终的 NFT 实战商业项目部分。

注:由于是付费专栏内容,若有错误请及时联系@1_bit,博客链接:https://blog.csdn.net/A757291228 ,或在文章下留言,收到后将会对错误进行改正,若是版本更新导致的问题也希望大家对错误进行提交,尽力去保证付费用户该得到的权益。

文章目录可查看:目录(文章更新中…)
更新内容将会在目录中更新…

友情提示:本系列文章读者最好学过一门编程语言,面向对象语言更佳,文章所有代码将会完整贴出。

一、库 library

solidity 中的 library 库合约跟合约编写方式类似,在 solidity 中的作用是减少代码冗余,减少重复代码;在 library 合约中,不能创建状态遍历,你可以理解为库合约 library 就是一个“流水线”,不提供“原料”只做流程处理。

一个 library 不能够被继承,也不能够接受以太,我们只编写流程代码,并且使用 library 还可以节省 gas,毕竟代码减少了对吧?

二、库 library 合约示例

首先我们在 remix 上创建一个合约,名为 LibraryDemo:
在这里插入图片描述
在这个合约中新建一个合约:

// SPDX-License-Identifier:MITpragma solidity ^0.8.7;library LibraryDemo{
}

从以上代码中可以看出,创建一个 库合约 非常简单,只需要把以前所使用的合约关键字 contract 换成 library 即可。

接着在这个结构体中创建一个 struct 结构体,并且给与一个成员变量 map,是一个 mapping 映射:

struct structData{mapping(string=>uint32) map;
}

在这个时候就有同学疑问了,不是说不能创建状态变量吗?为什么这里创建了一个结构体?

如果没有这个疑问的同学,很好,你这点是理解的,其实在这里创建的是一个结构体,表示一种数据“结构”,从本质上来说这个结构体就是一个“数据结构”,此处我们并没有把这个结构体进行“实例化”之类的操作,所以它只是一种抽象的数据结构,即使我在内部创建了一个 map 映射,那也只是表示一种数据结构,就像你在一个 function 中创建一个 uint 类型的变量,那么这个变量也是属于 memory 对吧?

既然已经说清楚以上的结构体了,那么接下来我们在这个 library 中创建个方法:

function insertData(structData storage self,string memory _name,uint32 _age)public {self.map[_name]=_age;
}

以上这个方法叫做 insertData,顾名思义就是往里面插值,那往哪里插值呢?咱们可以看参数 structData storage self,这个参数是用 storage 进行修饰的,表示的是传入地址,那么传入地址过来的数据修改了,那么就表示本身进行了修改,所以此时所需要把值插入到的变量那应该就是 self,这个 self 是这个 structData 结构体类型的变量;接着还有两个参数,分别是 _name 和 _age,由于 string 是一个可变长的参,在这里使用了 memory 对其进行修饰。

这个函数的函数体中,solidity 代码 self.map[_name]=_age; 表示给结构体中的 map 赋值,这里使用 点运算符进行操作。

那么接下来就创建一个取值的方法:

function get(structData storage self,string memory _name)view public returns(uint32){return self.map[_name];
}

这个代码应该没啥好解释的吧?跟之前的类似,多了一个 view 对其进行修饰,毕竟是读数据,返回一个 uint32 的数据。

以上完整的 library 合约代码如下:

// SPDX-License-Identifier:MITpragma solidity ^0.8.7;library LibraryDemo{struct structData{mapping(string=>uint32) map;}function insertData(structData storage self,string memory _name,uint32 _age)public {self.map[_name]=_age;}function get(structData storage self,string memory _name)view public returns(uint32){return self.map[_name];}
}

三、调用 library 示例

接着开始 调用 library的示例,在同 sol 文件下编写一个合约名叫 CallLib:

contract CallLib{
}

在合约中创建一个变量为 library 合约中 结构体 structData 的类似变量:

LibraryDemo.structData private libObj;

在这里直接使用合约名用点运算符可获取到合约内的内容,在这里 LibraryDemo.structData 就表示这个库合约中的 structData 结构体类型,并且修饰为这个名为 libObj 的结构体变量为 私有 private 。(注意不能设置为 public,规定为 private )

若设置这个库合约的变量 libObj 为 public 即可得到一个报错:
在这里插入图片描述
接着就是创建两个方法了(上图已经暴露),一个叫做 insertName 另一个叫做 get。insertName 传入两个参数,一个是名另一个是年龄,在这里_name 参数是 string 变长类型所以使用了 memory,接着直接使用 library 合约 LibraryDemo 调用 insertData 方法,传入参数即可:

LibraryDemo.insertData(libObj,_name,_age);

在这里 libObj 为创建的合约结构体类型变量,在库合约中是 storage 修饰的,所以是传址,即在库合约中修改了值在 CallLib 合约中也会发生改变。

随后就是 get 方法:

function get(string memory _name)view public returns(uint32){return LibraryDemo.get(libObj,_name);
}

get 方法接收一个字符串类型的 _name 变量,之后返回年龄,所以 returns 所指定的返回类型为 uint32,接下来直接使用 库合约调用 get 方法传入名称即可。

最后部署合约,调用方法传入值即可:
在这里插入图片描述
多个值之间使用逗号隔开。

这第三点的完整代码如下:

// SPDX-License-Identifier:MITpragma solidity ^0.8.7;library LibraryDemo{struct structData{mapping(string=>uint32) map;}function insertData(structData storage self,string memory _name,uint32 _age)public {self.map[_name]=_age;}function get(structData storage self,string memory _name)view public returns(uint32){return self.map[_name];}
}contract CallLib{LibraryDemo.structData private libObj;function insertName(string memory _name,uint32 _age)public{LibraryDemo.insertData(libObj,_name,_age);}function get(string memory _name)view public returns(uint32){return LibraryDemo.get(libObj,_name);}
}

四、调用 library sol

除了在一个sol文件中直接调用库合约,还可以直接调用合约文件,而在现实中往往也是这样做的,毕竟所有东西写在一个文件内看着还是非常头疼的。

接着我们创建一个sol 文件叫做CallLib.sol:
在这里插入图片描述

随后使用 import 关键字对文件进行引用:

import "./LibraryDemo.sol";

其中路径 "./" 表示当前路径下,若你直接使用 "/" 则表示根目录下。使用 import 在其后面写上所需要引入的文件路径即可。

接着代码编写与原来一致,完整的 CallLib.sol 代码如下:

// SPDX-License-Identifier:MITpragma solidity ^0.8.7;import "./LibraryDemo.sol";contract CallLib{LibraryDemo.structData private libObj;function insertName(string memory _name,uint32 _age)public{LibraryDemo.insertData(libObj,_name,_age);}function get(string memory _name)view public returns(uint32){return LibraryDemo.get(libObj,_name);}
}

编译没问题后部署后调用:
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/285847.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

paper 17 : 机器学习算法思想简单梳理

前言: 本文总结的常见机器学习算法(主要是一些常规分类器)大概流程和主要思想。 朴素贝叶斯: 有以下几个地方需要注意: 1. 如果给出的特征向量长度可能不同,这是需要归一化为通长度的向量(这里以…

BZOJ1179 Atm //缩点+spfa

1179: [Apio2009]Atm Description Input 第一行包含两个整数N、M。N表示路口的个数,M表示道路条数。接下来M行,每行两个整数,这两个整数都在1到N之间,第i1行的两个整数表示第i条道路的起点和终点的路口编号。接下来N行&#xff0c…

centos 新建swap区文件

一. 相当详细且流程完整,(推荐阅读) 在centos7上新建swap区 https://www.digitalocean.com/community/tutorials/how-to-add-swap-on-centos-7 二. centos官网 转:https://www.centos.org/docs/5/html/5.2/Deployment_Guide/s2-sw…

ArcGIS实验教程——实验三十六:ArcGIS Python脚本的巧妙使用

ArcGIS实验视频教程合集:《ArcGIS实验教程从入门到精通》(附配套实验数据)》 文章目录 一、ArcGIS脚本简介二、Python脚本与ArcPy三、Python窗口四、脚本编写(案例:矢量数据批量裁剪)五、在ModelBuilder中使用脚本工具一、ArcGIS脚本简介 脚本与模型相似,也是把处理过程…

基于Spring Boot和Spring Cloud实现微服务架构学习

目录 Spring 顶级框架 Spring cloud子项目 WHAT - 什么是微服务 微服务简介 微服务的具体特征 SOA vs Microservice HOW - 怎么具体实践微服务 客户端如何访问这些服务? 服务之间如何通信? 这么多服务,怎么找? 这么多服务&#x…

C语言试题七十七之请编写函实现渔夫打鱼晒网问题

📃个人主页:个人主页 🔥系列专栏:C语言试题200例目录 💬推荐一款刷算法、笔试、面经、拿大公司offer神器 👉 点击跳转进入网站 ✅作者简介:大家好,我是码莎拉蒂,CSDN博客专家(全站排名Top 50),阿里云博客专家、51CTO博客专家、华为云享专家 1、题目 编写函数:…

.NetCore实现图片缩放与裁剪 - 基于ImageSharp

前言(突然发现断更有段时间了最近在做博客的时候,需要实现一个类似Lorempixel、LoremPicsum这样的随机图片功能,图片有了,还需要一个根据输入的宽度高度获取图片的功能,由于之前处理图片时使用到了ImageSharp库&#x…

Mysql身份认证漏洞及利用(CVE-2012-2122) 补充测试用例

当连接MariaDB/MySQL时,输入的密码会与期望的正确密码比较,由于不正确的处理,会导致即便是memcmp()返回一个非零值,也会使MySQL认为两个密码是相同的。也就是说只要知道用户名,不断尝试就能够直接登入SQL数据库。按照公…

添加启动类

添加.h和cpp #pragma once #include "afxwin.h" class mySplash :public CWnd {DECLARE_DYNAMIC(mySplash)protected:DECLARE_MESSAGE_MAP()public:CBitmap m_bitmap;void Create(UINT nBitmapID);afx_msg void OnPaint();afx_msg void OnTimer(UINT_PTR nIDEvent); …

ArcGIS实验教程——实验三十七:基于ArcGIS的太阳辐射分析案例教程

ArcGIS实验视频教程合集:《ArcGIS实验教程从入门到精通》(附配套实验数据)》 文章目录 一、太阳辐射的基本概念1. 视域2. 太阳图3. 星空图二、太阳辐射ArcGIS案例实现1. 对该区域进行太阳辐射区域分析2. 对单个点的太阳辐射进行分析太阳辐射是地球上各种物理过程和生物过程的…

C语言试题七十八之请编写函实现求2个数的最大公约数和最小公倍数(辗转相除法)

📃个人主页:个人主页 🔥系列专栏:C语言试题200例目录 💬推荐一款刷算法、笔试、面经、拿大公司offer神器 👉 点击跳转进入网站 ✅作者简介:大家好,我是码莎拉蒂,CSDN博客专家(全站排名Top 50),阿里云博客专家、51CTO博客专家、华为云享专家 1、题目 求2个数的…

restful-api-design-references

之所以创建这个 repository,是因为我希望收集一些比较好的有关于 RESTful API 设计的参考文献。偶尔回顾,偶尔改进,大家一起来吧~ 如果你有更好的私藏文章,不凡分享出来,独乐乐不如众乐乐,(⊙o⊙) RESTful…

jQuery 3.4.0 Released(2019.4.10)

jQuery has a new release! It’s been a while since our last release, but we expect this to be the last minor release in the 3.x branch, and then we will move on to the overhaul that will be jQuery 4.0. But before we get to 4.0, we’re excited to share the …

C#-Linq源码解析之DefaultIfEmpty

前言在Dotnet开发过程中&#xff0c;DefaultIfEmpty作为IEnumerable的扩展方法&#xff0c;十分常用。本文对DefaultIfEmpty方法的关键源码进行简要分析&#xff0c;以方便大家日后更好的使用该方法。使用DefaultIfEmpty 返回 IEnumerable< T> 的元素&#xff1b;如果序列…

ArcGIS实验教程——实验三十八:基于ArcGIS的等高线、山体阴影、山顶点提取案例教程

ArcGIS实验视频教程合集:《ArcGIS实验教程从入门到精通》(附配套实验数据)》 文章目录 1. 加载DEM2. 提取等高距为15m的等高线3. 提取等高距为75m的等高线4. 生成山体阴影5. 生成三维等高线6. 提取山顶点7. 实验数据下载地址山顶点指那些在特定邻域分析范围内,该点都比周围…

Zabbix3.0 安装Graphtree

zabbix中&#xff0c;想要集中展示图形&#xff0c;唯一的选择是screen&#xff0c;zatree可以解决这个问题&#xff0c;但是性能不是很好。 Graphtree由OneOaas开发并开源出来&#xff0c;用来解决zabbix的图形展示问题&#xff0c;性能比较好 因为默认的zabbix 展示图形很麻烦…

(2.3)其他补充—— 二、solidity 基础进阶《实战NFT web3 solidity(新版本0.8.+)》

《web3 solidity0.8.版本&#xff08;持续更新新版本内容&#xff09; 基础到实战NFT开发》会及时更新新版本 solidity 内容&#xff0c;以及完成最终的 NFT 实战商业项目部分。 注&#xff1a;由于是付费专栏内容&#xff0c;若有错误请及时联系1_bit&#xff0c;博客链接&am…

Android之实现点击布局缩小然后再放大动画

1、需求 现在需要实现点击View先缩小然后再放大效果 2、代码实现 在res的anim目录下面&#xff0c;写anim_small.xml文件 <?xml version"1.0" encoding"utf-8"?> <set xmlns:android"http://schemas.android.com/apk/res/android"…

如何在web api中使用SignalR

说明&#xff1a; 在webapi中使用signalr&#xff0c;使用IIS 环境&#xff1a; vs2012, .net4.5 第一步&#xff1a;建web api项目 第二步&#xff1a;nuget导入signalr Install-Package Microsoft.AspNet.SignalR Install-Package Microsoft.Owin.Cors &#xff08;用于…

Directx11学习笔记【二】 将HelloWin封装成类

我们把上一个教程的代码封装到一个类中来方便以后的使用。 首先新建一个空工程叫做MyHelloWin&#xff0c;添加一个main.cpp文件&#xff0c;然后新建一个类叫做MyWindow,将于窗体有关的操作封装到里面 MyWindow.h文件 1 /***************************************************…