3. Solidity 基础:helloworld - 编写合约

0 阅读6分钟

一、 编写第一个智能合约

智能合约也是由编程语言编写,学习编程语言需要掌握以下基本内容:

  1. 数据类型
  2. 控制语句
  3. 数据结构和算法

首先需要了解合约的声明方式和基本数据类型。

1.1 Solidity 声明合约

使用 contract 关键字声明合约: Solidity 中声明变量的格式:类型 变量名 = 值; 同样的,在同一个智能合约中,不允许变量名重复;


// SPDX-License-Identifier: MIT

pragma solidity ^0.8.30;
  


// 使用 contract 关键字声明合约

contract HelloWorld {

  bool boolVar = true; // bool 值

}

1.2 Solidity 的基本数据类型

Solidity 中包含 4中基本数据类型:

  • bool:布尔值
  • unit:无符号整数
  • byte:字节
  • address:地址

1.2.1 bool 布尔值

bool 布尔值:在 Solidity 中,布尔值和其他语言中不同,其他语言中的 非 0 值表示 true,0 表示 false。

这一招在 Solidity 中不可用。这是因为智能合约部署在区块链上,一旦出现问题无法删除,因此设计的更为严谨。


bool boolVar = true; // bool 值

bool boolVar2 = false; // bool 值

1.2.2 uint 无符号整数

uint 无符号整数 ,u 表示 unsigned ,int 表示 integer 整数。uint 表示所有正数; 格式:unit 后面可以接位数, uint8 或者 unit256

  1. unit8 能表示的是 (0-2^8-1) 的数字即 0-255,赋值小于0或者大于255的就会报错,uint8 varNum1 = 256 报错

  2. uint256 常用,这个数字很大;一般 uint 和 uint256 等价

uint uintVarNum2 = 2555555; // 可以,但是一般不建议省略256,推荐显式声明

// int 整形:整数,可以存储有符号的整数,例如负数。int 表示 int256

int intVar = -1;

1.2.3 byte 字节

一个 byte 式 8 个 bit,一般存放字符串。solidity 中最大可以声明 bytes32,不能写 超过 32 的 bytes

bytes32 varChar = 'hello world';

注意 solidity 中也包含 bytes 但它是数组,是 bytes8/32/64的数组,不是默认的 bytes8

solidity 中也有 string:某一种特殊的 bytes,自动分配空间的 bytes

string strVar = 'hello world';

思考:有了 uint256 还要 unit8 干啥?有了 string 还要 bytes 干啥? 答案:节约内存,提升效率;声明内存和位数的分配的内存不会超过声明的位数

1.2.4 address:地址

你的合约地址,注意 地址不用双引号

address addVar = 0x5B38Da6a701c568545dCfcB03FcB875f56beddC4;

区块链地址从 右边的 deploy 选项卡中 ACCOUNT 右边的小菜单中复制地址

image.png

二、 函数

2.1 函数的声明

语法: function 函数名 (入参) 标识符 view returns (string memory) { 函数体 }

  • 函数名:函数的名称,驼峰?

  • 入参:函数参数

  • 标识符:函数可以被调用的范围,描述当前合约、子合约、外部合约、外部账户四类可以访问的函数和变量,共有4个标识符:

    • internal:仅仅可以在合约内部和子合约调用
    • external:仅可以被外部合约和外部账户调用
    • public:内部合约、外部合约、子合约、外部账户均可
    • private:只能在当前合约内部调用

image.png

子合约:继承当前合约的合约 child contracts

外部合约和外部账户基本等同,允许外部合约的就允许外部账户,不允许的同理

  • view: 表示当前函数仅仅读取状态,不会修改状态,建议只读取的函数加上这个 vivew,编译器会对函数逻辑进行检查;
  • returns(string memory) 返回值声明,string 返回值类型,memory 表示的是返回值的存储状态
function sayHello () public view returns(string memory) {
    return strVar;
}

2.2 编写合的函数

contract HelloWorld {
    string strVar = "hello world";
    function sayHello () public view returns(string memory) {

        return strVar;
    
    }
}

三、 部署合约

部署这个合约,通过 remix 的左边 Deploy 选项卡完成。当然,部署之前你的合约需要经过编译且编译不能有错误。

3.1 本地部署步骤

  1. 选择一个 RemixVM shanghai
  2. 选择一个账户 ACCOUNT,将会从这个账户扣除手续费?
  3. VALUE 写 0
  4. CONTRACT 选择你要部署的合约
  5. 点击橘黄色按钮 Deploy

image.png

3.2 区块链控制台中会有状态等信息:

  1. status: 状态,mined 挖矿,本地部署不需要挖矿

  2. transaction hash: 交易哈希,通过交易 hash 可以通过区块链浏览器在主网上面找到本次交易

  3. block hash: block 的 hash,本次交易生成的 block 的hahs

  4. block number : 区块的数量,1 是个假的数字,取决于你部署了几次,真实的区块链上的这个数字很大

  5. 合约中应该有个构造函数,但是不写的话 solidiy 会默认帮大家创建一个,所以本质上 contract 关键字等同于 class 关键字?

3.3 测试你的智能合约函数

在 Deploy 选项卡完成部署之后,在下面的 Deployed Contracts 菜单下将会有的你的合约,展开菜单你会看到如下的图片:

image.png

这就会出现一个蓝色的按钮,按钮的文案和你的合约中的方法名字相同,点击它,它下面将会透出你的智能合约方法的返回值。

在图上的 Deploy 按钮上一直在提示你 evm version: shanghai。这表示你的 Deploy 时选择 EVM Version 是 shanghai。

此时如果你的 Compiler 里面的 EVM version 选择的不是 shanghai 是不可否以的。即便能够部署成功,调用方法时也会提示你这两个地方不兼容。

四、编辑合约

我们可以编写一个 setHelloWorld 的方法,修改合约的数据,注意这里是在学习函数的声明。

编写 set 函数,即你想修改合约中的变量,由两点需要注意:

  1. 修改后的值是外面传入的,因此你需要定义一个形参,形参:类型+存储方式+变量名
  2. 这个函数是否需要返回值,不需要就不用声明 returns
contract HelloWorld {
    string strVar = "hello world";
    
    function sayHello () public view returns(string memory) {

        return strVar

    }
    
    function setHelloWorld(string memory newString) public {

        strVar = newString;

    }
}

五、总结

本章我们学习了 Solidity 的基本数据类型、函数定义、编写合约、部署合约、编辑合约:

  1. 数据类型;
      1. bool:布尔值,注意,1 和 0 这种值在 Solidity 中不能表示布尔值,不存在自动的类型转换;
      1. uint:无符号整数,由 uint8 和 unit256,不写位数默认 uint 256;
      1. byte:字节,byte8、bype32,最大可以声明 32 位的 byte,一般用来表示字符串;而 bytes 这个表示数组;
      1. string:字符串类型
      1. address:地址类型,注意这个没有引号,不是字符串,是一种特殊的类型1
  2. 函数声明
  3. 编写合约
  4. 部署合约
  5. 编辑合约