以太坊地址區分大小寫麼
以太坊地址區分大小寫麼?要搞清楚這個問題,我們不妨先在私鏈上做個實驗:
geth> eth.sendTransaction({ from: eth.accounts[0], to: "0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", value: web3.toWei(1, 'ether') }) geth> eth.sendTransaction({ from: eth.accounts[0], to: "0xAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", value: web3.toWei(1, 'ether') }) geth> eth.getBalance("0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa") geth> eth.getBalance("0xAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA")
從實驗結果上來看,純小寫地址和純大寫地址實際上是同一個地址,那麼是不是由此可以得出以太坊地址不區分大小寫呢?我們再看下面這個 ofollow,noindex" target="_blank">remix 上的實驗:
pragma solidity ^0.5.0; contract Foo { address bar = 0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa; }
程式碼執行結果如下圖所示:

remix
結果提示錯誤,並給了一個大小寫混合的正確地址:
This looks like an address but has an invalid checksum. Correct checksummed address: “0xaAaAaAaaAaAaAaaAaAAAAAAAAaaaAaAaAaaAaaAa”. If this is not used as an address, please prepend ’00’. For more information please see https://solidity.readthedocs.io/en/develop/types.html#address-literals
怎麼回事?實際上這是因為 EIP-55 規範引入了 checksum 機制。它有什麼用處?設想一下,如果你在輸入長長的以太坊地址的時候,不小心輸錯了一個字元,那麼很難發現這樣的錯誤,有了 checksum 機制,我們就能在業務程式裡校驗地址的準確性,從而降低使用者輸入錯誤地址的風險,給出一個 golang 程式碼的例子:
package main import ( "flag" "fmt" "github.com/ethereum/go-ethereum/common" ) var ( address = flag.String("address", "", "address") ) func init() { flag.Parse() } func main() { addressWithChecksum := common.HexToAddress(*address).Hex() if addressWithChecksum != *address { fmt.Println("valid: " + addressWithChecksum) fmt.Println("invalid: " + *address) } else { fmt.Println("This address is valid.") } }
程式碼執行結果如下圖所示:

checksum
如果你沒有 Golang 的執行環境,實際上還有更簡單的驗證方法:通過 Etherscan 來獲取帶 checksum 的地址,留意位址列中的地址和下面 Address 旁邊的地址:

etherscan
總結:以太坊地址本身不區分大小寫,但是出於安全性的考慮,我們應該儘可能使用符合 EIP-55 規範的地址,當然了,業務程式要有相應的 checksum 校驗邏輯才行。