# Web3.0学习树|6.Solidity基础 Ⅲ

By [链上巫师](https://paragraph.com/@looplove) · 2022-11-25

---

**这是Web3.0学习的第二章Solidity基础,文内如出现知识性和理解性错误还请各位斧正，原创文章，完全开源，若能得转载不胜荣幸，推特会分享Coding学习,生活日常和NBA等内容。**

[https://twitter.com/hanjin\_long](https://twitter.com/hanjin_long)

### 目录

*   **Memory,Storage&Calldata(介绍)**
    
*   **Mapping(映射)**
    
*   **部署第一个合约**
    
*   **EVM&第二章总结**
    
*   **下章预告**
    

### Memory,Storage&Calldata(介绍)

![](https://storage.googleapis.com/papyrus_images/afd31353653211e019e74f49b8bb51a8aed97542d54848439d01e01d251328c1.png)

但是我们不能说变量是storage,code或logs,只能说变量是memory,storage或calldata

       uint256 favoriteNumber;
       
       function addPerson(string memory _name, uint256 _favoriteNumber) public{
            People memory newPerson = People({favoriteNumber: _favoriteNumber, name: _name});
            people.push(newPerson);
            
            //上面那两句的效果相当于下面这一句
           //people.push(People(_favoriteNumber, _name));
        }
    

数据存储和存储器:

calldata:意味着变量只会暂时存在函数内, 是可以修改的临时变量

memory:意味着变量只会暂时存在函数内，是可以修改的临时变量所以上述那个\_name变量在交易期间只是暂时存在,调用这个addPerson函数

storage:意味着变量不仅会存储在函数内甚至会存储在函数之外,是可以修改的永久变量，如上述的uint256 fovoriteNumber,如果没有特别指定的话,默认是自动转化为storage变量

为什么上述的函数中,只有\_name需要指定memory,而 \_favoriteNumber不需要呢?

因为我们只能给数组、结构或映射指定数据位置。考虑数组,结构和映射被认为是Solidity里特殊的类型,Solidity自动知道在uint256中的位置,Solidity知道uint256类型的变量是一个临时变量。

但是不确定string类型的变量是什么,string其实是一个字节数组,因为string是一个数组,所以我们需要添加memory给数组指定数据位置,但是我们无法在\_name前面添加storage关键字,Solidity也知道,这是一个函数,这个 \_name变量实际上并没有存储在任何地方,故这个 \_name变量只接受memory和calldata。

总结:当我们将数组,结构和映射作为参数添加到不同的函数时,需要给出memory或calldata关键字。

### Mapping(映射)

映射是另一种存储列表的数据结构,访问数据更快更便捷(映射是一种数据结构，其中键被“映射”到单个值)。

映射就像一本字典或者一串钥匙,每个键返回与该键关联的某个值。

映射使用mapping(keyType => valueType)来定义，其中键需要是内置类型，如bytes，int，string或合约类型，而值可以是任何类型，如嵌套mapping类型。需要注意的是，mapping类型是不能被迭代遍历的，需要遍历则需要自行实现对应索引。

**基本操作**

>     //定义嵌套mapping类型
>     mapping(string => mapping(string => string)) nestedMap;
>     
>     //设置值
>     nestedMap[id][key] = "0707";
>     
>     //读取值
>     string value = nestedMap[id][key];
>     
>     //删除值
>     delete nestedMap[id][key];
>     

**创建一个映射变量**

        //字符串类型映射到uint类型
        //映射名为nameToFavoriteNumber,从名字映射到特定号码
        mapping(string => uint256) public nameToFavoriteNumber; 
    

然后将映射添加进数组里.

        function addPerson(string memory _name, uint256  _favoriteNumber) public{
           people.push(People(_favoriteNumber, _name));
           nameToFavoriteNumber[_name] = _favoriteNumber;//string => uint256
        }
    

创建映射时将所有内容初始化为其空值,字符串的初始值为0.

![](https://storage.googleapis.com/papyrus_images/fe1ad15ce3f640ba359c6ae28d9a7e1811192ca579a5d9c128c51c3ef00048c4.png)

部署第一个合约

部署合约后:

橙色按钮是写入

蓝绿色按钮是读取

红色按钮用于标记

假设我们真的很喜欢我们的合约并且我们准备好了把它发送给一个测试网,让其他人与之互动

inject Web3:注入Web3(部署到链上)

![](https://storage.googleapis.com/papyrus_images/fa5dfdd7f64419637be46f1673e53a46ec4ed7e040635e25404280f27d04d30c.png)

合约成功部署于Goerli测试网当中,一项由合约创建的交易。

![](https://storage.googleapis.com/papyrus_images/c22c1a288ed9a7456f10071353d2f869d5ce9144412965b8952efff799980c52.png)

当我们向合约存储数据时,相当于我们要修改区块链状态,此时钱包会弹出新的交易确认并要求我们签署该交易。

![](https://storage.googleapis.com/papyrus_images/540c5e0aa005615ce691995865bad5421c869f455a790afd0da01c5dfdb43625.png)

### EVM&第二章总结

EVM:以太坊虚拟机

EVM使用智能合约的标准,可以将Solity部署到与EVM兼容的区块链,例如Avalanche(雪崩),Fantom(幻影)和Polygon(多边形)

**回顾:**

你需要在智能合约当中做的第一件事是讲述你将使用什么版本的Solidity,另外需要添加一个SPDX许可证标识符。

然后必须创建自己的合约对象并命名自己的合约Solidity中的contract类似于其他编程语言当中的class。

Solidity有许多不同的类型,例如uint256,boolean,string,bytes32。

我们还可以创建结构体数组(struct)

可以创建动态数组和静态数组

还可以创建映射(mapping)

可以在Solidity中创建函数来修改区块链的状态

还可以创建只读的函数来查看区块链的状态(view和pure)

还可以指定函数中不同数据的存储位置(calldata,memory,storage)

函数的参数不能是storage类型的,因为这些参数只能存在于函数运行期间。

当我们点击编译,Solidity代码实际上编译成EVM规格的合约字节码然后部署的时候部署到以太坊链上。

### 下章预告

本章就分享到这里了，下一张会带大家真正去写一次智能合约，目前对智能合约的语法只有粗浅的讲解，之后的章节中会逐渐全面地讲语法讲全。

---

*Originally published on [链上巫师](https://paragraph.com/@looplove/web3-0-6-solidity)*
