以太坊solidity学习记录(一)新版在线remix编译器的使用(2020.4.27)
以太坊solidity学习记录(二)基础操作整理
以太坊solidity学习记录(三)基础数据操作
以太坊solidity学习记录(四)地址与交易
以太坊solidity学习记录(五)函数入门
以太坊solidity学习记录(六)内存与结构体
结论:
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;
}
}
结论:
1.可以直接对传入参数里面的命名来进行对应命名。这样可以调整顺序
2.格式
函数名({类型1:value1,类型2:value2,…,类型n:valuen})需要打{},而且等号(=)换成冒号(:)
3.使用时必须传入所有参数,否则报错
contract nametest{
uint public num;
string public teststring;
function setvalue(uint num1,string teststring1){
num=num1;
teststring = teststring1;
}
function test1(){
setvalue(1,'a');
}
function test2(){
setvalue({num1:1,teststring1:'a'});
}
function test3(){
setvalue({teststring1:'a',num1:1});
}
//function wrongtest4(){
// setvalue({teststring1:'a'});
//}
}
运行结果:
其他的可以自行点击test1,test2,test3看结果
结论:
1.solidity可以有多个返回值,可以命名(类型1 value1,类型2 value2,....,类型n valuen)
,可以直接赋值,如value1=111;
,赋值之后return里面对应参数也会修改,可以不用return。
2.return语句后面可以接表达式,如uint类型 return (value1+value2, value1*value2);
;
3.可以直接接具体数值,如uint类型 return (1+2,1*2,'teststring');
代码
contract returntest{
function test1() public view returns(uint8 num1,uint8 num2,string teststring){
num1=1;
num2=2;
teststring='hello';//直接赋值,最后可以看到返回值就是赋的值
}
function test2() public view returns(uint8 num1,uint8 num2,string teststring){
return (10,20,'hello2');//可以直接进行返回
}
function test3() public view returns(uint8 num1,uint8 num2,string teststring){
num1=1;
num2=2;
teststring='hello';
return (10,20,'hello2');//如果又赋值又返回,那么以最后为准
}
function test4() public view returns(uint8 num1,uint8 num2,string teststring1,string teststring2){
teststring1='testnb1';
teststring2='testnb2';
//return (10+20,10*20,'hello2',teststring1+teststring2);//solidity不支持string直接连接
return (10+20,10*20,teststring1,teststring2);
}
}
结论:
1.如果不在函数内再次定义重名变量,那么函数内部对合约变量进行修改
2.for循环中可能会出现重定义情况,注意
contract areatest{
uint public a=1;
function areatest1(uint a) public view returns(uint){
a=10;
return a;
}
function areatest2(uint a) public view returns(uint){
a=10;
//for(uint a=0;a<10;a++){
// }
return a;
}
function areatest3() public returns(uint){
a++;
return a;
}
function areatest4(uint a) public returns(uint){
a++;
return a;
}
}
结论
1.constant可在函数声明时使用,相当于view。不消耗燃料
但是此功能4.x版本可用,5.x版本废弃
2.constant只能用于全局变量
3.constant一旦声明函数的值就不可以修改
4.constant可以用于声明uint,int,bytes,string类型变量
代码
contract constanttest{
uint public constant a=1;
//function changetest() public{
// a=2; 函数内试图修改,结果编译报错
//}
//function changetest() public{
// uint constant test=2; //函数内无法声明constant变量
// }
int public constant b=2;
bytes32 public constant c=0x2323;
string public constant d='test';
}
结论:
1.效果:在合约部署时自动调用一次,而且只能调用这一次
2.使用方法有两种
新式(推荐):constructor(参数列表) {}
旧式:function 合约名(参数列表) {}
如果传入参数,那么部署时也需要输入参数
3.用处:可以用来声明,赋值变量等等
代码
contract maketest{
uint public a=1; //以下函数自行删除//测试,一个合约只能有零个或一个构造函数
//function maketest(){
// a=100;
//}
function maketest(uint b) {
b=200;
a=b;
}
//constructor(){
// a=300;
//}
//constructor(uint b){
// b=400;
// a=b;
//}
}
结论:
1.整体构造
modifier 函数名 (参数列表){
语句;
_; //代表调用modifier的函数的语句
语句;
}
2.如何调用modifier函数
function
函数名(参数列表)
modifier函数名
后面的和普通函数一样
调用之后会将函数自动插入制定modifier函数中间的 _;
位置运行,并且前后插入modifier函数已经写好的语句
多重modifier函数相互嵌套
3.应用场景:作判断,赋值等等
4.好处:实现代码重复使用
代码:
contract modifiertest{
uint public a=1;
modifier moditest1(){
_;
a=2;
}
modifier moditest2() {
a=3;
_;
}
function moditestfun1() moditest1{
a=10; //先运行a=10,再运行a=2,最后a=2
}
function moditestfun2() moditest2{
a=20;//先运行a=3,再运行a=20,最后a=20
}
uint public testnum;
function setvalue(uint _testnum){
testnum=_testnum; //设置testnum值
}
modifier judgetest1(uint judgenum){
require(testnum>judgenum); //如果testnum值大于judgenum值则继续,否则跳出
_;
}
function islarge1() judgetest1(3) public view returns(string){
return "finished!"; //大于3时,输出提示
}
uint public x1=1;
modifier taowa1(){
x1=2;
_;
x1=3;
}
modifier taowa2(){
x1=4;
_;
x1=5;
}
function taowatest1() taowa1 taowa2{
//可以有多个modifier函数,顺序不同可能会造成影响
//此处顺序为x1=2,x1=4,x1=5,x1=3,最后x1=3
}
function taowatest2() taowa2 taowa1{
//此处顺序为x1=4,x1=2,x1=3,x1=5,最后x1=5
}
}
运行结果太多就不放了
结论
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);
}
}
运行结果
结论:
是否继承 | 变量 | 函数 |
---|---|---|
是 | public,internal | public,internal,external |
否 | private, |
private |
注意:
1.不同说明:
internal只能在合约内部调用,合约外部不行
external只能在合约外部调用,合约内部不行
public合约内部,合约外部均可以调用
2.private不能够被继承,在合约外部不能被调用,但是在合约内部可以被调用
3.什么是合约内部/外部?
答:以remix举例
在内部就是指合约内部可以调用这个函数
在外部就是指合约部署之后可以在旁侧看到这个函数的按钮
4.一定要在合约内部调用external修饰函数有两种方法
a.使用 this.函数名
调用,这个相当于外部调用
b.再声明一个合约,在新的合约内部创建或者引用该合约即可
contract AuthoritySample{
uint a=0;
uint private b=1;
uint public c=2;
//uint external d=3;
uint internal e=4;
function privatetest() private view returns(string){
return 'private';
}
function internaltest() internal view returns(string){
return 'internal';
}
function externaltest() external view returns(string){
return 'external';
}
function publictest() public view returns(string){
return 'public';
}
function getexternal()public view returns(string){
return this.externaltest(); //调用external方法1
}
}
contract AuthorityTest is AuthoritySample{
function showa() view returns(uint){
return a;
}
//function showb() view returns(uint){
// return b;
//}
function showc() view returns(uint){
return c;
}
// function showd() view returns(uint){
// return d;
//}
function showe() view returns(uint){
return e;
}
}
contract newexternal{
AuthoritySample test=new AuthoritySample();
function testexternal() public view returns(string){
return test.externaltest();//调用external方法2
}
}
结论:
1.如果在声明变量时使用public方法,那么合约会自动生成一个external类型的函数,返回值是public声明的值的类型,命名就是变量名。如果是mapping还会需要一个参数
2.如果我们在外面定义了这个函数,那么这个public变量自动生成的函数会自动消失。
代码
contract gettertest{
uint public a=1;
function a() public view returns(uint){
return a; //声明变量时相当于自动生成了这个函数
}
mapping(uint=>string) public xxx; //使用mapping时也生成,但需要输入参数
function test2(){
xxx[a]='hello';
}
}
结论:
1.函数通过selfdistrust(合约调用者地址,实际上就是msg.sender)
2.销毁了合约之后,合约内的函数就会失效,无法再被调用
代码
contract suicidecontract{
uint public a=1;
function suicidecontracttest() {
selfdestruct(msg.sender);
}
function tets() public view returns(string){
return 'function end here!';
}
}
本文所有代码
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);
return test;
}
//function fun3test2() public view returns(uint160){
//uint160 temp=uint160(0x2e805eC48BdFBc458e7446058F94a315896A1cF6);
//fun3(temp);
//return temp;
//}
function fun4test() public view returns(uint){
fun4(256);
return test;
}
function reset() public{
test = 0;
}
}
contract nametest{
uint public num;
string public teststring;
function setvalue(uint num1,string teststring1){
num=num1;
teststring = teststring1;
}
function test1(){
setvalue(2,'b');
}
function test2(){
setvalue({num1:3,teststring1:'c'});
}
function test3(){
setvalue({teststring1:'d',num1:4});
}
//function wrongtest4(){
// setvalue({teststring1:'a'});
//}
}
contract returntest{
function test1() public view returns(uint8 num1,uint8 num2,string teststring){
num1=1;
num2=2;
teststring='hello';
}
function test2() public view returns(uint8 num1,uint8 num2,string teststring){
return (10,20,'hello2');
}
function test3() public view returns(uint8 num1,uint8 num2,string teststring){
num1=1;
num2=2;
teststring='hello';
return (10,20,'hello2');
}
function test4() public view returns(uint8 num1,uint8 num2,string teststring1,string teststring2){
teststring1='testnb1';
teststring2='testnb2';
//return (10+20,10*20,'hello2',teststring1+teststring2);
return (10+20,10*20,teststring1,teststring2);
}
}
contract areatest{
uint public a=1;
function areatest1(uint a) public view returns(uint){
a=10;
return a;
}
function areatest2(uint a) public view returns(uint){
a=10;
//for(uint a=0;a<10;a++){
// }
return a;
}
function areatest3() public returns(uint){
a++;
return a;
}
function areatest4(uint a) public returns(uint){
a++;
return a;
}
}
contract constanttest{
uint public constant a=1;
uint public a2=2;
function constest() public constant returns(uint a){
return a;
}
function constest2() public returns(uint a){
return a2;
}
//function changetest() public{
// a=2;
//}
//function changetest() public{
// uint constant test=2;
// }
int public constant b=2;
bytes32 public constant c=0x2323;
string public constant d='test';
}
contract maketest{
uint public a=1;
//function maketest(){
// a=100;
//}
function maketest(uint b) {
b=200;
a=b;
}
//constructor(){
// a=300;
//}
//constructor(uint b){
// b=400;
// a=b;
//}
}
contract modifiertest{
uint public a=1;
modifier moditest1(){
_;
a=2;
}
modifier moditest2() {
a=3;
_;
}
function moditestfun1() moditest1{
a=10;
}
function moditestfun2() moditest2{
a=20;
}
uint public testnum;
function setvalue(uint _testnum){
testnum=_testnum;
}
modifier judgetest1(uint judgenum){
require(testnum>judgenum);
_;
}
function islarge1() judgetest1(3) public view returns(string){
return "finished!";
}
uint public x1=1;
modifier taowa1(){
x1=2;
_;
x1=3;
}
modifier taowa2(){
x1=4;
_;
x1=5;
}
function taowatest1() taowa1 taowa2{
}
function taowatest2() taowa2 taowa1{
}
}
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 x=1000;
function getall2(uint z) public view returns(uint,string,string){
return (x,b,c);
}
}
contract AuthoritySample{
uint a=0;
uint private b=1;
uint public c=2;
//uint external d=3;
uint internal e=4;
function privatetest() private view returns(string){
return 'private';
}
function internaltest() internal view returns(string){
return 'internal';
}
function externaltest() external view returns(string){
return 'external';
}
function publictest() public view returns(string){
return 'public';
}
function getexternal()public view returns(string){
return this.externaltest();
}
}
contract AuthorityTest is AuthoritySample{
function showa() view returns(uint){
return a;
}
//function showb() view returns(uint){
// return b;
//}
function showc() view returns(uint){
return c;
}
// function showd() view returns(uint){
// return d;
//}
function showe() view returns(uint){
return e;
}
}
contract newexternal{
AuthoritySample test=new AuthoritySample();
function testexternal() public view returns(string){
return test.externaltest();
}
}
contract gettertest{
uint public a=1;
function a() public view returns(uint){
return a;
}
mapping(uint=>string) public xxx;
function test2(){
xxx[a]='hello';
}
}
contract suicidecontract{
uint public a=1;
function suicidecontracttest() {
selfdestruct(msg.sender);
}
function tets() public view returns(string){
return 'function end here!';
}
}