二、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…

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

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

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

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

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

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

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

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

如何在web api中使用SignalR

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

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

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

Badboy自动化测试工具11 导出脚本用于Jmeter并发测试

本节主要讲解利用Jmeter进行并发测试和引入图像报表 1. 在Jmeter中打开上节课(10)Badboy导出的在拉手网查询KTV的脚本Lashou_Search.jmx. 2. 右击Lashou节点,Add->Listener->Aggregate Graph & Graph Results 3. 对图像报表进行配置…

ArcGIS实验教程——实验三十九:ArcGIS多元分类(ISO聚类分析、最大似然分类、主成分分析)案例教程

ArcGIS实验视频教程合集:《ArcGIS实验教程从入门到精通》(附配套实验数据)》 文章目录 一、ISO聚类1. ISO聚类简介2. ISO聚类进行非监督分类实验操作二、最大似然分类1. 最大似然简介2. 最大似然分类实验案例三、主成分分析1. 主成分分析简介2. 主成分分析实验案例四、配套实…

ABP Framework 5.3.0 版本新增功能和变更说明

ABP Framework 5.3.0 稳定版已在2022年6月14日正式发布。以下是本版本的新增功能:• “开始”页面提供创建单层项目选项• 启动模板提供 PWA 支持• Volo.Abp.Gdpr.Abstractions 包介绍• 将发件箱中的事件批量发布到事件总线• eShopOnAbp 项目改进和电子书公告• …

智能合约开发——TypeScript 基础(全)

TS 准备 首先我们准备一个目录,使用 dos 进入到某目录,当然你直接 vs 打开终端执行也是没有问题的: 执行以下命令安装 typescrip(不用进入目录,直接安装即可): npm install -g typescript我是…

利用Signalr实现手机端App扫码登录web页面

实现原理: 1、web登录页面,利用jquery.qrcode展示一个随机生成的登录码的二维码; 2、手机App扫描二维码取得登录码; 3、手机App将本地用户id登录码通过api提交服务器; 4、服务器api,收到手机App请求&am…

【ArcGIS风暴】ArcGIS栅格影像(NDVI)归一化处理的两种方法精解

【ArcGIS遇上Python】ArcGIS批量处理栅格影像(NDVI)归一化完整案例代码 图像归一化是指对图像进行了一系列标准的处理变换,使之变换为一固定标准形式的过程,该标准图像称作归一化图像。 原始图像在经历一些处理或攻击后可以得到多种副本图像,这些图像在经过相同参数的图像…

以小见大:一个领域建模的简单示例,理解“领域驱动”。

背景:航空公司为了确保飞行路线不发生冲突,需要开发一款飞行路线管理软件。过程:我们先去找这个领域的专家,自然是作为平时管理和维护机场飞行秩序的工作人员;我们第一个目标就是与他们沟通,也许我们并不能…

【ArcGIS遇上Python】ArcGIS批量处理栅格影像(NDVI)归一化完整案例代码

文章《ArcGIS栅格影像(NDVI)归一化处理的两种方法精解》详细介绍了ArcGIS中进行NDVI影像归一化处理的两种方法,但是无法批量进行,本文就放大招用Python实现批量NDVI归一化处理,大大提高了工作效率,还不赶快Get了? 完整Python代码: import arcpy from arcpy import env…

Spark1.0.0 属性配置

1:Spark1.0.0属性配置方式Spark属性提供了大部分应用程序的控制项,而且能够单独为每一个应用程序进行配置。在Spark1.0.0提供了3种方式的属性配置:SparkConf方式 SparkConf方式能够直接将属性值传递到SparkContext;SparkConf能够对…

Lync Server 2010迁移至Lync Server 2013部署系列 Part1: 扩展AD架构

由于最近直在忙Lync 升级,好久没有更新博客了,今天开始将对最近做的Lync Server 2010迁移至Lync Server 2013项目做一个系列的部署操作更新,希望能给即将在企业中部署的兄弟们有所帮助,在这个测试环境中,企业 前端池共…

Hello Playwright:(7)模拟键盘和鼠标

尽管在上一节中,我们已经能够通过FillAsync或ClickAsync来实现输入和点击元素。但是,还有其他场景,我们必须模拟用户使用键盘、鼠标与页面交互。例如在线文档:Page.Keyboard 对象Keyboard提供用于管理虚拟键盘的 API,它…

【ArcGIS遇上Python】Python批量将多个文件夹下的多个影像数据镶嵌至新栅格

ArcGIS虽然可以实现一次多个影像同时参与,拼接成一个整的影像,但是通常情况下,多个影像并不在同一个文件夹下,这样拼接的时候需要逐个手动进行添加,如果数据量大的话,跟不就不可取,针对这一问题,本文采用Python,实现将多个文件夹下的多个影像拼接,高效快速。 我们以…