基于以太坊的智能合约开发Solidity(基础篇)

参考教程:基于以太坊的智能合约开发教程【Solidity】_哔哩哔哩_bilibili

1、第一个程序——Helloworld:

//声明版本号(程序中的版本号要和编译器版本号一致)
pragma solidity ^0.5.17;
//合约
contract HelloWorld
{
    //合约属性变量,也叫状态变量(定义方式:数据类型 变量名 = 数据)
    string myName = "helloworld";  //在solidity中,用单引号包含字符串也是可以的
    //合约中的方法(注意语法顺序,其中此处“view”代表方法只读,不会消耗燃料;“returns”后的是返回值类型)
    function getName() public view returns(string)
    {
        return myName;  //返回值类型要与returns声明的严格相同
    }
    //可以修改属性变量的值,但是会消耗燃料
    function changeName(string _newName) public
    {
        myName = _newName;
    }
    //“pure”代表不能读取也不能改变状态变量
    function pureName(string _name) public pure returns(string)
    {
        return _name;
    }
    /*
    用constant、view、pure修饰function分别表示:
    constant:只能读取不可改变状态变量(就是contract中定义的变量)
    view:只能读取不可改变状态变量,和constant一样
    pure:不能读取也不能改变状态变量
    */
    
}

(1)程序编译完成后,需要在虚拟机上运行,将合约部署好后便可执行刚刚编写的函数。(注意,合约一旦部署,就会永久存在于区块链上,且不可篡改,不过可以销毁)

(2)执行完成后,可以得到以下交易信息,下图所示的就是生成的区块信息:

(3)代码相关:

①属性变量定义方式:数据类型 变量名 = 数据(变量命名规则和c语言相同)

②一般用双引号包含一串字符串,不过在solidity中,用单引号包含字符串也是可以的。

③Solidity值类型:(在Solidity中,一旦一个变量被指定了某个数据类型,如果不经过强制转换,那么它就永远是这个数据类型,在调用函数时如果形参和实参类型不同将会报错

• 布尔类型(bool):可能的取值为字符常量值true或false

• 整型(int/uint):分别表示有符号和无符号的不同位数的整型变量,支持关键字uint8到 uint256(无符号,从8位到256位)以及int8到int256,以8位为步长递增

• 定长浮点型(fixed / ufixed):表示各种大小的有符号和无符号的定长浮点型,在关键字ufixedMxN和fixedMxN中,M表示该类型占用的位数,N表示可用的小数位数

• 地址(address):存储一个 20 字节的值(以太坊地址大小)

• 定长字节数组:关键字有 bytes1,bytes2,bytes3,...,bytes32

• 枚举(enum):一种用户可以定义类型的方法,与C语言类似,默认从0开始递增,一般用来模拟合约的状态

• 函数(function):一种表示函数的类型

④solidity函数的标准形式:

function functionName() {private|internal|external|public} [pure|constant|view|payable] [returns()]

在合约中定义函数要以function开头,后接函数名称,括号内则是传入函数中的参数(每一个参数的类型以及名称要依次写出,没有参数则不写),“returns”后接该函数返回值的类型(无返回值则可以不写returns)。

⑤用constant、view、pure修饰function分别表示:

    constant:只能读取、不可改变状态变量(就是contract中定义的变量)

    view:只能读取、不可改变状态变量,和constant一样,不消耗燃料

    pure:不能读取也不能改变状态变量,一个固定的输入只能有一个固定的输出

[1]以下情况被认为是修改状态:修改状态变量(函数体外部、合约内部创建的变量就是状态变量)、产生事件、创建其它合约、使用selfdestruct、通过调用发送以太币、调用任何没有标记为view或者pure的函数、使用低级调用、使用包含特定操作码的内联汇编。

[2]以下被认为是从状态中进行读取:读取状态变量、访问this.balance或者 <address>.balance、访问block,tx,msg中任意成员(除msg.sig和msg.data之外)、调用任何未标记为pure的函数、使用包含某些操作码的内联汇编。

⑥用external、public、internal、private修饰function分别表示:

    external:外部函数作为合约接口的一部分,意味着可以从其他合约和交易中调用,  一个外部函数f不能从内部调用(即f不起作用,但this.f()可以,这些后续都会详细介绍),当收到大量数据的时候,外部函数有时候会更有效率。

    public:public函数是合约接口的一部分,可以在内部或通过消息调用对于public状态变量,会自动生成一个getter函数

    internal:这些函数和状态变量只能是内部访问(即从当前合约内部或从它派生的合约 访问),不使用this调用。

    private:private函数和状态变量仅在当前定义它们的合约中使用,并且不能被派生合 约使用。

⑦solidity中函数可以递归调用。

⑧solidity可以使用import导入其它源文件:

[1]import "filename";  //从“filename”中导入所有的全局符号到当前全局作用域中

[2]import * as symbolName from "filename";  //创建一个新的全局符号symbolName,其成员均来自“filename”中的全局符号

[3]import {symbol1 as alias, symbol2} from "filename";  //创建新的全局符号alias和symbol2,分别从"filename"引用symbol1和symbol2

[4]import "filename" as symbolName;  //这条语句等同于import * as symbolName from "filename";

2、语法——逻辑运算:

//声明版本号(程序中的版本号要和编译器版本号一致)
pragma solidity ^0.5.17;
//合约
contract BoolTest
{
    
    bool a;  //创建布尔类型变量时如不初始化,默认赋为false
    
    function geta() public returns(bool)
    {
        return a;
    }

    function getnota() public returns(bool)
    {
        return !a;  //a当前为false,经过非运算后会返回true
    }

    int c = 1;
    int d = 2;
    
    //(这部分与c语言几乎完全相同,就不列举所有情形了)
    function cdequal() public returns(bool)
    {
        return c==d;  //c与d当前不相等,c==d不成立,会返回false
    }
    
    function cdequalAnd() public returns(bool)
    {
        return c==d && true;  //c==d返回false,false与true进行与运算,结果为false
    }
    
    function cdequalOr() public returns(bool)
    {
        return c==d || true;  //c==d返回false,false与true进行或运算,结果为true
    }
    
    function cdnotequalAnd() public returns(bool)
    {
        return c!=d && true;  //c与d当前不相等,c!=d成立,返回true,true与true进行或运算,结果为true
    }
}

3、语法——整型与算术运算:

//声明版本号(程序中的版本号要和编译器版本号一致)
pragma solidity ^0.5.17;
//合约
contract MathTest
{
    //加(a与b为传入方法中的参数,下同理)
    function add(uint a,uint b) public returns(uint)
    {
        return a+b;
    }
    //减
    function minus(uint a,uint b) public returns(uint)
    {
        return a-b;
    }
    //乘
    function multiply(uint a,uint b) public returns(uint)
    {
        return a*b;
    }
    //除
    function divide(uint a,uint b) public returns(uint)
    {
        return a/b;
    }
    //取余运算
    function mod(uint a,uint b) public returns(uint)
    {
        return a%b;
    }
    //幂运算
    function square(uint a,uint b) public returns(uint)
    {
        return a**b;
    }
}

4、语法——位运算:

//声明版本号(程序中的版本号要和编译器版本号一致)
pragma solidity ^0.5.17;
//合约
contract MathTest
{
    //uint8表示大小为8个位的无符号整型
    uint8 a = 3;  //二进制表示为00000011
    uint8 b = 4;  //二进制表示为00000100

    //按位与(该部分和c语言也几乎完全相同)
    function bitwiseAnd() public returns(uint8)
    {
        return a&b;
    }
    //按位或
    function bitwiseOr() public returns(uint8)
    {
        return a|b;
    }
    //按位取反
    function tilde() public returns(uint8)
    {
        return ~a;
    }
    //按位异或
    function caret() public returns(uint8)
    {
        return a^b;
    }
    //左移(左移运算符后接左移的位数)
    function leftShift() public returns(uint8)
    {
        return a<<1;
    }
    //右移(右移运算符后接右移的位数)
    function rightShift() public returns(uint8)
    {
        return a>>1;
    }
}

(图源:https://blog.csdn.net/aiwaston/article/details/113665723)

5、语法——复合运算:

//声明版本号(程序中的版本号要和编译器版本号一致)
pragma solidity ^0.5.17;
//合约
contract MathTest
{
    uint a = 1;
    //该语法也和c语言基本完全相同
    //输出a
    function add1() public returns(uint)
    {
        return a++;  //执行完该语句后a的值会加1
    }
    //输出a+1
    function add2() public returns(uint)
    {
        return ++a;  //执行该语句前a的值会加1,然后再执行该语句
    }
    //输出a
    function sub1() public returns(uint)
    {
        return a--;  //执行完该语句后a的值会减1
    }
    //输出a-1
    function sub2() public returns(uint)
    {
        return --a;  //执行该语句前a的值会减1,然后再执行该语句
    }
}

6、现象——整型溢出:

//声明版本号(程序中的版本号要和编译器版本号一致)
pragma solidity ^0.5.17;
//合约
contract MathTest
{
    //这部分也与c语言几乎完全相同
    function flow() view public returns(uint8)
    {
        uint8 mm  = 255;  //二进制为11111111
        mm++;
        return mm;  //mm只有8位,但是对于mm,再加1会得到100000000,只能取前8位,于是返回0而不是256
    }
    
    function flow2() view public returns(uint256)
    {
        uint8 mm  = 255;
        mm++;
        return mm;  //即使返回值声明有256位,但是在“mm++”这一步mm就被修改为0,所以返回的还是0
    }
    
     function flow3() view public returns(uint)
     {
        uint mm  = 255;  //这次没对mm的位数进行限制,它可以装下100000000
        mm++;
        return mm;
    }

    function flow4() view public returns(uint8){
        uint8 nn = 0;
        nn--;
        return nn;  //对00000000做减法,会先给“第九位”添1(要明确nn的位数),那么就会得到结果11111111,转换成十进制就是255(对于有符号数,就涉及到了补码的运算,同理,先转换成补码按此规律运算,再转换回十进制)
    }
}

7、现象——非法运算:

//声明版本号(程序中的版本号要和编译器版本号一致)
pragma solidity ^0.5.17;
//合约
contract MathTest
{
    function errorTest() view public returns(int)
    {
        int a = 2;
        int b = 3;
        return a/b;  //既然声明了返回值为整型,那么就不可能得到小数
        //不过solidity允许整型运算的过程中存在小数,只是结果不能接纳小数,比如2/5-2/5
        //solidity会将表达式计算出结果后再按照一定的规则(比如整形溢出等)进行处理,比如2**99-2**99+1
    }
    
    function errorTest2() view public returns(int)
    {
        int a = 2;
        int b = 0;
        return a/b;  //0不能做除数,这个方法甚至不能成功编译
    }

    function errorTest3() view public returns(int)
    {
        int a = -1;
        int b = 0;
        return b >> a;  //位移运算符不接受负数
    }
    
}

8、语法——固定长度字节数组:

//声明版本号(程序中的版本号要和编译器版本号一致)
pragma solidity ^0.5.17;
//合约
contract ByteArray
{
    bytes1 public num1 = 0x7a;  //1个字节长度的变量
    
    bytes2 public num2 = 0x7a68;  //2个字节长度的变量
    
    bytes12 public num3 = 0x7a68656e676a69616e78756e;  //12个字节长度的变量
}

(1)在solidity中,直接用public声明成员变量,编译部署后,会生成一个默认的get方法,通过该方法可以直接查看这个成员属性,而不需要通过自拟函数返回这个成员属性。

(2)字节数组同样支持位运算以及逻辑运算。

(3)固定长度字节数组不可以仅仅对某个字段进行更改(可以仅对某个字段进行读取,如下表所示),要么就直接对其整体重新赋值

名称

num3[0]

num3[1]

num3[2]

num3[3]

num3[4]

num3[5]

num3[6]

num3[7]

num3[8]

num3[9]

num3[10]

num3[11]

内容

0x7a

0x68

0x65

0x6e

0x67

0x6a

0x69

0x61

0x6e

0x78

0x75

0x6e

(4)定长字节数组的关键字有bytes1,bytes2,bytes3,...,bytes32。

(5)不管是定长数组还是动态长度数组,都不能越界访问,否则会报错。

9、语法——动态长度字节数组:

//声明版本号(程序中的版本号要和编译器版本号一致)
pragma solidity ^0.5.17;
//合约
contract DynamicByteArray
{
    
    bytes public name = new bytes(2);  //为动态字节数组开辟2个字节的空间
    
    function initName() public
    {
        name[0] = 0x7a;  //对动态长度字节数组进行初始化
        name[1] = 0x68;
    }
    
    function getLength() view public returns(uint)
    {
        return name.length;  //8个位(一个字节)为一个长度单位
    }
    
    function changeName() public
    {
        name[0] = 0x88;  //可以对某一字段进行修改
    }
    
    function changeLength() public
    {
        name.length = 5;  //可以修改数组的长度,不过修改的同时会将数组的内容全部置为0
    }

    function pushTest() public
    {
        name.push(0x99);  //可以在数组末尾追加字节元素,同时增加数组的长度
    }
}

(1)动态长度字节数组可以仅对某个字段进行更改

(2)可以通过修改动态长度数组的length属性修改动态长度数组的长度,不过修改的同时会将数组的内容全部置为0。

(3)动态长度数组有push方法,使用该方法可以在数组末尾追加指定的字节元素,同时增加数组的长度。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/235487.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

一些AG10K FPGA 调试的建议-Douglas

PLL AGM FPGA 在配置成功时&#xff0c;PLL 已经完成锁定&#xff0c;lock 信号已经变高&#xff1b;如果原设计中用 lock 信号输出实现系统 reset 的复位功能&#xff0c;就不能正确完成上电复位&#xff1b;同时&#xff0c;为了保证 PLL 相移的稳定&#xff0c;我们需要在 P…

项目文章(ChIP-seq)|Plant Physiol组蛋白H3K4甲基转移酶DcATX1促进乙烯诱导康乃馨花瓣衰老

发表单位&#xff1a;华中农业大学 期 刊 &#xff1a;Plant Physiology&#xff08;IF:7.4&#xff09; 发表日期&#xff1a;2023年5月2日 2023年5月2日华中农业大学的张帆教授研究团队在期刊Plant Physiology&#xff08;IF:7.4&#xff09;发表了题为“Histone H3K…

【软考】信息系统项目管理师论文方向猜想

报喜不报忧&#xff0c;每天都在为鸡零狗碎推诿扯皮&#xff0c;属实是有辱师门。 通过软考&#xff0c;目前算是真正有意义的事情。 虽然都说高项的论文是个玄学&#xff0c;但是道听途说了一些通关感想还是蛮有启发的。 文件要求 参考了一份广西省高级工程师评审的文件&am…

磁学单位SI制和CGS制的转换

电磁学领域中除了使用一般的SI国际制单位外&#xff0c;还会使用CGS高斯制单位&#xff0c;这对于接触磁性材料的朋友们来说&#xff0c;有时就需要做单位的转换&#xff0c;而这两种单位制的转换计算非常复杂。为了方便大家使用&#xff0c;我们系统地总结了一下电磁学中的单位…

python用turtle画樱花飘落,python代码画樱花代码

这篇文章主要介绍了python用turtle画樱花飘落&#xff0c;具有一定借鉴价值&#xff0c;需要的朋友可以参考下。希望大家阅读完这篇文章后大有收获&#xff0c;下面让小编带着大家一起了解一下。 1、python画樱花树代码为&#xff1a; import turtle as T import random import…

洲际酒店集团内外并举 引领行业多元包容文化发展

携手多家本地合作伙伴聚焦女性职业发展和残障群体关爱 2023年12月8日&#xff0c;上海 — 近年来&#xff0c;随着“中国式现代化”进程的不断推进&#xff0c;建立多元、包容的雇佣环境&#xff0c;促进公平就业机会等愈加受到社会各界的重视。洲际酒店集团深知&#xff0c;“…

ssm基于JAVA的网上药品售卖系统论文

摘 要 现代经济快节奏发展以及不断完善升级的信息化技术&#xff0c;让传统数据信息的管理升级为软件存储&#xff0c;归纳&#xff0c;集中处理数据信息的管理方式。本网上药品售卖系统就是在这样的大环境下诞生&#xff0c;其可以帮助管理者在短时间内处理完毕庞大的数据信息…

从零开始搭建企业管理系统(四):集成 Knife4j

集成 Knife4j 前言Knife4j是什么集成 Knife4j引入 pom 依赖添加基础配置启动程序测试完善文档信息编写配置类修改 UserController修改 UserEntity修改 BaseEntity 文档效果图swagger 界面knife4j 界面 前言 前面一小节我们使用postman来进行接口的调试&#xff0c;如果接口一多…

大数据机器学习算法项目——基于Django/协同过滤算法的房源可视化分析推荐系统的设计与实现

大数据机器学习算法项目——基于Django/协同过滤算法的房源可视化分析推荐系统的设计与实现 技术栈&#xff1a;大数据爬虫/机器学习学习算法/数据分析与挖掘/大数据可视化/Django框架/Mysql数据库 本项目基于 Django框架开发的房屋可视化分析推荐系统。这个系统结合了大数据…

Java项目-瑞吉外卖Day3

填充公共字段&#xff1a; 目的&#xff1a;由于某些属性&#xff0c;例如createdTime这些需要填充的字段会在多个地方出现&#xff0c;所以考虑使用公共字段自动填充的办法减少重复代码。 在对应属性上加入TableField注解。通过fill字段表明策略&#xff0c;是插入/更新的时候…

5个免费AI文案生成器【2024】

随着科技的不断进步&#xff0c;人工智能在各行各业中崭露头角&#xff0c;其中&#xff0c;AI文案生成器的出现在内容创作领域引起了翻天覆地的变化。在这个信息快速传递的时代&#xff0c;如何更高效地进行文案创作成为许多从业者关注的焦点。本文将深入探讨AI文案生成器&…

每日一博 - 图解5种Cache策略

文章目录 概述读策略Cache AsideRead Through 写策略Write ThroughWrite AroundWrite Back 使用场景举例 概述 缓存是在系统中存储数据的临时存储器&#xff0c;用于提高访问速度。缓存策略定义了如何在缓存和主存之间管理数据 读策略 Read data from the system: &#x1f5…

如何从众多知识付费平台中正确选择属于自己的平台(我有才知识付费平台)

在当今的知识付费市场中&#xff0c;用户面临的选择越来越多&#xff0c;如何从众多知识付费平台中正确选择属于自己的平台呢&#xff1f;下面&#xff0c;我们将为您介绍我有才知识付费平台相比同行的优势&#xff0c;帮助您做出明智的选择。 一、创新的技术架构&#xff0c;…

Oracle中LISTAGG 函数 的使用

概念&#xff1a;对于查询中的每个组&#xff0c;LISTAGG 聚合函数根据 ORDER BY 表达式对该组的行进行排序&#xff0c;然后将值串联成一个字符串

一键优化工具,十分不错的win7、win10系统优化的工具,可以帮助用户轻松快速优化系统,供大家学习研究参考~

主要功能 01、禁用索引服务 02、禁止window发送错误报告 03、禁用"最近使用的项目” 04、关闭Windows Defender 05、关闭防火墙 06、检查更新而不自动下载更新 07、启动电源计划“高性能” 08、调整电源选项 09、禁用休眠(删除休眠文件) 10、开启快速启动 11、…

C语言-每日刷题练习

[蓝桥杯 2013 省 B] 翻硬币 题目背景 小明正在玩一个“翻硬币”的游戏。 题目描述 桌上放着排成一排的若干硬币。我们用 * 表示正面&#xff0c;用 o 表示反面&#xff08;是小写字母&#xff0c;不是零&#xff09;&#xff0c;比如可能情形是 **oo***oooo&#xff0c;如果…

【高数:3 无穷小与无穷大】

【高数&#xff1a;3 无穷小与无穷大】 1 无穷小与无穷大2 极限运算法则3 极限存在原则4 趋于无穷小的比较 参考书籍&#xff1a;毕文斌, 毛悦悦. Python漫游数学王国[M]. 北京&#xff1a;清华大学出版社&#xff0c;2022. 1 无穷小与无穷大 无穷大在sympy中用两个字母o表示无…

第 375 场 LeetCode 周赛题解

A 统计已测试设备 模拟&#xff1a;记录当前已测试设备数量 class Solution { public:int countTestedDevices(vector<int> &batteryPercentages) {int res 0;int s 0;for (auto x: batteryPercentages) {if (x - s > 0) {res;s;}}return res;} };B 双模幂运算 …

Course3-Week1-无监督学习

Course3-Week1-无监督学习 文章目录 Course3-Week1-无监督学习1. 欢迎1.1 Course3简介1.2 数学符号约定 2. K-means算法2.1 K-means算法的步骤2.2 代价函数2.3 选择聚类数量 3. 异常检测3.1 异常检测的直观理解3.2 高斯分布3.3 异常检测算法3.4 选取判断阈值 ε \varepsilon ε…

面试操作系统八股文五问五答第一期

面试操作系统八股文五问五答第一期 作者&#xff1a;程序员小白条&#xff0c;个人博客 相信看了本文后&#xff0c;对你的面试是有一定帮助的&#xff01; ⭐点赞⭐收藏⭐不迷路&#xff01;⭐ 1.死锁产生的条件 1.互斥条件&#xff0c;即当资源被一个线程使用&#xff08;…