当前位置:   article > 正文

Solidity 智能合约基础入门(第一章)_智能合约solidity

智能合约solidity

目录

Solidity简介:

一、值类型 

1.整型

2.布尔型 

3.地址类型 

4.字节数组

5. 枚举 enum

 二、引用类型

1.数组array

2.结构体struct

3.映射Mapping

 三、变量与常量

1.变量

状态变量(state)​

局部变量(local )​

 全局变量(global)​

2.常量

总结


Solidity简介:

Solidity是一种面向智能合约的编程语言,用于开发以太坊区块链上的去中心化应用(DApps)。它是以太坊平台的官方语言,并且在其他一些区块链平台中也被广泛采用。

Solidity语言结合了C++、JavaScript和Python的特性,其语法类似于这些语言,使开发者更容易上手。使用Solidity,开发者可以定义和执行智能合约,这些合约定义了在区块链上运行的一系列代码和规则。智能合约用于管理和控制区块链上的资产和交互行为。

Solidity支持各种数据类型,包括整数、浮点数、字符串、布尔型以及自定义类型等。它提供了丰富的编程功能,例如条件语句、循环语句、函数、事件和异常处理,以便开发者能够灵活地设计和实现智能合约的逻辑。

通过Solidity,开发者可以创建代币、实现多方资金转移、创建投票系统、编写游戏逻辑等。智能合约的代码由Solidity编写,并且通过以太坊虚拟机(EVM)执行。开发者可以使用Solidity编译器将代码编译为EVM可执行的字节码,然后将其部署到以太坊区块链上。

尽管Solidity是一种强大的工具,但在开发过程中也需谨慎对待。由于智能合约在区块链上是不可更改的,因此一旦合约部署,它将永久保留。这意味着任何错误或漏洞可能导致无法修复的损失。因此,开发者需要进行充分的测试和审查,以确保智能合约的安全性和正确性。


Hello World:

在学习Solidity 之前先分享一个在线开发工具(Remix)的网址:  http://remix.zhiguxingtu.com/

我们将在Remix中编写智能合约

下面我们从一个简单的Hello World合约了解Solidity智能合约:

  1. // SPDX-License-Identifier: MIT(许可证)
  2. pragma solidity ^0.8.4;//编译器版本
  3. //合约
  4. contract Hello{
  5. //变量
  6. string name;
  7. //事件
  8. event Rename(string newName);
  9. //构造函数
  10. constructor(string memory _name){
  11. name = _name;
  12. }
  13. //函数
  14. function setName(string memory _name)public{
  15. name = _name;
  16. //触发事件
  17. emit Rename(_name);
  18. }
  19. function getName()public view returns(string memory){
  20. return name;
  21. }
  22. }

、值类型 

1.整型

int/uint(零值:0) 可加数字表示精度:8~256(为8的倍数)

int是有符号整型,可以是正整数也可以是负整数

uint 是无符号整型,只能是正整数

solidity中没有浮点类型,通过位数精度来表示浮点类型

  1. // 整型
  2. int public _int = -1; // 整数,包括负数
  3. uint public _uint = 1; // 正整数
  4. uint256 public _number = 20220330; // 256位正整数

常用的整型运算符包括:

  • 比较运算符(返回布尔值): <=, <, ==, !=, >=, >
  • 算数运算符: +, -, 一元运算 -, +, *, /, %(取余),**(幂)

2.布尔型 

布尔类型:取值为truefalse(零值:false):

  1. //布尔值
  2. bool isAlive=ture;

布尔值的运算符,包括:

  • ! (逻辑非)
  • && (逻辑与, "and" )
  • || (逻辑或, "or" )
  • == (等于)
  • != (不等于)
  1. // 布尔运算
  2. bool public _bool1 = !_bool; //取非
  3. bool public _bool2 = _bool && _bool1; //与
  4. bool public _bool3 = _bool || _bool1; //或
  5. bool public _bool4 = _bool == _bool1; //相等
  6. bool public _bool5 = _bool != _bool1; //不相等

字节数组 bytes 可加字节数组大小(1~32)

3.地址类型 

  1. address:最常用的地址类型是address,表示以太坊账户的地址。一个address类型的变量存储了一个20字节大小的地址,它可以是一个普通账户地址,也可以是一个合约地址。可以使用address类型来存储和操作账户的地址。

  2. address payable:address payableaddress类型的一个特殊子类型,用于表示可以接收以太币的地址。除了address具有的功能外,address payable还提供了一些特殊方法,如transfersend,用于发送以太币。

    1. // 地址
    2. address public owner = 0x5B38Da6a701c568545dCfcB03FcB875f56beddC4;
    3. address payable public owner1 = payable(_address);//可以转账、查余额

4.字节数组

字节数组bytes分两种:

定长:bytebytes8bytes32(消耗gas比较少 

不定长:定长的属于数值类型,不定长的是引用类型(下面章节会提起)

  1. // 固定长度的字节数组
  2. bytes32 public _byte32 = "MiniSolidity";
  3. bytes1 public _byte = _byte32[0];

MiniSolidity变量以字节的方式存储进变量_byte32,转换成16进制为:0x4d696e69536f6c69646974790000000000000000000000000000000000000000

_byte变量存储_byte32的第一个字节,为0x4d

5. 枚举 enum

枚举类型来定义一组预定义的常量,用于表示一组固定的取值,这些取值在定义时被明确列出,且不能更改。

  1. // 定义一个名称为State的枚举类型
  2. enum State {
  3. Created,
  4. InProgress,
  5. Completed
  6. }
  7. // 声明一个状态变量,类型为State枚举
  8. State public currentState;
  9. // 在合约中使用枚举类型
  10. function updateState(State newState) public {
  11. currentState = newState;
  12. }

 、引用类型

1.数组array

数组(array)在solidity语言中,用来存储一组数据(整数,字节,地址等等)。数组分为固定长度数组和可变长度数组两种:

  • 固定长度数组:固定长度数组在声明时指定了数组的长度,长度不可改变。 用T[k]的格式声明,其中T是元素的类型,k是长度,例如:
  1. // 固定长度 Array
  2. uint256[5] array1;
  3. bytes1[5] array2;
  4. address[100] array3;

例如:uint256[5]    表示一个包含5个无符号256位整数的固定长度数组。

  • 动态长度数组:动态长度数组是长度可以在运行时进行更改的数组。通过使用关键字storagememory声明数组的存储位置。用T[]的格式声明,其中T是元素的类型,例如(bytes比较特殊,是数组,但是不用加[]):
  1. // 可变长度 Array
  2. uint256[] array4;
  3. bytes1[] array5;
  4. address[] array6;
  5. bytes array7;

例如: uint256[]表示一个可变长度的无符号256位整数数组。

索引:

使用数组时,可以使用索引访问和操作数组中的元素。数组的索引从0开始,表示数组中的第一个元素,依次递增。可以使用length属性获取数组的长度。

常用数组操作: 

  • push() 添加元素:使用push方法将元素添加到动态长度数组的末尾。
  • 访问元素:使用索引来访问数组中的特定元素。
  • 修改元素:使用索引和赋值操作符(=)来修改数组中的元素。
  • 删除元素:Solidity中的数组无法直接删除单个元素,但可以通过重赋值空值或使用delete关键字将元素设置为默认值来删除元素。
    1. pragma solidity ^0.8.0;
    2. contract ArrayExample {
    3. uint256[] public dynamicArray;
    4. constructor() {
    5. // 添加元素到数组
    6. dynamicArray.push(10);
    7. dynamicArray.push(20);
    8. dynamicArray.push(30);
    9. // 修改数组元素
    10. dynamicArray[1] = 25;
    11. // 删除数组元素
    12. delete dynamicArray[2];
    13. }
    14. function getArrayLength() public view returns (uint256) {
    15. // 返回数组的长度
    16. return dynamicArray.length;
    17. }
    18. function getElement(uint256 _index) public view returns (uint256) {
    19. // 返回数组中指定索引位置的元素
    20. return dynamicArray[_index];
    21. }
    22. }

2.结构体struct

结构体(Struct)是一种自定义的数据结构,允许定义一个包含多个不同类型的字段的复合数据类型。

  1. // 结构体
  2. struct Student{
  3. uint256 id;
  4. uint256 score;
  5. }

    Student student; // 初始一个student结构体

给结构体赋值的两种方法:

  1. // 给结构体赋值
  2. // 方法1:在函数中创建一个storage的struct引用
  3. function initStudent1() external{
  4. Student storage _student = student; // assign a copy of student
  5. _student.id = 11;
  6. _student.score = 100;
  7. }
  1. // 方法2:直接引用状态变量的struct
  2. function initStudent2() external{
  3. student.id = 1;
  4. student.score = 80;
  5. }

3.映射Mapping

映射(Mapping)是一种键值对存储结构,类似于其他编程语言中的哈希表或字典。

映射允许您将一个键(Key)与一个值(Value)相关联,以便快速访问、存储和更新数据。

映射的声明语法如下:

    mapping(KeyType => ValueType) public myMapping;

 KeyType 是键的数据类型,ValueType 是值的数据类型。可以根据需要选择不同的数据类型,例如 addressstringuint256 等等。例如:

  1. mapping(uint => address) public idToAddress; // id映射到地址
  2. mapping(address => address) public swapPair; // 币对的映射,地址到地址

映射类型常用操作:

  • 添加/更新键值对:使用映射的索引操作符([])可以添加或更新键值对。例如:
myMapping[key] = value;

这会将键 key 的值设置为 value

  • 读取值:使用映射的索引操作符可以根据给定的键读取相应的值。如果没有为某个键设置值,那么读取操作将返回该值类型的默认值。例如:
ValueType myValue = myMapping[key];

这会将键 key 的值存储在变量 myValue 中。

  • 映射长度:通过使用内置的 length 属性,您可以获取映射中键值对的数量。映射的长度指的是存储在映射中的键值对数量。例如:
uint256 length = myMapping.length;

  • 检查键是否存在:您可以使用映射的键查找操作来检查某个键是否存在于映射中。
  1. if (myMapping[key] != 0) {
  2. // 键存在于映射中
  3. } else {
  4. // 键不存在于映射中
  5. }

 、变量与常量

1.变量

Solidity语言中的变量与大多数编程语言类似,从作用域的角度来看大概分为三种

  • 状态变量(state)

状态变量是数据存储在链上的变量,所有合约内函数都可以访问 ,gas消耗高。状态变量在合约内、函数外声明:

  1. contract Variables {
  2. uint public x = 1;
  3. uint public y;
  4. string public z;

我们可以在函数里更改状态变量的值:

  1. function foo() external{
  2. // 可以在函数里更改状态变量的值
  3. x = 5;
  4. y = 2;
  5. z = "0xAA";
  6. }

  • 局部变量(local )

局部变量是仅在函数执行过程中有效的变量,函数退出后,变量无效。局部变量的数据存储在内存里,不上链,gas低。局部变量在函数内声明:

  1. function bar() external pure returns(uint){
  2. uint xx = 1;
  3. uint yy = 3;
  4. uint zz = xx + yy;
  5. return(zz);
  6. }

  •  全局变量(global)

全局变量是全局范围工作的变量,都是solidity预留关键字。他们可以在函数内不声明直接使用:

  1. function global() external view returns(address, uint, bytes memory){
  2. address sender = msg.sender;
  3. uint blockNum = block.number;
  4. bytes memory data = msg.data;
  5. return(sender, blockNum, data);
  6. }

在上面例子里,我们使用了3个常用的全局变量:msg.senderblock.numbermsg.data,他们分别代表请求发起地址,当前区块高度,和请求数据。

常用的全局变量:

  • msg.sender:全局变量 msg.sender 是一个地址类型(address),它表示当前调用合约的用户(或合约)的地址。可以使用 msg.sender 来验证合约调用者的身份或执行一些权限检查。

  • msg.value:全局变量 msg.value 是一个整数类型(uint256),它表示当前交易发送的以太币(ether)数量。可以使用 msg.value 来处理合约接收的以太币,例如存款操作或付款验证。

  • block.timestamp:全局变量 block.timestamp 是一个整数类型(uint256),它表示当前块的时间戳。可以使用 block.timestamp 来记录合约交易发生的时间或执行时间相关的逻辑。

  • address(this)address(this) 用于获取当前合约的地址,可以在合约内部使用它来执行一些与合约地址相关的操作,如自毁(self-destruct)或传递合约地址给其他合约。

  • block.number:全局变量 block.number 是一个整数类型(uint256),它表示当前块的块号。可以使用 block.number 来跟踪块号或执行与块号相关的逻辑。

2.常量

在Solidity中,有两个关键字用于标识不可变的变量:constant 和 immutable

  • constant:该关键字用于声明常量值,这些值在编译时确定并且不能被修改。constant 可以用于函数定义、变量声明和参数声明。

    示例:

    1. function getNumber() public pure returns (uint256) {
    2. constant uint256 myNumber = 42;
    3. return myNumber;
    4. }

    在这个例子中,myNumber 是一个常量值,在编译时确定,并且不能在运行时修改或更新。

  • immutable:该关键字用于在合约的构造函数中声明不可变的状态变量。与 constant 不同,immutable 的值在合约部署时确定,并且在运行时保持不变。

    示例:

    1. contract MyContract {
    2. address public immutable owner;
    3. constructor() {
    4. owner = msg.sender;
    5. }
    6. }

    在这个例子中,owner 是一个不可变的状态变量,其值在合约部署时被初始化为合约的创建者的地址(msg.sender)。在构造函数执行时,owner 的值被设置为一次性的,之后无法再被修改。

小结

本章简单讲解值类型,引用类型,常量与变量,接下来我们将讲解函数,数据存储位置,错误,事件....等语法。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/你好赵伟/article/detail/277499
推荐阅读
相关标签
  

闽ICP备14008679号