从零构建以太坊(Ethereum)智能合约到项目实战——学习笔记7
P28 、1-Solidity Types - 地址(Address) - 初识
以太坊钱钱包地址位数验证
以太坊中的地址的长度为20字节,一字节等于8位,一共160位,所以address其实亦可以用uint160来声明。
备注:以太坊钱包地址是以16进制的形式呈现,我们知道一个十六进制的数字等于4个字节,
160/4=40。
我的以太坊地址:40*4=160位
//address:0x70D50B5B472fEca307831eD3bF0bcc24fE9339E1
//uint160:644158014355021713829634535757592778847062014433
pragma solidity ^0.4.4; contract Test{ address _owner; uint160 _ownerUint; function Test(){ _owner=0x70D50B5B472fEca307831eD3bF0bcc24fE9339E1; _ownerUint=644158014355021713829634535757592778847062014433; } function owner() constant returns(address){ return _owner; } function ownerUint160() constant returns(uint160){ return uint160(_owner); } function ownerUintToAddress() constant returns(address){ return address(_ownerUint); } }
P29 、2-Solidity Types - 地址(Address) - msg.P 、sender
不可不知的几个常识
pragma solidity ^0.4.4; contract Test{ address public _owner; uint public _number; function Test(){ _owner=msg.sender;//第一次部署合约的地址 _number=100; } function msgSenserAddress() constant returns(address){ return msg.sender;//调取消息的当前地址 } function setNumbeAdd1(){ _number = _number+5; } function setNumbeAdd2(){ if(msg.sender==_owner){ _number = _number+10; } } }
P30 、3-Solidity Types - 地址(Address) - 论合约地址与this指针
合约拥有者
msg.sender就是当前调用方法时的发起人,一个合约部署后,通过钱包地址操作合约的人很多,但是如何正确判断谁是合约的拥有者,判断方法很简单,就是第一次部署合约时,谁出的gas,谁就对合约具有拥有权。
合约地址
一个合约部署后,会有一个合约地址,这个合约地址就代表合约自己。
this是人还是鬼
this在合约中到底是msg.sender还是合约地址,this即是当前合约地址。
pragma solidity ^0.4.4; contract Test{ address public _owner; uint public _number; function Test(){ _owner=msg.sender;//第一次部署合约的地址 _number=100; } function msgSenserAddress() constant returns(address){ return msg.sender;//调取消息的当前地址 } function setNumbeAdd1(){ _number = _number+5; } function setNumbeAdd2(){ if(msg.sender==_owner){ _number = _number+10; } } function returnContractAddress() constant returns(address){ return this; } }
P31 、4-Solidity Types - 地址(Address) - 运算符
支持的运算符:<=、<、==、!=、>=和>
pragma solidity ^0.4.4; contract Test{ address address1; address address2; // <= < == != >= > function Test(){ address1=0xca35b7d915458ef540ade6068dfe2f44e8fa733c; address2=0x14723a09acff6d2a60dcdf7aa4aff308fddc160c; } // <= function test1() constant returns(bool){ return address1<=address2; } // < function test2() constant returns(bool){ return address1<address2; } // == function test3() constant returns(bool){ return address1==address2; } // != function test4() constant returns(bool){ return address1!=address2; } // >= function test5() constant returns(bool){ return address1>=address2; } // > function test6() constant returns(bool){ return address1>address2; } }
P32 、5-Solidity Types - 地址(Address) - balance查看余额
成员变量和函数
一、balance
如果我们需要查看一个地址的余额,我们可以使用balance属性进行查看。
pragma solidity ^0.4.4; contract addressBalance{ //0xca35b7d915458ef540ade6068dfe2f44e8fa733c function getBalance(address addr) constant returns(uint){ return addr.balance; } }
1 eth = 10^8 wei
备注:合约地址也是合法的钱包地址
P33 、6-Solidity Types - 地址(Address) - transfer转账
三、transfer
transfer:从合约发起方向某个地址转入以太币(单位是wei),地址无效或者合约发起方余额不足时,代码将抛出异常并停止转账。
pragma solidity ^0.4.4; contract PayableKeyword{ //从合约发起方 向 0xca35b7d915458ef540ade6068dfe2f44e8fa733c 地址转入 msg.value 个以太币,单位wei function deposit() payable{ address Account3 = 0xca35b7d915458ef540ade6068dfe2f44e8fa733c; Account3.transfer(msg.value); } function getAccount3Balance() constant returns(uint){ address Account3 = 0xca35b7d915458ef540ade6068dfe2f44e8fa733c; return Account3.balance; } function getOwnerBalance() constant returns(uint){ address Owner = msg.sender; return Owner.balance; } }
P34 、7-Solidity Types - 地址(Address) - 通过send方法转账
四、send
send:send相对transfer方法较底层,不过使用方法和transfer相同,都是从合约发起方向某个地址转入以太币(单位是wei),地址无效或者合约发起方余额不足时,send不会抛出异常,而是直接返回false。
pragma solidity ^0.4.4; contract PayableKeyword{ //从合约发起方 向 0xca35b7d915458ef540ade6068dfe2f44e8fa733c 地址转入 msg.value 个以太币,单位wei function deposit() payable returns(bool){ address Account3 = 0xca35b7d915458ef540ade6068dfe2f44e8fa733c; return Account3.send(msg.value); } function getAccount3Balance() constant returns(uint){ address Account3 = 0xca35b7d915458ef540ade6068dfe2f44e8fa733c; return Account3.balance; } function getOwnerBalance() constant returns(uint){ address Owner = msg.sender; return Owner.balance; } }
Warning
send()方法执行时有一些风险
- 调用递归深度不能超过1024。
- 如果gas不够,执行会失败。
- 所以使用这个方法要检查成果与否。
- transfer相对send较安全。