900字范文,内容丰富有趣,生活中的好帮手!
900字范文 > [区块链笔记1] 入坑区块链 智能合约solidity基础

[区块链笔记1] 入坑区块链 智能合约solidity基础

时间:2021-11-24 14:05:47

相关推荐

[区块链笔记1] 入坑区块链 智能合约solidity基础

以太坊是一个分布式计算网络,提供了运行智能合约的分布式平台。

智能合约是在以太坊虚拟机上运行的应用程序。

以太坊拥有多种高级语言可以用来编写智能合约,最流行的是solidity,基于javascript。

remix ide是一个智能合约开发的IDE

第一个代码

pragma solidity ^0.4.0;//向上兼容到0.5.0以下contract Demo{string str = "hello world";function getStr() public view returns(string){return str;}function setStr(string t_str) public{str = t_str;}function pureTest(string t_str) public pure returns(string){return t_str;}}

节省gas(或者说ether)的两个关键字

view修饰的函数可以读取状态变量但是不能改

pure修饰的函数不能改也不能读状态变量

int/uint类型

整形变量:int8/uint8~int256/uint256,步长为8,int/uint=int256/uint256,即256位二进制位

数组

固定长度字节数组:bytes1,bytes2…bytes32,步长为1,1byte=8bit;正好和int/uint位数对应

bytes类型的变量可以通过length属性访问长度

不定长字节数组bytes arr=new bytes(2);//分配两个字节数组

不定长数组长度可以改变,自动在右侧添加0x00填充

可通过push操作向后面添加数据,push的过程会自动增加数组长度

bytes arr = new bytes(2);function setArr() public{arr[0]=0x01; arr[1]=0x02;}function getArr() public view returns(uint){return arr.length;} function pushData() public {//arr.length = 3;arr.push(0x03);}

string类型

string没有length属性,也不可以通过下标的方式来获取其中元素。

注意string中存储中文一个占3个字节

string转bytes

string str="hello world";function getLength() public view returns (uint){return bytes(str).length;}function getStr() public view returns (bytes){return bytes(str);}function getChar() public view returns (bytes1){return bytes(str)[0];}function opChar() public {bytes(str)[0] = 'x';}

bytes转string

bytes byteStr = new bytes(2);function init() public {byteStr[0]=0x68; byteStr[1]=0x65;}function getStr() public view returns (string){return string(byteStr);}

bytes10转string

function bytes10ToString(bytes10 byteStr) public pure returns (string){uint count=0;for (uint i=0; i<byteStr.length; i++){if (byteStr[i]!=0x00){count++;}else{break;}}bytes memory bytesStr = new bytes(count);for (uint j=0; j<count; j++){bytesStr[j] = byteStr[j];}return string(bytesStr);}

固定长度字节数组截取

bytes8 byteStr = 0x1234567891234567;function getbyte1() public view returns (bytes1){return bytes1(byteStr);}function getbyte10() public view returns (bytes10){return bytes10(byteStr);}

固定长度字节数组转可变长度字节数组

bytes8 byteStr = 0x1234567891234567;function getDynamicStr() public view returns (bytes){bytes memory tStr = new bytes(byteStr.length);for (uint i=0; i<byteStr.length; i++){tStr[i] = byteStr[i];}return tStr;}

int/uint数组

一维固定长度数组

int[5] arr = [];

固定长度数组只可以访问length,不能改变

二维固定长度数组

int[2][3] arr;表示有3个元素,每个元素占两个int.

当在访问下标是又变成[i][j],第i行第j列

一维可变长度数组

int[] arr = [];

可变长度数组可以修改length, push元素

二维可变长度数组

int[][] arr = [[1,2], [3,4], [5,6]];

可以修改外层长度和内层长度,但是没有push方法

地址address是用uint160来存储的

address public p;address public p = 0xca35b7d915458ef540ade6068dfe2f44e8fa733c;function getAddress() public view returns (uint160){return uint160(p);}uint public pData = 1154414090619811796818182302139415280051214250812;function getAddress2() public view returns (address){return address(pData);}

payable关键字代表可以通过这个函数给合约地址转账,默认转账单位是位

this代表合约的地址

通过合约/账户地址的属性balance可以获取合约/账户的ether

通过外部账户向合约转账

contract Demo{function getBalance() payable public {}function showBalance() public view returns (uint){return uint(this.balance);}function showRandBalance(address p) public view returns (uint) {return uint(this.balance);}}

外部账户转账给其他账户

contract Demo{function trans() public payable {address p = 0xca35b7d915458ef540ade6068dfe2f44e8fa733c;p.transfer(msg.value);}}

外部账户转账给合约

contract Demo{function showBalance() public view returns(uint){return this.balance;}function trans2() public payable {this.transfer(msg.value);}function() payable {}}

全局变量

msg.sender:合约的调用者(账户)的地址

msg.value:当前消息附带的以太币

block.number:当前区块块号

block.difficulty:当前块的困难度

mapping用法,注意输入地址的时候要用双引号

contract Demo{mapping(address => uint) idMap;mapping(uint => string) strMap;uint public pos=0;function func(string str) public {pos++;address p = msg.sender;idMap[p] = pos;strMap[pos] = str;}function getIdByAddress(address ad) public view returns(uint){return idMap[ad];}function getStrById(uint id) public view returns (string) {return strMap[id];}}

多返回值

contract Demo{function test(uint a, uint b) public view returns(uint res1, uint res2){return (a+b, a-b);}function test2(uint a, uint b) public view returns(uint res1, uint res2){res1 = a+b;res2 = a-b;}}

solidity中的构造函数只能有一个

老版本中可以用和类名相同的函数名作为构造函数

新版本中可以使用关键字constructor作为构造函数

contract Demo{int public n;// function Demo() public {//n = 5;// }constructor() public{n=6;}}

require函数,当判断条件为真,继续执行下面语句;否则下面语句都不执行

modefier关键字

contract Demo{address public owner;int public n;constructor() public {owner = msg.sender;}modifier onlyOwner() {require(owner == msg.sender);_; //动态添加代码}function func(int tn) onlyOwner {n = tn;} }

modifier代码重用示例

contract Demo{uint public level=5;uint public flag=0;modifier func(uint needLevel){require(level>=needLevel);_;}function func1() func(2){flag=1;}function func2() func(6){flag=2;}}

深入modifier, 执行顺序:x=1,x=3,x=5,x=4,x=2

contract Demo{int public x;modifier mod1() {x=1;_;x=2;}modifier mod2() {x=3;_;x=4;}function test() mod1 mod2 {x=5;}}

继承使用is关键字对象可以连续继承,也可多继承:

contract son is father, mother

父类中的变量不加修饰的时候,子类中默认(public)可以访问

父类对象中的internal修饰的成员,子类中也可以访问。在合约内可访问,外部不可访问。

父类对象中的private修饰的成员,子合约中不可以访问

父类对象中的external修饰的成员不可以在合约中访问或调用,只能在合约外部访问或调用

说明

相对于C++

public->public

private->private

internal->protected

C++中的类在这里叫合约

constant在函数中的用法被抛弃,在全局变量中,只用于byte1-byte32,int,uint,string,表示数据不可被修改

public修饰的成员会默认生成getter方法,供外部调用

比如,其中的x方法就是自动生成的,但是当我们显示写了这个函数后,就不会自动生成默认的x方法了

contract Demo{int public x;function x() external view returns(int) {return x;}}

合约的销毁

contract Demo{address owner;int x = 0;constructor() public {owner = msg.sender;}function increase() public returns (int) {x = x+10;return x;}function destruct() public {if (owner == msg.sender){selfdestruct(owner);}}}

结构体的使用

contract Demo{struct student{string name;uint grade;}function func1() public view returns (string, uint) {student memory t = student("name1", 100);return (t.name, t.grade);} function func2() public view returns (string, uint) {student memory t = student({name:"name2", grade:99});return (t.name, t.grade);}}

不能包含本身,但是可以是动态的数组或者mapping等类型

注意memory定义的结构体,不可以直接操作结构体中的mapping

但是可以操作在合约内部默认storage定义的结构体中的mapping

storage可以看成C++中的引用

contract Demo{struct student{string name;uint grade;}student stu;function test(student storage st) internal {student storage s = st;s.grade = 100;}function func() public view returns(uint) {test(stu);return stu.grade;}}

memory类型的变量传递是通过指针来传递的

枚举类型

enum day{monday, thusday, wendesday}

综合示例:众筹功能代码

pragma solidity ^0.4.0;contract Charity{struct Payer{address payerAddress;uint payMoney;}struct Needer{address neederAddress;uint goal;uint curMoney;uint payerCount;mapping(uint => Payer) map;}uint neederCount;mapping(uint => Needer) needMap;function newNeeder(address _neederAddress, uint _goal) public {neederCount++;needMap[neederCount] = Needer(_neederAddress, _goal, 0, 0);}function pay(address _address, uint _neederPos) payable {Needer storage _needer = needMap[_neederPos];_needer.curMoney += msg.value;_needer.payerCount++;_needer.map[ _needer.payerCount] = Payer(_address, msg.value);}function trans(uint _neederPos){Needer storage _needer = needMap[_neederPos];if (_needer.curMoney <= _needer.goal){_needer.neederAddress.transfer(_needer.curMoney);}}function show(uint _neederPos) public view returns (uint, uint, uint) {Needer storage _needer = needMap[_neederPos];return(_needer.goal, _needer.curMoney, _needer.payerCount);}}

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。