web3学习笔记(二)

主要是学习solidity基础

web3学习笔记(二)

1.合约

Solidity 的代码都包裹在合约里面, 一份合约就是以太应币应用的基本模块, 所有的变量和函数都属于一份合约。

// 表示代码所使用的软件许可(license)
// SPDX-License-Identifier: MIT

// 表示使用的Solidity版本,这里`^0.8.21`表示的是不小于0.8.21版本
pragma solidity ^0.8.21;

// contract创建合约,并命名为`HelloWeb3`
contract HelloWeb3{
    // 声明了一个字符串,赋值为`Hello Web3!`
    string public _string = "Hello Web3!";
}

2.状态变量和整数

上一步,我们做了一个合约的外壳,下面学习怎么使用变量

状态变量是被永久地保存在合约中。也就是说它们被写入以太币区块链中,想象成写入一个数据库。

contract Example {
  // 这个无符号整数将会永久的被保存在区块链中
  // 定义了a的类型为uint,赋值100
  uint a = 100;
}

2.1.uint

uint 无符号数据类型, 指其值不能是负数

对于有符号的整数存在名为 int 的数据类型。

uint实际上是unint256的简写,所以我们后面也会用到unint8unint16等等。

3.数学运算

在 Solidity 中,数学运算很直观明了,与其它程序设计语言相同:

  • 加法: x + y
  • 减法: x - y,
  • 乘法: x * y
  • 除法: x / y
  • 取模 / 求余: x % y (例如, 13 % 53, 因为13除以5,余3)
  • 乘方: x**y
pragma solidity ^0.4.19;

contract HelloWeb3 {
    uint a = 16;
    uint b = 10 ** a;

}

4.结构体

如果需要更加复杂的数据类型,就需要使用到结构体,个人感觉类似JS中或者其他语言中的类和对象。

struct Person {
    uint age;
    string name;
}

5.数组

跟其他语言一样,solidity也有数组,不过分两种:静态数组和动态数组。

// 固定长度为2,类型为uint
uint[2] array1;
// 固定长度为5,类型为string
string[5] array2;
// 动态数组,可以动态添加元素
uint[] array3;
// 甚至还有机构体数组
Person[] array4; 

5.1.公共数组

可以使用public修饰数组,其他合约可以从这个数组读取数据,但是不能写入数据。

struct Person {
    uint age;
    string name;
}
Person[] public people;

6.定义函数

// 这里变量用了_做开头,但这个不是语法要求,是一种习惯
function foo(string _name, uint _age){

}

7.使用结构体和数组

struct Person {
    uint age;
    string name;
}
Person[] public peopleList;
// 创建一个新的Person:
Person person1 = Person(172, "zs");

// 将新创建的person1添加进people数组:
peopleList.push(person1);

当然也可以把创建和push合为一步

peopleList.push(Person(172,"zs"))

结合一下上面写的函数,定义一个函数,函数里面创造了一个People,然后在peopleList的尾部加入这个People

function foo(string _name, uint _age){
    // 创建的People的参数由函数传入
    peopleList.push(Person(_age,_name))
}

8.私有/公共函数

在合约中定义的函数默认为public的,也就是公共的。这就意味着其他的合约也可以调用这个函数,这样是不安全的。所以要有一个习惯,这个函数确定是公共的才把他设置为public

公共的对立面就是私有,那么如何定义一个私有的函数呢?

uint[] numbers;

// 在函数名字后面使用private关键字,就能把他设置为私有
// 私有函数的名字用_开头,这是一种习惯
function _addToArray(uint _number) private {
  numbers.push(_number);
}

9.函数的更多属性

9.1.返回值

// 函数如果有返回值,有语法规定
// returns 定义了返回值的类型为 string
string str = "hello";
function sayHello() public returns (string) {
    return str;
}

9.2函数的修饰符

上面的sayHello没有改变任何状态,他只是返回了str,这种情况下我们可以把函数定义为view,这个意思就是他只能读取状态而不能改变状态。

function sayHello() public view returns (string) {
    return str;
}

此外,还有另一个修饰符pure,这个表示函数没有读取也没有修改状态。

function _multiply(uint a, uint b) private pure returns (uint) {
    return a * b;
}

10.Keccak256 和 类型转换

10.1.Keccak256

// 有一个方法是把一个字符串转换为一个256位的16进制数字
keccak256("aaab"); 
//6e91ec6b618bb462a4a6ee5aa2cb0e9cf30f7a052bb467b0ba58b8748c00d2e5

不过需要注意的是,在区块链中安全地产生一个随机数是很困难的事情,这个方法是不安全的。

10.2.类型转换

uint8 a = 5;
uint b = 6;
// 这样写会报错,因为a * b返回的是uint。
// 这个类似TS中的类型报错一样
uint8 c = a * b;
// 转换一下b的类型,这样就可以了
uint8 c = a * uint8(b);

11.事件

事件是合约和区块链通讯的一种机制。前端要监听某些事件然后做出处理。

// 使用event建立事件
event AddEvent(uint x, uint y, uint res);

function add(uint _x, uint _y) public {
    uint res = _x + _y;
    // 触发事件
    AddEvent(_x, _y, res);
    return res;
}
// 然后前端就可以监听这个事情,做出一些处理
YourContract.AddEvent(function(err,res)){
                      
}
kucha
“ 大冬天的非常冷,打工人很辛苦,需要一杯奶茶暖暖肚子。 ”
 喜欢文章
头像