区块链中级.以太坊开发
From:JamesZou & 传智播客研究院 & 传智播客区块链本文参考文档 ,官方中文文档,官方英文文档
思考:下面这个代码中的 luckNum 最后等于多少?
pragma solidity ^0.4.25;
contract ValueType{
function testValueType() public view returns(uint){
uint luckNum = 101;
uint loveNum = luckNum;
changeValue(luckNum);
return luckNum;
}
function changeValue(uint _num) private{
_num += 100;
}
}
storage
进行修饰。bool flag1 = true;
bool flag2 = false;
int(有符号整型,有正有负)
uint(无符号整型,无负数)
以8位为区间,支持int8,int16,int24 至 int256,uint同理。
int默认为int256,uint默认为uint256
function intTest() public returns(int){
int8 i = 10;
int j = 10;
return i + j;
}
20个字节
,每个字节8位,20 * 8 = 160位
,所以可以用一个uint160
编码。地址是所有合约的基础,所有的合约都会继承地址对象,通过合约的地址串,调用合约内的函数。描述 | 符号 |
---|---|
比较运算符 | <=,<,==,!=,>=,> |
属性/方法 | 含义 | 备注 |
---|---|---|
balance(uint256) | 获取余额(wei) | 属性,其余的都是方法 |
transfer(uint256 value) | 给 address 转账 value(Wei),失败会抛异常 | 建议使用 |
send(uint256 value) | 和 transfer 类似,transfer 更常用,失败会返回false | 不建议使用 |
call | 合约内部调用合约 | |
delegatecall | 调底层代码,别用 | |
callcode | 调底层代码,别用 |
pragma solidity ^0.4.25;
contract Lover{
string outerMsg;
function(){
outerMsg = string(msg.data);
}
function getFail() returns (string){
return outerMsg;
}
}
contract CallLover{
function callData(address addr) returns (bool){
return addr.call("i love Ether ~~!");
}
}
注意:在 solidity 源码中,address 不需要加双引号。但在 Remix 的对话界面中输入 address 时,务必加上双引号,否则会报错
pragma solidity ^0.4.25;
contract addressTest{
function getBalance(address addr) constant public returns (uint){
return addr.balance;
}
}
合约地址 (this)
如果只是想返回当前合约账户的余额,可以使用this
指针,this
表示合约自身的地址
pragma solidity ^0.4.0;
contract addressTest{
function getBalance() constant public returns (uint){
//return addr.balance;
return this.balance; // <<----此处使用this代替
}
}
转账(send,transfer)
send和transfer函数提供了由合约向其他地址转账的功能。
对比项 | send | transfer | 备注 |
---|---|---|---|
参数 | 转账金额 | 转账金额 | wei单位 |
返回值 | true/false | 无(出错抛异常) | transfer更安全 |
pragma solidity ^0.4.25;
contract TransferTest {
function transfer123(address addr) payable {
addr.transfer(msg.value);
}
}
solidity内置了一些数组的数据类型:(和go语言做一下对比, var [8] byte),完全只读
bytes1
, … ,bytes32
,允许值以步长1递增。内置方法:length() -> 返回数组长度
存储方式:16进制ascii码
pragma solidity ^0.4.25;
//bytes1
contract fixedArray {
/*
1. 长度可以读取 length
2. 长度不可以修改
3. 可以通过下标访问
4. 内容不可修改
*/
//bytes1 ... bytes32
//bytes1 b1 = "xy";
bytes2 b2 = "xy";
bytes3 public b3 = "xy";
uint public len = b3.length;
//b3.length = 10;
bytes8 b8 = "12345678";
//b8_0返回0x31,即十进制的数字1的ascii值(3*16+1=49)
bytes1 public b8_0 = b8[0];
//b = "HELLO";ERROR,定义之后不可修改
//b8[1] = "0";
//b8= "4567";
}
描述 | 符号 |
---|---|
比较运算 | <=,<,==,!=,>=,> |
位运算符 | &,|,^(异或),~非 |
下标访问 | [0,n),n表示长度 |
bytes:不定长度的字节数组 (Dynamically-sized byte array)
bytes类型可以使用 push() 方法,具有 length 属性
string public name = "itheima.com";
bytes public g = 0x6c697975656368756e;
// 初始化一个两个字节空间的字节数组
bytes public name = new bytes(2);
string public str01 = "itheima.com";
function getStrLegnth(string _str) constant returns (uint) {
return bytes(_str).length; // 强制转换string为bytes
}
pragma solidity ^0.4.0;
contract test {
enum WeekDays {
Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday
}
WeekDays currentDay;
WeekDays defaultday = WeekDays.Sunday;
function setDay(weekDays _day) public {
currentDay = _day;
}
function getDay() public view returns(uint256) {
return uint256(currentDay);
}
function getDefaultDay() public view returns(uint256) {
return uint256(defaultday);
}
}
当做变量赋值
,当做函数参数传递
,当做返回值
。修饰符 | 说明 |
---|---|
public | 公有,任何人(拥有以太坊账户的)都可以调用 |
private | 私有, 只有智能合约内部可以调用 |
external | 仅合约外部可以调用,合约内部需使用this调用 |
internal | 仅合约内部和继承的合约可以调用 |
view/constant | 函数会读取但是不会修改任何contract的状态变量 |
pure | 函数不使用任何智能合约的状态变量 |
payable | 调用函数需要付钱,钱付给了智能合约的账户 |
returns | 返回值函数声明中使用 |
注意,所有在合约内的东西对外部的观察者来说都是可见,将某些东西标记为private
仅仅阻止了其它合约来进行访问和修改,但并不能阻止其它人看到相关的信息。
一个合约可以有且只有一个匿名函数,此函数不能有参数,也不能有任何返回值,当我们企图去执行一个合约上没有的函数时,那么合约就会执行这个匿名函数。
当合约在只收到以太币的时候,也会调用这个匿名函数,而且一般情况下会消耗很少的gas,所以当你接收到以太币后,想要执行一些操作的话,你尽可以把你想要的操作写到这个匿名函数里,因为这样做成本非常便宜。
//如果想向合约转账,在合约中添加如下函数即可
function() payable {
//函数体什么都不填
}