苏泽
大家好 这里是苏泽 一个钟爱区块链技术的后端开发者
本篇专栏 ←持续记录本人自学两年走过无数弯路的智能合约学习笔记和经验总结 如果喜欢拜托三连支持~
本篇主要是做一个知识的整理和规划 作为一个类似文档的作用 更为简要和明了 具体的实现案例和用法 后续会陆续给出一些demo~ 请持续关注~
目录
本篇主要是做一个知识的整理和规划 作为一个类似文档的作用 更为简要和明了 具体的实现案例和用法 后续会陆续给出一些demo~ 请持续关注~
数据类型
-
基本数据类型:
- 布尔型(bool):用于表示真(true)或假(false)。 示例:
bool isTrue = true;
uint256
。 示例:uint256 myNumber = 10;
-
地址类型(address):
address myAddress = 0xAbcdef;
-
字符串类型(string):
string myString = "Hello, World!";
-
数组类型(array):
uint256[] myArray = [1, 2, 3];
-
结构体类型(struct):
用于自定义复合类型,可以包含多个字段。 示例:
Copy Code struct Person { string name; uint age; } Person myPerson; myPerson.name = "Alice"; myPerson.age = 25;
-
Enum
Enum
是枚举类型,可以通过以下语法来定义
enum Status { Unknown, Start, End, Pause } 并通过以下语法来进行更新与初始化 // 实例化枚举类型 Status public status; // 更新枚举值 function pause() public { status = Status.Pause; } // 初始化枚举值 function reset() public { delete status; }
-
映射类型(mapping):
Copy Code mapping(address => uint256) balances; balances[msg.sender] = 100;
关键字
-
"view" 关键字
用于标识一个函数不会修改合约的状态,即它只能读取数据而不能修改数据。这意味着在调用视图函数时,不会产生任何交易费用,并且不会改变合约的状态。例如:
function getName() public view returns (string memory) {return name; }
-
"pure" 关键字
用于标识一个函数既不会修改合约的状态,也不会读取或访问合约的存储数据。这种函数通常用于执行纯粹的计算操作,不涉及存储或外部调用。例如:
function add(uint256 a, uint256 b) public pure returns (uint256) {return ab; }
-
"public":
- 将函数或变量声明为公共的,可以被合约内部和外部访问。例如:
string public name = "Alice";
-
"private":
- 将函数或变量声明为私有的,只能在合约内部访问。例如:
uint256 private balance = 100;
-
"external":
将函数声明为外部函数,只能从合约外部调用。与 "public" 关键字不同的是,外部函数不能在合约内部直接调用,也不能被合约继承。例如:
Copy Code function transfer(address recipient, uint256 amount) external { // transfer logic here }
-
"internal":
将函数声明为内部函数,只能在合约内部或合约继承链上的合约中访问。例如:
function withdraw(uint256 amount) internal { // withdraw logic here }
-
"payable":
将函数声明为可以接收以太、币的函数,在函数中可以接收以太币并进行转账操作。例如:
function purchase() public payable { // purchase logic here }
函数
-
函数定义和调用:
Copy Code function sayHello(string memory name) public {// 函数逻辑// ... } sayHello("Alice");
-
函数可见性(public、private等):
Copy Code function myFunction() public {// 可公开访问的函数 } function privateFunction() private {// 私有函数,只能在合约内部调用 }
-
函数修饰器(modifier):
-
Copy Code modifier onlyOwner() { require(msg.sender == owner, "Only owner can call this function.");_; } function changeName(string memory newName) public onlyOwner {// 只有合约所有者可以调用该函数 name = newName; }
-
-
函数返回值:
Copy Code function add(uint256 a, uint256 b) public pure returns (uint256) {return a + b; } uint256 result = add(2, 3); // result = 5
数组
-
数组定义和初始化:
uint256[] myArray; // 空数组uint256[] myArray2 = new uint256[](3); // 长度为3的动态数组uint256[] myArray3 = [1, 2, 3]; // 直接初始化数组
-
数组长度和访问元素:
length
属性获取数组长度,并通过索引访问数组元素。 示例:
uint256[] myArray = [1, 2, 3]; uint256 length = myArray.length; // length = 3uint256 secondElement = myArray[1]; // secondElement = 2
-
动态数组和静态数组:
uint256[] dynamicArray; uint256[3] staticArray;
-
多维数组:
uint256[][] twoDimensionalArray; uint256[2][3] twoByThreeArray;
结构体
-
结构体定义和初始化:
struct Person { string name; uint age; } Person myPerson; myPerson.name = "Alice"; myPerson.age = 25;
-
结构体成员访问:
Person myPerson; myPerson.name = "Alice"; string memory personName = myPerson.name; // personName = "Alice"
-
结构体作为函数参数和返回值:
struct Person { string name; uint age; } function getPerson() public view returns (Person memory) { Person memory person; person.name = "Alice"; person.age = 25; return person; } Person memory myPerson = getPerson();
-
结构体数组:
-
struct Person { string name; uint age; } Person[] people; Person memory person1; person1.name = "Alice"; person1.age = 25; people.push(person1); Person memory person2; person2.name = "Bob"; person2.age = 30; people.push(person2);
-
储存方式
当在Solidity中声明变量时,可以使用不同的存储位置修饰符来指定变量应该存储在何处。共有三种存储位置:memory
、storage
和calldata
。其中,memory
和storage
是最常用的两种。
-
memory
:- 可以使用
memory
关键字将变量声明为memory
类型,也可以在函数参数中使用memory
。 示例:
memory
是一种临时存储位置,用于存储函数执行期间的临时数据。它适用于需要在函数内部进行临时计算或处理大量数据的情况。在函数执行完毕后,memory
中的数据会被清空。
function processArray(uint256 memory myArray) public {// 在 memory 中处理数组// ... }
-
storage
:- 可以直接在函数内部使用
storage
类型的变量,无需显式声明。 示例:
storage
是一种永久性存储位置,用于在合约的存储空间中存储和访问数据。它适用于需要在不同函数之间共享和保留数据的情况。在合约中声明的state variables
默认是storage
类型。
-
calldata
:- 在函数参数中,默认情况下,所有的非
mapping
类型参数都被视为calldata
类型。 示例:
calldata
是一种特殊的存储位置,用于存储函数参数和外部函数调用的输入数据。calldata
中的数据是只读的,不能被修改。此存储位置适用于函数参数传递和与外部合约交互。
function processInputData(uint256 calldata inputData) external {// 处理输入数据 } function callExternalContract(address externalContract, bytes calldata data) external { (bool success, ) = externalContract.call(data); require(success, "External contract call failed."); }
总结一下:
memory
用于临时存储函数执行期间的数据,适用于临时计算或处理大量数据的情况;storage
用于永久性存储变量,适用于在不同函数之间共享和保留数据的情况;calldata
用于存储函数参数和外部函数调用的输入数据,是只读的。
-
堆栈(Stack):
- 通常情况下,开发者不需要手动操作堆栈,Solidity 编译器会自动进行堆栈管理。但在一些需要优化调用栈空间的场景下,可能需要手动控制函数调用堆栈的大小和顺序。 示例:
function foo(uint256 x, uint256 y) public pure returns (uint256) { uint256 result = bar(x) + y;return result; } function bar(uint256 x) public pure returns (uint256) { uint256 result = x * 2;return result; }
-
日志(Logs):
- 日志由合约的事件(event)和事件参数组成,可以通过
emit
关键字触发。日志数据会被写入到交易的日志中,不会影响合约状态,但会占用一定的 Gas。 示例:
event Transfer(address indexed from, address indexed to, uint256 value); function transfer(address _to, uint256 _value) public { require(balances[msg.sender] >= _value, "Insufficient balance."); balances[msg.sender] -= _value; balances[_to] += _value; emit Transfer(msg.sender, _to, _value); }
-
Code
Solidity 中的一种特殊的数据类型,用于存储合约的字节码。
在 Solidity 中,合约代码(也称为字节码)可以通过 type
关键字将其存储在 bytes
或 bytescode
类型的变量中。这样可以在合约内部或外部对代码进行处理和分析。
以下是一个简单的示例,展示了如何将合约代码存储在 bytes
类型的变量中:
pragma solidity ^0.8.0; contract CodeExample { bytes public contractCode; constructor() { // 将合约代码存储在 contractCode 变量中 contractCode = type(CodeExample).creationCode; } }
Mappings
-
映射定义和初始化:
mapping(address => uint256) balances;
-
映射的键值对:
mapping(address => uint256) balances; address account = 0xAbcdef; balances[account] = 100;
-
映射的访问和修改:
mapping(address => uint256) balances; address account = 0xAbcdef; uint256 balance = balances[account]; // 获取映射值 balances[account] = 200; // 修改映射值
-
映射的迭代:
- Solidity 中的映射不支持直接迭代,需要结合其他数据结构或编写逻辑来实现迭代功能。
在 Solidity 中,映射(Mapping)是一种键值对的数据结构,类似于字典或哈希表。每个键对应一个唯一的值。但是,Solidity 中的映射并不支持直接迭代,这意味着你无法像遍历数组或列表那样直接对映射进行循环迭代。
到此这篇Solidity 智能合约开发 - 基础:基础语法 基础数据类型、以及用法和示例的文章就介绍到这了,更多相关内容请继续浏览下面的相关推荐文章,希望大家都能在编程的领域有一番成就!版权声明:
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若内容造成侵权、违法违规、事实不符,请将相关资料发送至xkadmin@xkablog.com进行投诉反馈,一经查实,立即处理!
转载请注明出处,原文链接:https://www.xkablog.com/qkl-kf/7525.html