solidity笔记1(基础部分)

这篇具有很好参考价值的文章主要介绍了solidity笔记1(基础部分)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

 以太坊Solidity是一种面向智能合约的高级语言,其语法与JavaScript类似。solidity是用于生成在EVM上执行的机器级代码的工具。solidity编译器获取高级代码并将其分解为更简单的指令。Solidity代码封装在Contracts中。

因为之前实验课程已经完成了相关内容,所以主要整理一部分个人觉得比较难以理解和重要的部分
 

1.solidity基础操作整理

1.1.solidity的四种可见度

public:公共函数任何人都可以调用该函数,包括DApp的使用者。
private:只有合约本身可以调用该函数(在另一个函数中)。
internal:只有这份合同以及由此产生的所有合同才能称之为合同。
external:只有外部可以调用该函数,而合约内部不能调用。

1.2.solidity的三种修饰符

view: 可以自由调用,因为它只是“查看”区块链的状态而不改变它(查看)
pure: 也可以自由调用,既不读取也不写入区块链
payable:常常用于将代币发送给合约地址。

2.函数结构

一个solidity的函数应有以下部分组成
function
你的函数名字(类型1 名字,类型2 名字,。。。,类型n 名字) 如果没有就什么都不填即可


可见度/访问权限,即public/private/internal/external 如果不写则系统默认为public并且警告


修饰符,即view/pure/payable 如果需要花费gas则不写


returns(类型1 名字,类型2 名字,。。。,类型n 名字) 如果有的话

pragma solidity ^0.4.0;

contract helloworld {
    function stringtest(string inputstr) public view returns(string){
        return inputstr;
    }
}

6.函数

1.函数重载是指函数命名相同,但需要满足以下两个条件之一
a.函数传入参数类型不同
b.函数传入参数数量不同
2.如果函数多个参数都匹配,那么会报错
3.address因为实际存储的也是uint160

pragma solidity ^0.4.0;


contract funtest{
    
    
    /*function fun0() {
        
    }
    
    
    function fun0() {
        
    }*/
      uint public test= 0;
      
    function fun1(uint num1,uint num2) {
        test = 10;
    }
    
    
    function fun1(uint num1) {
        test = 20;
    }
    
    
    function fun2(uint a) {
        test = 100;
    }
    
    
    function fun2(string a) {
         test = 200;
    }
    
    
    
    function fun3(address a) {
        test=1000;
    }
    
    
    function fun3(uint160 a){
        test=2000;
    }
    
    
    
    
    function fun4(uint8 a){
         test=10000;
    }
    
    
    function fun4(uint16 a){
        test=20000;
    }
    
    
    
    
    function fun1test() public view returns(uint){
        fun1(1,2);
        return test;
    }
    
     function fun2test() public view returns(uint){
        fun2('asdasd');
        return test;
    }
    
    function fun3test() public view returns(uint){
        fun3(0x2e805eC48BdFBc458e7446058F94a315896A1cF6);
        //仅使用address类型,可以运行并运行address参数的重载函数
        return test;
    }
    
    //function fun3test2() public view returns(uint160){
        //uint160  如果转化成uint160类型并运行,那么报错          
        //temp=uint160(0x2e805eC48BdFBc458e7446058F94a315896A1cF6);
        //fun3(temp);
        //return temp;
    //}
    
    
    
    
    function fun4test() public view returns(uint){
        fun4(256);
        return test;
    }
   
    
    function reset() public{
        test = 0;
    }
    

}
运行结果

solidity笔记1(基础部分)

3.数据类型

3.1bool、int、uint 、bytes、bytes1-bytes32

   //布尔类型 bool 数据操作:逻辑与、逻辑或、逻辑非 ||、 && 、!

   int num1=100;

   int num2=200;

   //整型 int=int256 uint=uint256 数据操作:加减乘除求余、求平方 +-*/%、**

        return a**b;

     //计算a的b次方

  //位运算:按位与、按位或、按位取反、按位异或、左移、右移 &、|、~、^、<<、>> 

    uint8 a=3; uint8 b=4

    return a|b;

    //按位或,结果为7

   //整型字面量:在solidity里面运算是计算出结果再赋值

     uint num=1/2*1000;

     return num;

    //返回500

    //字节(数组)类型:bytes1(byte)、bytes2...bytes32,长度固定且内部数据不可修改

    //属性:length 可以进行比较,位运算

    bytes9 name=0xe69d8ee79fa5e681a9;

    byte num=0x7a;

    return num.length;

    //返回1

    return name[index];

   //按照index获得字节数组的值

3.2 动态字节数组:bytes num=new bytes()

bytes  public  num=new bytes(2);//创建动态字节数组

 num[0]=0x12;

num[1]=0x34;

 //初始化数组

return num.length;

//获取数组长度

num.length=5;

//修改数组长度

num.push(0x56);

 //push方法在数组末尾追加数据

3.3 字符串类型

 string name1="方晰雨 

3.4 数组

3.4.1 固定数组

   //固定数组初始化

   uint[5] arr=[1,2,3,4,5];

   //获取数组元素并修改

   arr[1]=200;

3.4.2 可变数组

// 可变数组初始化

uint[]  grade=[1,2,3,4,5];

//获取可变数组元素并修改 

grade[0]=100;

grade[1]=200;

4.1 地址 address

address 在存储上和uint160一样,且二者可以互相转换,地址之间也可以进行比较大小

pragma solidity ^0.4.0;
contract whatisaddress{
    //0x75e453B2039c8A168b8Dab1AA97F4735618559De
    address account1;
    address account2 = 0x75e453B2039c8A168b8Dab1AA97F4735618559De;
    function showaddress1() public view returns(address){
        return account1; //可以看到未赋值时,参数为0
    }
    
    function showaddress2() public view returns(uint160){
        return uint160(account2);//说明可以转化为uint160类型
    }
    
    function typechange(uint160 num) public view returns(address){
        return address(num);//可以互相转换
    }
    
    //0x76E67229eaE13967955cb972658ca33bAa36b696
    address account3 = 0x76E67229eaE13967955cb972658ca33bAa36b696;
    function largetest() public view returns(bool){
        return account3>account1;
    }
}

4.2.转账操作与余额获取


1.可以通过地址.balance获取某个地址的余额
2.this指的是当前合约的地址,如此处就是paytest合约的地址
3.转账可以通过remix图形界面来进行转账数目的改变
4.对其他账户的转账需要使用账户名称.transfer(msg.value)或者账户名称.transfer(数量 单位,如1 ether)如果在输入value的同时又写的是数量 单位,那么多余的value就自动转账到合约地址里去
5.如果对当前合约使用transfer转账this.transfer(msg.value)则必须需要一个回滚函数。
6…如果函数含有payable而函数里面没有要求给某个账户转账的话,则会默认转账到合约当中
7.send和transfer的区别是,前者是底层函数,返回bool值;后者会直接在调用时报错。具体体现在如果转账金额为0是,send正常运行但是返回false 现在尝试了之后发现即使转账金额0,两者均都不报错,返回的为true,见测试5

contract  paytest{
    function payabletest() payable{
    }
    
    function getbalance(address account) public view returns(uint){
        return account.balance;
    }
    
    function thistest() public view returns(address){
        return this;
    }
    
    function transfertest1() payable public returns(uint){
        address account1=0xeb46e45709DE0b10AECa4A9C9D1800beB6a13C6C;//账户随意
        account1.transfer(msg.value);
        return account1.balance;
    }
    
    function transfertest2()  payable public  returns(uint){
        this.transfer(msg.value);
        return this.balance;
    }
    
    function () payable{       
    }
}
运行结果
1.先得到this的地址,再讲this的地址复制进去查看,可以知道此时合约的余额为0

solidity笔记1(基础部分)

 2.修改remix界面中的value值然后点击我们payabletest,再调用之后就可以发现余额发生了变化

solidity笔记1(基础部分)

solidity笔记1(基础部分)

3.原本0xeb46e45709DE0b10AECa4A9C9D1800beB6a13C6C地址的余额是

solidity笔记1(基础部分)

PS.虽然显示是这个,但实际上是100eth,但这些先不追究


输入2之后点击transfertest1可以看到余额发生变化

4.转账8个,但是只接受4个,剩下的都到合约地址去了


5.value设置为0
调用sendtest,返回值为true

调用transfertest2,正常运行没有报错

5.mapping映射


1.定义映射mapping(类型1 => 类型2) 映射名称

contract mappingtest{
    mapping(address => uint) ATU;
    mapping(uint => string) UTS;
    uint sum=0;
    
    function test(string teststring) {
        address account=msg.sender;
        sum++;
        ATU[account]= sum;
        UTS[sum]= teststring;
    }
    
    function ATUtest() public view returns(uint){
        address account=msg.sender;
        return ATU[account];
    }
    
    function UTStest() public view returns(string){
        return UTS[sum];
    }

}
solidity笔记1(基础部分)

6.简单继承


1.合约通过is来继承上一个合约可以继承的函数,参数等
2.合约可以连续继承,即
b is a,b继承了a的元素
c is b,c继承b的元素同时继承了a的元素
3.子合约继承父合约的变量以及函数时,如果子合约定义了同名变量或者函数,那么子合约的变量/函数会覆盖继承过来的
4.合约如果一次性要继承多个合约的话,通过逗号连接,如果有重复的变量名或者函数名以最后一个出现的为准。当然子合约出现的话最终还是以自合约为准
代码

contract jicheng1{
    uint a=1;
    string b='hello! i am jicheng1 !';
    function saygoodbye() public view returns(string){
        return 'goodbye';
    }
}

contract jicheng2 is jicheng1{
    function getall1() public view returns(uint,string ){
        return (a,b);
    }
    string c='hello! i am jicheng2 !';
    bytes2 d=0x1234;
}

contract jicheng3 is jicheng2{
    function getall2() public view returns(uint,string,string,bytes2){
        return (a,b,c,d);
    }
}

contract jicheng4 is jicheng3{
    
    uint a=1000;
    function getall2(uint a) public view returns(uint,string,string){
        return (a,b,c);
    }
    
}


运行结果

solidity笔记1(基础部分)

solidity笔记1(基础部分)

6.memory与storage


1.在solidity合约内部
函数外部声明的变量默认储存在storage里
函数内部声明的变量默认储存在memory里

solidity笔记1(基础部分)

7.结构体

代码示例

pragma solidity ^0.4.0;
contract structtest1{
    
    struct stu{
        uint id;
        string name;
        mapping(uint=>string) maptest; //mapping即使在结构体内,初始化时也是可以忽略的
    }
    
    function init1() public returns(uint,string){
        stu memory student1= stu(1234,'stu1');
        return (student1.id,student1.name); //初始化方法一
    }
    
    function init2() public returns(uint,string){
        stu memory student2=stu({name:'stu2',id:5678});
        return (student2.id,student2.name); //初始化方法二
    }
    
    stu tempstudent1; //只要是函数外面的都是storage
    
    function mappingtest() public returns(uint,string){
        stu memory student3=stu({name:'stu3',id:5678});
        //student3.maptest[100]='mapstu3';
       //直接赋值会报错,因为storage不能转化为memory
       tempstudent1=student3;
       //此时tempstudent1,student3使用的是统一指针,所以下面对tempstudent1修改就等于修改student3
       tempstudent1.maptest[100]='how to map';
       return (student3.id,tempstudent1.maptest[100]);
    }
}

 7.2结构体storage转storage


1.要是函数以结构体作为参数,那么函数修饰符必须有private/internal
2.storage可以接受storage的值,并且storage的改动影响其它storage


代码

 contract STS{   //此例temp,student1均为storage
    struct stu{
        uint id;
        string name;
    }
    stu student1;
    function structtest(stu storage temp) internal{ //传入storage结构体
        student1=temp; //赋值
        temp.id=2;    //即使只是修改并未再次赋值,student1的id也会改变
    }
    
    function tets() public view returns(uint){
        structtest(student1); 
        return (student1.id);
    }
    
}

7.3结构体memory转storage


1.要是函数以结构体作为参数,那么函数修饰符必须有private/internal
2.storage可以接受memory的值
3.memory的改动不影响storage
4.storage的改动不影响memory
contract MTS{
    
    struct stu{
        uint id;
        string name;
    }
    
    stu student1;
    uint memorynum; //记录memory的值是否受storage影响
    function structtest1(stu memory temp) internal{
        student1=temp; //storage可以接受memory的值,但是memory的改动不影响storage
        temp.id=2; //改变memory的值,看看storage值是否随之改变
        memorynum=temp.id;  //如果student1随着temp改变,那么说明storage受memory影响
    }
    
    function structtest2(stu memory temp) internal{
        student1=temp;
        student1.id=3;//改变storage的值,看看memory值是否随之改变
        memorynum=temp.id; //如果temp随着student1改变,那么说明memory受storage影响
    }
    
    function test1() public returns(uint,uint){
        stu memory temp=stu(1,'a');
        structtest1(temp);
        return (student1.id,memorynum);
    }
    
    function test2() public returns(uint,uint){
        stu memory temp=stu(1,'a');
        structtest2(temp);
        return (student1.id,memorynum);
    }
    
}
 

7.4.结构体storage转memory


1.要是函数以结构体作为参数,那么函数修饰符必须有private/internal
2.storage可以接受memory的值
3.memory的改动不影响storage
4.storage的改动不影响memory
代码

contract STM{
    
    struct stu{
        uint id;
        string name;
    }
    
    stu student1=stu(1,'a');
    uint memorynum; //记录memory的值是否受storage影响
    function structtest1(stu storage temp) internal{
        stu memory student2=temp;
        student2.id=2;//改变memory的值,看看storage值是否随之改变
        memorynum=student2.id;
    }
    
    function structtest2(stu storage temp) internal{
        stu memory student2=temp;
        temp.id=3;//改变storage的值,看看memory值是否随之改变
        memorynum=student2.id;
    }
    
    function test1() public view returns(uint,uint){
        structtest1(student1);
        return (student1.id,memorynum);
    }
    
    function test2() public view returns(uint,uint){
        structtest2(student1);
        return (student1.id,memorynum);
    }
    
}

7.5.结构体memory转memory


1.要是函数以结构体作为参数,那么函数修饰符必须有private/internal
2.在此处中看似不影响,但是solidity自我优化是的传入的memory转化为指针,然后连锁导致后面的也全部变为指针,相当于storage转storage了
代码
 文章来源地址https://www.toymoban.com/news/detail-413836.html

到了这里,关于solidity笔记1(基础部分)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 以太坊智能合约开发:Solidity 语言快速入门

    在本文中,我们从一个简单的智能合约样例出发,通过对智能合约源文件结构的剖析与介绍,使大家对Solidity语言有一个初步的认识。最后,我们将该智能合约样例在 Remix 合约编译器中编译、部署,观察其执行结果。 在开始之前,我们先对Solidity有个初步的了解,即Solidity是

    2023年04月09日
    浏览(51)
  • 第四章 以太坊智能合约solidity介绍

    Solidity 是一门面向合约的、为实现智能合约而创建的高级编程语言,设计的目的是能在以太坊虚拟机上运行。 本章大概介绍合约的基本信息,合约的组成,语法方面不做过多的介绍,个人建议多阅读官方文档效果更佳,后续的章节会开发ERC20代币合约案例以便于更好的学习智

    2024年02月06日
    浏览(51)
  • 以太坊智能合约开发:Solidity语言中的映射

    本文我们介绍Solidity语言中的映射,包括映射的基本定义、语法、映射的变量声明和基本读写操作。并且通过两个智能合约例子演示了映射的定义与基本操作。 Solidity中关于映射的一些定义: 映射以键-值对(key = value)的形式存储数据; 键可以是任何内置数据类型,包括字节

    2024年02月05日
    浏览(54)
  • 【以太坊 Solidity】管理员读写权限/访问控制/角色控制

    在 Solidity 语言的多继承中,若 多个合约 共同继承一个 父合约 ,则这 多个合约 共享 父合约 中的变量和函数。 合约继承路线如下: 1.1 权限管理合约 1.2 继承权限管理合约的基类合约 1.3 待测试的合约 2.1 正向测试:合约拥有者OWNER具有管理员权限 此时 合约 Authority 中的 构造

    2024年02月04日
    浏览(60)
  • 04-Solidity8.0以太单位Gas和全局变量

    04-Solidity8.0以太单位Gas和全局变量 以太和Wei 交易ether. 类似于1美元等于 100 美分,1ether等于 10**18 wei。 Gas ether您需要为交易支付多少费用? 您支付gas spent * gas price的金额ether,在哪里 gas是一个计算单位 gas spentgas是交易中使用的总金额 gas priceether是你愿意支付多少gas 具有较高

    2024年02月02日
    浏览(63)
  • 以太坊智能合约开发(五):Solidity成绩录入智能合约实验

    每个学生分别部署合约Student.sol ,保证只有自己可以修改姓名。老师部署合约StudentScore.sol,用于录入学生成绩,查询学生信息。查询学生信息时,需要调用学生部署的合约Student.sol。 student.sol合约,用于学生对自己信息进行管理。 学生的基本信息作为状态变量: 声明构造函

    2024年02月07日
    浏览(47)
  • 以太坊智能合约开发:Solidity 语言中的数据类型

    本文我们介绍Solidity语言的数据类型,重点是值类型,包括布尔类型、整型、地址类型、字节类型、字符串类型和枚举类型。并且通过两个智能合约例子,用于演示这些数据类型的声明与使用方法。 访问 Github 仓库 获取更多资料。 Solidity中关于数据类型的定义如下: Solidity是

    2024年02月02日
    浏览(67)
  • 以太坊智能合约开发:Solidity语言中的构造函数

    Solidity语言中关于构造函数的定义: 构造函数是使用 constructor 声明的一个可选函数; 构造函数只在合约部署时调用一次,并用于初始化合约的状态变量; 如果没有显式定义的构造函数,则由编译器创建默认构造函数。 构造函数声明语法如下: 其中: ** constructor :

    2024年02月01日
    浏览(51)
  • 基于以太坊的智能合约开发Solidity(事件&日志篇)

    (1)事件用于记录在区块链上的特定活动,“emit ValueChanged(newValue);”语句的作用是触发ValueChanged事件(首先需要声明事件)。 ①触发事件后会生成相应日志,上图黄框就是“emit ValueChanged(newValue);”语句产生的日志,其中“form”指的是触发事件的合约账户。 ②事件主要是供

    2024年02月04日
    浏览(42)
  • Solidity 中的数学(第 2 部分:溢出)

    每次我看到 + 、 * 或 ** 审计另一个 Solidity 智能合约时,我都会开始写以下评论:“这里可能会溢出”。我需要几秒钟来写这四个字,在这几秒钟内,我观察附近的行,试图找出原因,为什么不可能溢出,或者为什么在这种特殊情况下应该允许溢出。如果找到原因,我会删除

    2023年04月12日
    浏览(31)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包