网站首页 > 开源技术 正文
solidity高级语法
全局函数/变量
- 最重要的两个全局变量
- 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。如1 ether == 1000 finney的结果是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无法返回自定义的数据结构,所以若想返回一个自定义结构的数据,需要在函数中一次返回多个值,即元组。元组是一个数据集合,类似于字典但是无法修改数据,使用圆括号包括多种数据类型。
- 可以包含多个数据
- 类型可以不同
- 不可以修改
- 使用圆括号包裹
- new
创建对象,合约等
- delete
- delete操作符可以用于任何变量(map除外),将其设置成默认值
- 如果对动态数组使用delete,则删除所有元素,其长度变为0: uint[ ] array0 ; arry0 = new uint
- 如果对静态数组使用delete,则重置所有索引的值: uint[10] array1 = [1,2,3,4,5,6];
- 如果对map类型使用delete,什么都不会发生
- 但如果对map类型中的一个键使用delete,则会删除与该键相关的值
猜你喜欢
- 2024-09-30 「链块技术39期」以太坊智能合约语言(四):Solidity函数(上)
- 2024-09-30 学习 Solidity 智能合约开发 02:合约
- 2024-09-30 「干货」区块链技术分享:Solidity语言(七)
- 2024-09-30 Solidity的整数(solid size)
- 2024-09-30 了解Solidity语言基础知识(sol语言有哪些特点)
- 2024-09-30 solidity基本数据类型使用、主要关键字学习、address使用
- 2024-09-30 「链块技术36期」以太坊智能合约—Solidity概述和开发工具的使用
- 2024-09-30 区块链研究实验室 | 深入解析Solidity合约
- 2024-09-30 【干货】区块链技术分享:Solidity语言
- 2024-09-30 以太坊2.0进展:存款合约已经从Vyper重写为Solidity语言并重新验证
你 发表评论:
欢迎- 最近发表
- 标签列表
-
- jdk (81)
- putty (66)
- rufus (78)
- 内网穿透 (89)
- okhttp (70)
- powertoys (74)
- windowsterminal (81)
- netcat (65)
- ghostscript (65)
- veracrypt (65)
- asp.netcore (70)
- wrk (67)
- aspose.words (80)
- itk (80)
- ajaxfileupload.js (66)
- sqlhelper (67)
- express.js (67)
- phpmailer (67)
- xjar (70)
- redisclient (78)
- wakeonlan (66)
- tinygo (85)
- startbbs (72)
- webftp (82)
- vsvim (79)
本文暂时没有评论,来添加一个吧(●'◡'●)