笔记来自:17小时最全Web3教程:ERC20,NFT,Hardhat,CCIP跨链_哔哩哔哩_bilibili,十分推荐大家学习该课程!
目录
[1. Solidity语言与以太坊开发体系](#1. Solidity语言与以太坊开发体系)
[2. EVM与指令集](#2. EVM与指令集)
[1. 部署与链上交互](#1. 部署与链上交互)
[2. Remix中的部署环境选择](#2. Remix中的部署环境选择)
[1. bool布尔型](#1. bool布尔型)
[2. unit(unsigned integer)](#2. unit(unsigned integer))
[3. int](#3. int)
[4. bytes字节](#4. bytes字节)
[5. string:动态分配的bytes类型](#5. string:动态分配的bytes类型)
[6. bytes字节数组](#6. bytes字节数组)
[7. address](#7. address)
[1. Solidity的函数访问权限](#1. Solidity的函数访问权限)
[2. view 标识](#2. view 标识)
[3. 函数实现](#3. 函数实现)
一、Solidity概念
1. Solidity语言与以太坊开发体系
Solidity是当前智能合约领域使用最广泛的编程语言,主要用于在以太坊及兼容EVM的区块链上开发去中心化应用。其语法结构受C、JavaScript等语言影响,易于上手,可读性较高。

除了Solidity,也有Yul这样的底层语言,适用于追求极致性能与更深控制权的开发场景。智能合约在逻辑上等同于"不可篡改的后端程序",但运行环境完全交由区块链共识网络维护,不依赖中心化服务器。
2. EVM与指令集
EVM(Ethereum Virtual Machine)是以太坊虚拟机,用于执行编译后的字节码。Solidity编译器负责将源码转为opcode,而EVM负责解释执行。当EVM升级后,opcode指令集会随之扩充,开发者因此能够实现更多功能。这一关系形成了以太坊技术栈中的重要结构:语言层负责表达能力,EVM层负责执行上限。如果EVM版本较旧,则某些新opcode无法识别,即便编译器已经支持新语法,也无法真正运行。
当前EVM版本以城市命名,每一次版本升级都具有全网意义,相当于以太坊的整个区块链进行了一次升级(支持新操作、新功能等),需要节点运行同一套规则才能保持共识。
二、智能合约的部署
1. 部署与链上交互
智能合约在完成编写与编译后,需要部署至区块链节点组成的分布式网络。部署成功后,系统会分配一个合约地址,任何用户都可以通过该地址与之交互,例如调用函数或读取链上存储的数据。部署的过程会永久写入链上账本,属于一次性上链行为,逻辑无法修改,除非事先编写可升级合约结构(如使用代理模式)。
2. Remix中的部署环境选择
Remix是适合入门与快速测试的Web IDE,其中的部署界面最关键的选项是Environment。
Remix VM
完全本地运行的虚拟链,模拟EVM行为,不产生真实交易,适合逻辑验证与调试。
Injected Provider
使用浏览器钱包(如MetaMask)连接真实网络,包括主网与测试网。此类环境会产生真实交易纪录,部署需要消耗Gas和原生代币。
选择不同的环境决定了部署后的交互范围:本地环境仅供个人测试,链上部署则具备全球可读性与可调用性。
三、编译前的准备
无代码文件运行后,遇到两个警告,第一个警告为:
该警告表示:没有使用SPDX license,即合约所适用的开源软件协议。下面,我们查看一下SPDX license:
SPDX协议类型相当多,作者平常用Apache 2.0,课程老师推荐MIT。所以,在第一行补充MIT协议,第一个警告不再出现:

第二个警告则提醒我们需要在Remix里指定编译器的版本:
解决代码如下:

如果明确指定所有高于版本的编译器都可以执行我的指令,就需要在版本号前加^:
需要注意,版本更低的编译器是不能执行上述代码的。
需要contract关键字,表示合约/合同:
四、Solidity基础数据类型
1. bool布尔型
对于真值目前只能是true,而不能是其他正整数(1也不行):
因为智能合约是需要部署在区块链上的,不能由一个中心化的服务器自由删除以重新部署,所以一旦出现问题,都是不可逆的,故Solidity的语法严格程度是比较高的。
2. unit(unsigned integer)
无符号整数,可代表任何一个正数。
unit后可加具体的数值,表示该变量的存储范围。比如unit8代表我可以存储从0~255(2^8-1)的数据。经常使用的是unit256(unit不加具体数值,默认就是unit256,但建议都加入数据标识,提升可读性)。
3. int
同理,最常用的也是int256,负值不能用unit,需要用int变量承接。
4. bytes字节
一个byte字节=8bit。也建议后面加数据标识,代表这个变量最多能够存储几个字节,比如bytes8或者bytes32(最大是32)。bytes最多用来存储字符串(大小范围确定了):
5. string:动态分配的bytes类型
大小范围是动态确定的,但我们需要bytes,因为string的动态空间分配是比bytes32这样提前确定空间大小所消耗的空间更大。同理,如果数据不大,我们更推荐的是int8而不是int32。效率在智能合约中是相当重要的。
6. bytes字节数组
注意,bytes后不加数字,并不是代表bytes32,而是byte[ ]数组。
7. address
在区块链上,地址是一个非常常见的概念:
五、函数function编写
1. Solidity的函数访问权限
(或称"可见度标识符")有以下四类(对象:当前合约,外部合约,子合约,外部账户):
Internal有点像protected,对子合约开放。External是Internal的相反,自己和孩子都不能访问,只能被外界合约或账户访问(外部合约和账户的限制与否是同时出现的)。
2. view 标识
没有任何的状态改变(写操作),即只对变量进行读取,则需在声明函数时增加view关键字标识(告诉编译器我只会对变量进行读取而不是修改操作)。
3. 函数实现

点击deploy部署:
其中,左下角的控制台属性介绍如下:
- status:挖矿成功(本地部署其实没有挖矿)。
- transaction hash:交易哈希,可以理解为交易的身份证。可通过交易哈希找到某一个交易。
- block hash:区块哈希,同理,区块的身份证。一个block可以包含多个transaction。
- block number:在真实网络下,会很大,因为链已经非常长了。但在Remix本地,则number不真实。
点击sayHello函数卡片,即可收到"Hello World!"返回值,即函数function编写成功: