高级语法
全局函数/变量
- 最重要的两个全局变量
-
msg.sender
每一次和以太坊交互时都会产生一笔交易,这笔交易的执行人就是msg.sender。简而言之:谁调用的,msg.sender就是谁,每笔交易的msg.sender都可以不同。举例:
- 部署合约的时候,msg.sender就是部署的账户。
- 调用setMessage时,msg.sender就是调用账户。
- 调用getMessage时,msg.sender就是调用账户。
-
msg.value
我们在介绍payable关键字的时候说,如果函数修饰为payable,那么这个函数可以接收转账,这笔钱通过remix的value输入框传递进来。
在转账操作中,这笔钱是通过我们调用一个函数从而产生一笔交易而转入合约的,换句话说,是这笔交易附带了一笔钱。在合约中,每次转入的value是可以通过msg.value来获取到的。注意,
- 单位是wei
- 有msg.value,就必须有payable关键字
- 区块和交易的属性
函数 | 含义 |
---|---|
blockhash(uint blockNumber) | 哈希值(byte32) |
block.coinbase | (address) 当前块矿工的地址。 |
block.difficulty | (uint)当前块的难度 |
block.gaslimit | (uint)当前块的gaslimit |
block.number | (uint)当前区块的块号 |
block.timestamp | (uint)当前块的时间戳 |
msg.data | (bytes)完整的调用数据(calldata) |
gasleft() | (uint)当前还剩的gas |
msg.sender | (address)当前调用发起人的地址 |
msg.sig | (bytes4)调用数据的前四个字节(函数标识符) |
msg.value | (uint)这个消息所附带的货币量,单位为wei |
now (uint)当前块的时间戳 | 等同于block.timestamp |
tx.gasprice | (uint) 交易的gas价格 |
tx.origin | (address)交易的发送者(完整的调用链) |
两个常用单位
- 货币单位
- 一个字面量的数字,可以使用后缀
wei
,finney
,szabo
或ether
来在不同面额中转换。 - 不含任何后缀的默认单位是
wei
。如1ether
== 1000finney
的结果是true
。
- 时间单位
- seconds,minutes,hours,days,weeks,years均可做为后缀,默认是seconds为单位。
- 1 = 1 seconds
- 1 minutes = 60 seconds
- 1 hours = 60 minutes
- 1 days = 24 hours
- 1 weeks = 7 days
- 1 years = 365 days
事件(Event)
相当于打印log,但是需要在调用端才能看到,web3调用时演示
pragma solidity ^0.4.0;
contract ClientReceipt {
//定义,注意,需要加分号,相当于一句语句,与struct和enum不同。
//类似于定义函数原型
event Deposit(
address indexed _from,
uint indexed _id,
uint _value
);
function deposit(uint _id) {
//使用
Deposit(msg.sender, _id, msg.value);
//TODO
}
}
访问函数(Getter Functions)
编译器为自动为所有的public的状态变量
创建访问函数。下面的合约例子中,编译器会生成一个名叫data的无参,返回值是uint的类型的值data。状态变量的初始化可以在定义时完成。
pragma solidity ^0.4.24;
contract Test {
// 加了public 的转态变量,solidity会自动的生成一个同名个访问函数。
// 在合约内部使用这个状态变量的时候,直接当初变量使用即可, 不能直接当成方法使用
// 如果在合约外面向访问这个public变量(data),就需要使用xx.data()形式
uint256 public data = 200;
function getData() public view returns(uint256) {
return data;
}
//This代表合约本身,如果在合约内部使用this自己的方法的话,相当于外部调用
function getData1() public view returns(uint256) {
//return this.data; //不能使用.data形式
return this.data();
}
}
contract Test1 {
function getValue() public view returns(uint256) {
Test t1 = new Test();
return t1.data();
}
}
合约
- 创建合约和外部调用
- new关键字,返回值是一个address,
需要显示转化类型
后才能使用 - C c1形式,此时c1是空的,需要赋值地址才能使用,否则报错
pragma solidity ^0.4.24;
contract C1 {
uint256 public value ;
constructor(uint256 input) public {
value = input;
}
function getValue() public view returns(uint256) {
return value;
}
}
contract C2 {
C1 public c1; //0x0000000000000
C1 public c11; //0x0000000000000
C1 public c13;
function getValue1() public returns(uint256) {
//创建一个合约,返回地址
address addr1 = new C1(10); //balance , transfer方法
//return addr1.getValue();
//需要显示的转换为特定类型,才可以正常使用
c1 = C1(addr1);
return c1.getValue();
}
function getValue2() public returns(uint256) {
//定义合约的时候,同时完成类型转换
c11 = new C1(20);
return c11.getValue();
}
function getValue3(address addr) public returns(uint256) {
//传进来的地址必须是同类型的,如果是不是C1类型的,转换时报错
c13 = C1(addr);
return c13.getValue();
}
}
继承
- is关键字, 可以同时继承多个父合约。
- 当父合约存在同名函数时,默认为最远继承原则
- 可以指定某个父合约,调用它的方法
pragma solidity ^0.4.24;
contract baseA {
function getData() public pure returns(uint256) {
return 1;
}
}
contract baseB {
function getData() public pure returns(uint256) {
return 2;
}
}
contract sonA is baseA, baseB {
function getSonData() public pure returns(uint256){
return 3;
}
function getData3() public pure returns(uint256) {
return baseA.getData();
}
}
合约间如何转钱
如何使用一个合约向另一个合约转账。
pragma solidity ^0.4.24;
contract TestA {
string public message;
function invest(string _input) payable public {
message = _input;
}
function getBalanceA() public view returns(uint256) {
return address(this).balance;
}
}
contract TestB {
TestA public a1;
function setFeed(address addr)public{
a1 = TestA(addr);
}
function() public payable {
}
function Test() payable public{}
function pay() public {
//TestB调用TestA的invest方法时,如何转账给TestA?
//把TestB的钱转给TestA, 并不是调用pay函数人的钱
a1.invest.value(5 ether).gas(21000)("hangtou!");
}
function getBalanceB() public view returns(uint256) {
return address(this).balance;
}
}
internal和external
访问函数有外部(external)可见性。如果通过内部(internal)的方式访问,比如直接访问,你可以直接把它当一个变量进行使用,但如果使用外部(external)的方式来访问,如通过this.,那么它必须通过函数的方式来调用。
private , intenal , external, public 合约本身可以调用, 合约及子类可以调用, 只能在合约外部调用, 可以被任意的合约调用
元组(tuple)
return(a, b, c)
solidity无法返回自定义的数据结构,所以若想返回一个自定义结构的数据,需要在函数中一次返回多个值,即元组。元组是一个数据集合,类似于字典但是无法修改数据,使用圆括号包括多种数据类型。文章来源:https://www.toymoban.com/news/detail-436326.html
- 可以包含多个数据
- 类型可以不同
- 不可以修改
- 使用圆括号包裹
- new
创建对象,合约等文章来源地址https://www.toymoban.com/news/detail-436326.html
- delete
- delete操作符可以用于任何变量(map除外),将其设置成默认值
- 如果对动态数组使用delete,则删除所有元素,其长度变为0: uint[ ] array0 ; arry0 = new uint
- 如果对静态数组使用delete,则重置所有索引的值: uint[10] array1 = [1,2,3,4,5,6];
- 如果对map类型使用delete,什么都不会发生
- 但如果对map类型中的一个键使用delete,则会删除与该键相关的值
到了这里,关于【solidity三】Solidity中继承、创建合约和外部调用、合约事件event、solidity中元祖的使用、new、delete关键字的使用、solisity创建合约和外部调用的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!