【CryptoZombies - 1 Solidity 教程】014 函数可见性

2023-12-11 20:38

本文主要是介绍【CryptoZombies - 1 Solidity 教程】014 函数可见性,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

一、前言

看了一些区块链的教程,论文,在网上刚刚找到了一个项目实战,CryptoZombies。

如果你想了解更多有关于机器学习、深度学习、区块链、计算机视觉等相关技术的内容,想与更多大佬一起沟通,那就扫描下方二维码加入我们吧!

二、 函数可见性

1、回顾

我们之前讲函数权限,讲到函数可以设置公有和私有,当初设置私有是因为:不是任何时候,其他合约都可以调用某个合约中的函数,而且容易受到攻击。所以一般情况下,将函数定义为私有,只有外部调用时,才设置为公有

设置私有函数方式如下:

uint[] numbers;function _addToArray(uint _number) private {numbers.push(_number);
}

在这个代码中,我们定义一个无符号整数数组,并通过函数为其添加元素。

1.添加private意味着:只有合约中的其它函数才能够调用这个函数

2.和函数的参数类似,私有函数的名字用(_)起始

 

2、内部internal和外部external

1.引入

当我们讲到继承的时候,因为子合约不能继承使用父合约的私有函数,这显然和我们的想法是违背的,一旦继承,有些合约只不过不能让外部合约进行访问而已,但是子合约应该允许访问。所以通过private已经不能满足我们的需求了。所以我们引入外部和内部两个描述函数可见性的修饰词。

2.internal和external

public private 属性之外,Solidity 还使用了另外两个描述函数可见性的修饰词:

1.internal(内部) :internal 和 private 类似,不过, 如果某个合约继承自其父合约,这个合约即可以访问父合约中定义的“internal”函数。

2.external(外部):external 与public 类似,只不过这些函数只能在合约之外调用 - 它们不能被合约内的其他函数调用。

 声明函数 internal 或 external 类型的语法,与声明 private 和 public类 型相同:

contract Sandwich {uint private sandwichesEaten = 0;function eat() internal {sandwichesEaten++;}
}contract BLT is Sandwich {uint private baconSandwichesEaten = 0;function eatWithBacon() public returns (string) {baconSandwichesEaten++;// 因为eat() 是internal 的,所以我们能在这里调用eat();}
}

3、实战

1.要求

将 _createZombie() 函数的属性从 private 改为 internal , 使得其他的合约也能访问到它。

pragma solidity >=0.5.0 <0.6.0;contract ZombieFactory {event NewZombie(uint zombieId, string name, uint dna);uint dnaDigits = 16;uint dnaModulus = 10 ** dnaDigits;struct Zombie {string name;uint dna;}Zombie[] public zombies;mapping (uint => address) public zombieToOwner;mapping (address => uint) ownerZombieCount;// edit function definition belowfunction _createZombie(string memory _name, uint _dna) private {uint id = zombies.push(Zombie(_name, _dna)) - 1;zombieToOwner[id] = msg.sender;ownerZombieCount[msg.sender]++;emit NewZombie(id, _name, _dna);}function _generateRandomDna(string memory _str) private view returns (uint) {uint rand = uint(keccak256(abi.encodePacked(_str)));return rand % dnaModulus;}function createRandomZombie(string memory _name) public {require(ownerZombieCount[msg.sender] == 0);uint randDna = _generateRandomDna(_name);_createZombie(_name, randDna);}}

 

2.代码

pragma solidity >=0.5.0 <0.6.0;contract ZombieFactory {event NewZombie(uint zombieId, string name, uint dna);uint dnaDigits = 16;uint dnaModulus = 10 ** dnaDigits;struct Zombie {string name;uint dna;}Zombie[] public zombies;mapping (uint => address) public zombieToOwner;mapping (address => uint) ownerZombieCount;// edit function definition belowfunction _createZombie(string memory _name, uint _dna) internal {uint id = zombies.push(Zombie(_name, _dna)) - 1;zombieToOwner[id] = msg.sender;ownerZombieCount[msg.sender]++;emit NewZombie(id, _name, _dna);}function _generateRandomDna(string memory _str) private view returns (uint) {uint rand = uint(keccak256(abi.encodePacked(_str)));return rand % dnaModulus;}function createRandomZombie(string memory _name) public {require(ownerZombieCount[msg.sender] == 0);uint randDna = _generateRandomDna(_name);_createZombie(_name, randDna);}}

这篇关于【CryptoZombies - 1 Solidity 教程】014 函数可见性的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/482041

相关文章

PostgreSQL中rank()窗口函数实用指南与示例

《PostgreSQL中rank()窗口函数实用指南与示例》在数据分析和数据库管理中,经常需要对数据进行排名操作,PostgreSQL提供了强大的窗口函数rank(),可以方便地对结果集中的行进行排名... 目录一、rank()函数简介二、基础示例:部门内员工薪资排名示例数据排名查询三、高级应用示例1. 每

全面掌握 SQL 中的 DATEDIFF函数及用法最佳实践

《全面掌握SQL中的DATEDIFF函数及用法最佳实践》本文解析DATEDIFF在不同数据库中的差异,强调其边界计算原理,探讨应用场景及陷阱,推荐根据需求选择TIMESTAMPDIFF或inte... 目录1. 核心概念:DATEDIFF 究竟在计算什么?2. 主流数据库中的 DATEDIFF 实现2.1

MySQL中的LENGTH()函数用法详解与实例分析

《MySQL中的LENGTH()函数用法详解与实例分析》MySQLLENGTH()函数用于计算字符串的字节长度,区别于CHAR_LENGTH()的字符长度,适用于多字节字符集(如UTF-8)的数据验证... 目录1. LENGTH()函数的基本语法2. LENGTH()函数的返回值2.1 示例1:计算字符串

使用Docker构建Python Flask程序的详细教程

《使用Docker构建PythonFlask程序的详细教程》在当今的软件开发领域,容器化技术正变得越来越流行,而Docker无疑是其中的佼佼者,本文我们就来聊聊如何使用Docker构建一个简单的Py... 目录引言一、准备工作二、创建 Flask 应用程序三、创建 dockerfile四、构建 Docker

MySQL 中的 CAST 函数详解及常见用法

《MySQL中的CAST函数详解及常见用法》CAST函数是MySQL中用于数据类型转换的重要函数,它允许你将一个值从一种数据类型转换为另一种数据类型,本文给大家介绍MySQL中的CAST... 目录mysql 中的 CAST 函数详解一、基本语法二、支持的数据类型三、常见用法示例1. 字符串转数字2. 数字

Python内置函数之classmethod函数使用详解

《Python内置函数之classmethod函数使用详解》:本文主要介绍Python内置函数之classmethod函数使用方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地... 目录1. 类方法定义与基本语法2. 类方法 vs 实例方法 vs 静态方法3. 核心特性与用法(1编程客

Python函数作用域示例详解

《Python函数作用域示例详解》本文介绍了Python中的LEGB作用域规则,详细解析了变量查找的四个层级,通过具体代码示例,展示了各层级的变量访问规则和特性,对python函数作用域相关知识感兴趣... 目录一、LEGB 规则二、作用域实例2.1 局部作用域(Local)2.2 闭包作用域(Enclos

MySQL count()聚合函数详解

《MySQLcount()聚合函数详解》MySQL中的COUNT()函数,它是SQL中最常用的聚合函数之一,用于计算表中符合特定条件的行数,本文给大家介绍MySQLcount()聚合函数,感兴趣的朋... 目录核心功能语法形式重要特性与行为如何选择使用哪种形式?总结深入剖析一下 mysql 中的 COUNT

MySQL 中 ROW_NUMBER() 函数最佳实践

《MySQL中ROW_NUMBER()函数最佳实践》MySQL中ROW_NUMBER()函数,作为窗口函数为每行分配唯一连续序号,区别于RANK()和DENSE_RANK(),特别适合分页、去重... 目录mysql 中 ROW_NUMBER() 函数详解一、基础语法二、核心特点三、典型应用场景1. 数据分

MySQL数据库的内嵌函数和联合查询实例代码

《MySQL数据库的内嵌函数和联合查询实例代码》联合查询是一种将多个查询结果组合在一起的方法,通常使用UNION、UNIONALL、INTERSECT和EXCEPT关键字,下面:本文主要介绍MyS... 目录一.数据库的内嵌函数1.1聚合函数COUNT([DISTINCT] expr)SUM([DISTIN