地址Address
以太坊錢包地址位數驗證
以太坊中的地址的長度爲20字節
,一字節等於8位
,一共160位
,所以address
其實亦可以用uint160
來聲明。
我的以太坊錢包地址爲0xDF12793CA392ff748adF013D146f8dA73df6E304
,0x
代表十六進制
,我們將DF12793CA392ff748adF013D146f8dA73df6E304
拷貝,如下圖所示,將其進行二進制轉換,不難發現,它的二進制剛好160位
。
備註:以太坊錢包地址
是以16進制
的形式呈現,我們知道一個十六進制的數字等於4個字節
,160 / 4 = 40,你自己驗證一下,錢包地址
DF12793CA392ff748adF013D146f8dA73df6E304的長度爲40
。
以太坊錢包地址
0xDF12793CA392ff748adF013D146f8dA73df6E304
通過工具對應的二進制爲:
1101111100010010011110010011110010100011100100110000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
ps:通過工具轉換的二進制可能存在問題,可以自己嘗試轉換。
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較安全