Solidity address 地址
以太坊中的地址 address 的长度为20字节,一字节等于8位,一共160位,所以 address 也可以用 uint160 来声明。
我的以太坊钱包地址为 0xDF12793CA392ff748adF013D146f8dA73df6E304,0x代表十六进制,我们将 DF12793CA392ff748adF013D146f8dA73df6E304拷贝,如下图所示,将其进行二进制转换,不难发现,它的二进制刚好160位。
以太坊钱包地址是以 16 进制的形式呈现,我们知道一个十六进制的数字等于4 bit,所以以太坊钱包地址的十六进制表示法的长度为 160 / 4 = 40,例如:钱包地址DF12793CA392ff748adF013D146f8dA73df6E304的长度为40。
以太坊钱包地址:
0xDF12793CA392ff748adF013D146f8dA73df6E304
通过工具对应的二进制为:
1101111100010010011110010011110010100011100100110000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
通过工具转换的二进制可能存在问题,可以自己尝试转换。
pragma solidity ^0.4.4; contract test { address _owner; uint160 _ownerUint; function test() { _owner = 0xDF12793CA392ff748adF013D146f8dA73df6E304; _ownerUint = 1273516916528256943268872459582090959717186069252; } function owner() constant returns (address) { return _owner; } function ownerUint160() constant returns(uint160){ //转换10进制 1273516916528256943268872459582090959717186069252 return uint160(_owner); } function ownerUintToAddress() constant returns (address) { return address(_ownerUint); } } //0x 16进制 45 //B 2进制 0100 0101 //1 + 2 + 4 + 8 + 16 + 32 + 64 + 128 //1 + 0 + 4 + 0 + 0 + 0 + 64 + 0 = 69 //D 10进制 69 //0x DF12793CA392ff748adF013D146f8dA73df6E304 //D 转换10进制 1273516916528256943268872459582090959717186069252 //1 2 3 4 5 6 7 8 9 A B C D E F //40个 * 4位(二进制) =160位 //1101 1111 0001 0010 0111 10010011110010100011100100110000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 //1+4+8=13 D 1+2+4+8=15 F 1 2 1+2+4=7 .... //address //uint160
不可不知的几个常识
- 合约拥有者
msg.sender就是当前调用方法时的发起人,一个合约部署后,通过钱包地址操作合约的人很多,但是如何正确判断谁是合约的拥有者,判断方式很简单,就是第一次部署合约时,谁出的gas,谁就对合约具有拥有权。
pragma solidity ^0.4.4; contract Test { address public _owner; uint public _number; function Test() { _owner = msg.sender; _number = 100; } function msgSenderAddress() constant returns (address) { return msg.sender; } function setNumberAdd1() { _number = _number + 5; } function setNumberAdd2() { if (_owner == msg.sender) { _number = _number + 10; } } } //0x14723A09ACff6D2A60DcdF7aA4AFf308FDDC160C
- 合约地址
pragma solidity ^0.4.4; // 0x903ad08970c70d10e5fb5b3c26f7b714830afcf6 // 0x62e40877f4747e06197aa1a2b9ac06dd9bb244a3 // 0xf055775ebd516e7419ae486c1d50c682d4170645 // 0xe7795e05d15f7406baf411cafe766fc28eccf35f // 0xe7795e05d15f7406baf411cafe766fc28eccf35f contract Test { address public _owner; uint public _number; function Test() { _owner = msg.sender; _number = 100; } function msgSenderAddress() constant returns (address) { return msg.sender; } function setNumberAdd1() { _number = _number + 5; } function setNumberAdd2() { if (_owner == msg.sender) { _number = _number + 10; } } function returnContractAddress() constant returns (address) { return this; } }
一个合约部署后,会有一个合约地址,这个合约地址就代表合约自己。 this在合约中到底是msg.sender还是合约地址,由上图不难看出,this即是当前合约地址。
部署
在Remix网页编辑器中点击部署(Deploy)按钮
点击插件的submit
显示部署挖矿成功,钱包中的测试以太币也相应的减去部署需要花费的gas
支持的运算符
pragma solidity ^0.4.4; contract Test { address address1; address address2; // <=,<,==,!=,>=和> function Test() { address1 = 0xF055775eBD516e7419ae486C1d50C682d4170645; address2 = 0xEAEC9B481c60e8cDc3cdF2D342082C349E5D6318; } // <= 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; } }
- <=,<,==,!=,>=,>
成员变量和函数
-
一、 balance
如果我们需要查看一个地址的余额,我们可以使用balance属性进行查看。
pragma solidity ^0.4.4; contract addressBalance{ function getBalance(address addr) constant returns (uint){ return addr.balance; } }
在Account一栏中,会自动生成测试钱包地址供我们测试使用,在我们点击Deploy按钮时,Account一栏选中的是钱包地址,我们部署合约时,花费的gas就从这个钱包地址里面扣除,【PS:这5个钱包地址每次都是系统临时生成,所以在我们开发测试过程中,每次的地址不会相同】。因为在本案例中,我们部署合约时,用的是第一个Account,所以gas自然从它里面扣除,大家会发现,其它四个钱包地址中的余额是ether,而第一个钱包地址中不到100个ether。
当我们点击getBalance获取某个钱包地址的余额时,获取到的余额的单位是Wei,一个ether等于1000000000000000000Wei,Wei是最小单位,相当于我们的1元RMB等于100分。【PS:1ether等于10的18次方Wei】
99999999999996890347 wei == 99.999999999996890347 ether
- 二、this 查看当前合约地址余额
pragma solidity ^0.4.4; contract addressBalance{ function getBalance() constant returns (uint){ return this.balance; } function getContractAddrees() constant returns (address){ return this; } function getBalance(address addr) constant returns (uint){ return addr.balance; } }
- 三、transfer
transfer:从合约发起方向某个地址转入以太币(单位是wei),地址无效或者合约发起方余额不足时,代码将抛出异常并停止转账。
pragma solidity ^0.4.4; contract PayableKeyword{ // 从合约发起方向 0x14723a09acff6d2a60dcdf7aa4aff308fddc160c 地址转入 msg.value 个以太币,单位是 wei function deposit() payable{ address Account2 = 0x14723a09acff6d2a60dcdf7aa4aff308fddc160c; Account2.transfer(msg.value); } // 读取 0x14723a09acff6d2a60dcdf7aa4aff308fddc160c 地址的余额 function getAccount2Balance() constant returns (uint) { address Account2 = 0x14723a09acff6d2a60dcdf7aa4aff308fddc160c; return Account2.balance; } // 读取合约发起方的余额 function getOwnerBalance() constant returns (uint) { address Owner = msg.sender; return Owner.balance; } }
- 四、send
send:send相对transfer方法较底层,不过使用方法和transfer相同,都是从合约发起方向某个地址转入以太币(单位是wei),地址无效或者合约发起方余额不足时,send不会抛出异常,而是直接返回false。
pragma solidity ^0.4.4; contract PayableKeyword{ function deposit() payable returns (bool){ address Account2 = 0x14723a09acff6d2a60dcdf7aa4aff308fddc160c; return Account2.send(msg.value); } function getAccount2Balance() constant returns (uint) { address Account2 = 0x14723a09acff6d2a60dcdf7aa4aff308fddc160c; return Account2.balance; } function getOwnerBalance() constant returns (uint) { address Owner = msg.sender; return Owner.balance; }
⚠️Warning
send()方法执行时有一些风险
- 调用递归深度不能超1024。
- 如果gas不够,执行会失败。
- 所以使用这个方法要检查成功与否。
- transfer相对send较安全
下一章:Solidity 众筹智能合约
Solidity 众筹智能合约,提供一个安全、完整的 Solidity 智能合约案例,用于通过众筹方式进行筹资。 1. 募资人 struct Donee用于表示一个募资项目,其中包括募资人地址、目标 ...