学习区块链(六)--创建僵尸军团进阶Ⅰ

2024-02-27 01:32

本文主要是介绍学习区块链(六)--创建僵尸军团进阶Ⅰ,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

在前面两章的介绍中,我们基本学会了solidty的基本语法,包括数据类型,函数的创建及其属性及事件,下面我们将继续深入学习solidity和Etherun的结合使用。

一.映射
首先介绍一个很重要的概念:地址,以太坊区块链由 account (账户)组成,你可以把它想象成银行账户。一个帐户的余额是 以太 (在以太坊区块链上使用的币种),你可以和其他帐户之间支付和接受以太币,就像你的银行帐户可以电汇资金到其他银行帐户一样。

每个帐户都有一个“地址”,你可以把它想象成银行账号。这是账户唯一的标识符,它看起来长这样:
0x5Dcf545Bfb5Cfe2313864DC3FAFa53c6003938F4
这是小弟的地址,欢迎打赏转账测试,哈哈!
如果我们需要wei僵尸指定主人,通过地址生成僵尸的id是个不错的主意,当用户通过与我们的应用程序交互来创建新的僵尸时,新僵尸的所有权被设置到调用者的太坊地址名下。

为了存储僵尸的所有权,我们会使用到两个映射:一个记录僵尸拥有者的地址,另一个记录某 ID 所拥有僵尸的数量。

1.创建一个叫做 zombieToOwner 的映射。其键是一个uint(我们将根据它的 id 存储和查找僵尸),值为 adress。映射属性为public。

   mapping (uint => address) public zombieToOwner;

2.创建一个名为 ownerZombieCount 的映射,其中键是一个 address,值是 uint。

    mapping (address => uint) ownerZombieCount;

这两部操作相当于Java的map,zombieToOwner这个映射输入僵尸id就能找到僵尸主人的地址,即address = map.get(“id”); 而ownerZombieCount 输入用户地址能获取他拥有僵尸的数量,即count = map.get(“address”);

二 .Msg.sender

在 Solidity 中,功能执行始终需要从外部调用者开始。 一个合约只会在区块链上什么也不做,除非有人调用其中的函数。调用者就是 msg.sender,msg.sender就是合约调用者的地址。

我们来修改 _createZombie 方法,将僵尸分配给函数调用者:

首先,在得到新的僵尸 id 后,更新 zombieToOwner 映射,在 id 下面存入 msg.sender。

然后,我们为这个 msg.sender 名下的 ownerZombieCount 加 1。

    function _createZombie(string _name, uint _dna) private {uint id = zombies.push(Zombie(_name, _dna)) - 1;// 从这里开始zombieToOwner[id] = msg.sender;ownerZombieCount[msg.sender]++;NewZombie(id, _name, _dna);}

有了前面和map的对比,这里很好理解。

三.require

我们成功让用户通过调用 createRandomZombie 并输入一个名字来创建新的僵尸。 但是,如果用户能持续调用这个函数来创建出无限多个僵尸加入他们的军团,这游戏就太没意思了!
根据以往的开发经验,此时就使用if()去判断一个地址是否创建一个僵尸,创建过了就不再次创建,而在solidity中,我们是用require来更简洁的实现这一功能:
我们在createRandomZombie方法开始的时候使用 require(ownerZombieCount[msg.sender] == 0);来判断用户是否已经创建了僵尸,如果ownerZombieCount[msg.sender]不等于0就会抛出一个错误不再继续执行合约!

    function createRandomZombie(string _name) public {require(ownerZombieCount[msg.sender] == 0);uint randDna = _generateRandomDna(_name);_createZombie(_name, randDna);}

本章完整代码:

pragma solidity ^0.4.19;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;function _createZombie(string _name, uint _dna) private {uint id = zombies.push(Zombie(_name, _dna)) - 1;zombieToOwner[id] = msg.sender;ownerZombieCount[msg.sender]++;NewZombie(id, _name, _dna);}function _generateRandomDna(string _str) private view returns (uint) {uint rand = uint(keccak256(_str));return rand % dnaModulus;}function createRandomZombie(string _name) public {require(ownerZombieCount[msg.sender] == 0);uint randDna = _generateRandomDna(_name);_createZombie(_name, randDna);}}

这篇关于学习区块链(六)--创建僵尸军团进阶Ⅰ的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



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

相关文章

Spring创建Bean的八种主要方式详解

《Spring创建Bean的八种主要方式详解》Spring(尤其是SpringBoot)提供了多种方式来让容器创建和管理Bean,@Component、@Configuration+@Bean、@En... 目录引言一、Spring 创建 Bean 的 8 种主要方式1. @Component 及其衍生注解

从基础到进阶详解Python条件判断的实用指南

《从基础到进阶详解Python条件判断的实用指南》本文将通过15个实战案例,带你大家掌握条件判断的核心技巧,并从基础语法到高级应用一网打尽,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一... 目录​引言:条件判断为何如此重要一、基础语法:三行代码构建决策系统二、多条件分支:elif的魔法三、

Unity新手入门学习殿堂级知识详细讲解(图文)

《Unity新手入门学习殿堂级知识详细讲解(图文)》Unity是一款跨平台游戏引擎,支持2D/3D及VR/AR开发,核心功能模块包括图形、音频、物理等,通过可视化编辑器与脚本扩展实现开发,项目结构含A... 目录入门概述什么是 UnityUnity引擎基础认知编辑器核心操作Unity 编辑器项目模式分类工程

Python进阶之列表推导式的10个核心技巧

《Python进阶之列表推导式的10个核心技巧》在Python编程中,列表推导式(ListComprehension)是提升代码效率的瑞士军刀,本文将通过真实场景案例,揭示列表推导式的进阶用法,希望对... 目录一、基础语法重构:理解推导式的底层逻辑二、嵌套循环:破解多维数据处理难题三、条件表达式:实现分支

MySQL 数据库表操作完全指南:创建、读取、更新与删除实战

《MySQL数据库表操作完全指南:创建、读取、更新与删除实战》本文系统讲解MySQL表的增删查改(CURD)操作,涵盖创建、更新、查询、删除及插入查询结果,也是贯穿各类项目开发全流程的基础数据交互原... 目录mysql系列前言一、Create(创建)并插入数据1.1 单行数据 + 全列插入1.2 多行数据

基于Python编写自动化邮件发送程序(进阶版)

《基于Python编写自动化邮件发送程序(进阶版)》在数字化时代,自动化邮件发送功能已成为企业和个人提升工作效率的重要工具,本文将使用Python编写一个简单的自动化邮件发送程序,希望对大家有所帮助... 目录理解SMTP协议基础配置开发环境构建邮件发送函数核心逻辑实现完整发送流程添加附件支持功能实现htm

Python学习笔记之getattr和hasattr用法示例详解

《Python学习笔记之getattr和hasattr用法示例详解》在Python中,hasattr()、getattr()和setattr()是一组内置函数,用于对对象的属性进行操作和查询,这篇文章... 目录1.getattr用法详解1.1 基本作用1.2 示例1.3 原理2.hasattr用法详解2.

MySQL 临时表创建与使用详细说明

《MySQL临时表创建与使用详细说明》MySQL临时表是存储在内存或磁盘的临时数据表,会话结束时自动销毁,适合存储中间计算结果或临时数据集,其名称以#开头(如#TempTable),本文给大家介绍M... 目录mysql 临时表详细说明1.定义2.核心特性3.创建与使用4.典型应用场景5.生命周期管理6.注

MySQL的触发器全解析(创建、查看触发器)

《MySQL的触发器全解析(创建、查看触发器)》MySQL触发器是与表关联的存储程序,当INSERT/UPDATE/DELETE事件发生时自动执行,用于维护数据一致性、日志记录和校验,优点包括自动执行... 目录触发器的概念:创建触www.chinasem.cn发器:查看触发器:查看当前数据库的所有触发器的定

创建springBoot模块没有目录结构的解决方案

《创建springBoot模块没有目录结构的解决方案》2023版IntelliJIDEA创建模块时可能出现目录结构识别错误,导致文件显示异常,解决方法为选择模块后点击确认,重新校准项目结构设置,确保源... 目录创建spChina编程ringBoot模块没有目录结构解决方案总结创建springBoot模块没有目录