mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-26 06:36:43 +00:00
crypto/crypto, cmd/geth: added checksumaddress
This commit is contained in:
parent
83fc6fdb34
commit
8021a17879
3 changed files with 169 additions and 4 deletions
|
|
@ -170,7 +170,7 @@ nodes.
|
||||||
func accountList(ctx *cli.Context) error {
|
func accountList(ctx *cli.Context) error {
|
||||||
stack := utils.MakeNode(ctx, clientIdentifier, gitCommit)
|
stack := utils.MakeNode(ctx, clientIdentifier, gitCommit)
|
||||||
for i, acct := range stack.AccountManager().Accounts() {
|
for i, acct := range stack.AccountManager().Accounts() {
|
||||||
fmt.Printf("Account #%d: {%x} %s\n", i, acct.Address, acct.File)
|
fmt.Printf("Account #%d: %s %s\n", i, crypto.ChecksumAddress(acct.Address), acct.File)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
@ -268,7 +268,7 @@ func accountCreate(ctx *cli.Context) error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
utils.Fatalf("Failed to create account: %v", err)
|
utils.Fatalf("Failed to create account: %v", err)
|
||||||
}
|
}
|
||||||
fmt.Printf("Address: {%x}\n", account.Address)
|
fmt.Printf("Address: %s\n", crypto.ChecksumAddress(account.Address))
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -303,7 +303,7 @@ func importWallet(ctx *cli.Context) error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
utils.Fatalf("%v", err)
|
utils.Fatalf("%v", err)
|
||||||
}
|
}
|
||||||
fmt.Printf("Address: {%x}\n", acct.Address)
|
fmt.Printf("Address: %s\n", crypto.ChecksumAddress(acct.Address))
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -322,6 +322,6 @@ func accountImport(ctx *cli.Context) error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
utils.Fatalf("Could not create the account: %v", err)
|
utils.Fatalf("Could not create the account: %v", err)
|
||||||
}
|
}
|
||||||
fmt.Printf("Address: {%x}\n", acct.Address)
|
fmt.Printf("Address: %s\n", crypto.ChecksumAddress(acct.Address))
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -36,6 +36,9 @@ import (
|
||||||
"github.com/ethereum/go-ethereum/crypto/sha3"
|
"github.com/ethereum/go-ethereum/crypto/sha3"
|
||||||
"github.com/ethereum/go-ethereum/rlp"
|
"github.com/ethereum/go-ethereum/rlp"
|
||||||
"golang.org/x/crypto/ripemd160"
|
"golang.org/x/crypto/ripemd160"
|
||||||
|
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
func Keccak256(data ...[]byte) []byte {
|
func Keccak256(data ...[]byte) []byte {
|
||||||
|
|
@ -222,3 +225,31 @@ func zeroBytes(bytes []byte) {
|
||||||
bytes[i] = 0
|
bytes[i] = 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ChecksumAddress converts an address into a checksummed address.
|
||||||
|
// It returns a 42-letter string starting with "0x".
|
||||||
|
// The checksum algorithm is discussed in https://github.com/ethereum/EIPs/issues/55
|
||||||
|
func ChecksumAddress(a common.Address) string {
|
||||||
|
// hex.EncodeToString is always lower case without 0x prefix
|
||||||
|
address := hex.EncodeToString(a[:])
|
||||||
|
// skip the "0x" at the beginning
|
||||||
|
addressHash := hex.EncodeToString(Sha3([]byte(a.Hex()[2:])))
|
||||||
|
checksumAddress := "0x"
|
||||||
|
for i := 0; i < len(address); i++ {
|
||||||
|
// If ith character is 8 to f then make it uppercase
|
||||||
|
l, _ := strconv.ParseInt(string(addressHash[i]), 16, 16)
|
||||||
|
if l > 7 {
|
||||||
|
checksumAddress += strings.ToUpper(string(address[i]))
|
||||||
|
} else {
|
||||||
|
checksumAddress += string(address[i])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return checksumAddress
|
||||||
|
}
|
||||||
|
|
||||||
|
// ChecksumAddressHex converts an address into a checksummed address.
|
||||||
|
// The input s may or may not be prefixed with "0x".
|
||||||
|
// The returned string is 42 long and always includes the prefix "0x".
|
||||||
|
func ChecksumAddressHex(s string) string {
|
||||||
|
return ChecksumAddress(common.HexToAddress(s))
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -247,3 +247,137 @@ func TestPythonIntegration(t *testing.T) {
|
||||||
fmt.Printf("msg: %x, privkey: %x sig: %x\n", msg0, k1, sig0)
|
fmt.Printf("msg: %x, privkey: %x sig: %x\n", msg0, k1, sig0)
|
||||||
fmt.Printf("msg: %x, privkey: %x sig: %x\n", msg1, k1, sig1)
|
fmt.Printf("msg: %x, privkey: %x sig: %x\n", msg1, k1, sig1)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TestChecksumAddress performs 4 groups of tests: a) all caps,
|
||||||
|
// b) all lower, c) mixed lower and upper case, and
|
||||||
|
// d) examples taken from myetherwallet.com
|
||||||
|
func TestChecksumAddress(t *testing.T) {
|
||||||
|
testcases := []string{
|
||||||
|
"0x52908400098527886E0F7030069857D2E4169EE7",
|
||||||
|
"0x8617E340B3D01FA5F11F306F4090FD50E238070D",
|
||||||
|
|
||||||
|
"0xde709f2102306220921060314715629080e2fb77",
|
||||||
|
"0x27b1fdb04752bbc536007a920d24acb045561c26",
|
||||||
|
|
||||||
|
"0x5aAeb6053F3E94C9b9A09f33669435E7Ef1BeAed",
|
||||||
|
"0xfB6916095ca1df60bB79Ce92cE3Ea74c37c5d359",
|
||||||
|
"0xdbF03B407c01E7cD3CBea99509d93f8DDDC8C6FB",
|
||||||
|
"0xD1220A0cf47c7B9Be7A2E6BA89F429762e7b9aDb",
|
||||||
|
|
||||||
|
"0x5A4EAB120fB44eb6684E5e32785702FF45ea344D",
|
||||||
|
"0x5be4BDC48CeF65dbCbCaD5218B1A7D37F58A0741",
|
||||||
|
"0xa7dD84573f5ffF821baf2205745f768F8edCDD58",
|
||||||
|
"0x027a49d11d118c0060746F1990273FcB8c2fC196",
|
||||||
|
"0x689E3fE51F45760Ab73D237d28fc1d2C8EaC6D71",
|
||||||
|
"0x97D509F0b388daE6D000C33193F4645D1e71Dc54",
|
||||||
|
"0xa4Fd5bD20Cf5A7CF1c5A6015D2b3e08A3eC1b1a7",
|
||||||
|
"0x230AE42Daf56B494E4b9E6D8Cce99F5E14FE29c1",
|
||||||
|
"0xC19D1EDB7FC943f2abbF576f6058c2425B347AB9",
|
||||||
|
"0x4f936Bb00CaaD116adc3861146dd8f68BF66F4E6",
|
||||||
|
"0xE74287ECA7B7151Fd194cdf7680EB50752671c47",
|
||||||
|
"0x5d32a30FBc5bddF39293CE3a9D74E4505dEb621D",
|
||||||
|
"0x27cBC66cbE3625c2857ce3CF77A9933e589545DF",
|
||||||
|
"0xE2A5f301EA7e461880Fe9A6B4b7EC1aBD023129A",
|
||||||
|
"0xe0DFdDA1D174aB7315C753EA198885ee88B52763",
|
||||||
|
"0x843655C78939365298FD9515b489939bADca64Ec",
|
||||||
|
"0x6bB7a54E4ef381e4C64009DDa0A9ED127aab852C",
|
||||||
|
}
|
||||||
|
|
||||||
|
failed, passed := 0, 0
|
||||||
|
for i := 0; i < len(testcases); i++ {
|
||||||
|
ca := ChecksumAddress(common.HexToAddress(testcases[i]))
|
||||||
|
if testcases[i] == ca {
|
||||||
|
passed++
|
||||||
|
} else {
|
||||||
|
failed++
|
||||||
|
t.Errorf("Failed to compute ChecksumAddress for address " + testcases[i] + ": \n\tExpected=" + testcases[i] + "\n\tReceived=" + ca)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fmt.Printf("Passed %d tests and failed %d tests out of %d.\n", passed, failed, passed+failed)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestChecksumAddressHex(t *testing.T) {
|
||||||
|
testcases := []string{
|
||||||
|
"0x52908400098527886E0F7030069857D2E4169EE7",
|
||||||
|
"0x8617E340B3D01FA5F11F306F4090FD50E238070D",
|
||||||
|
|
||||||
|
"0xde709f2102306220921060314715629080e2fb77",
|
||||||
|
"0x27b1fdb04752bbc536007a920d24acb045561c26",
|
||||||
|
|
||||||
|
"0x5aAeb6053F3E94C9b9A09f33669435E7Ef1BeAed",
|
||||||
|
"0xfB6916095ca1df60bB79Ce92cE3Ea74c37c5d359",
|
||||||
|
"0xdbF03B407c01E7cD3CBea99509d93f8DDDC8C6FB",
|
||||||
|
"0xD1220A0cf47c7B9Be7A2E6BA89F429762e7b9aDb",
|
||||||
|
|
||||||
|
"0x5A4EAB120fB44eb6684E5e32785702FF45ea344D",
|
||||||
|
"0x5be4BDC48CeF65dbCbCaD5218B1A7D37F58A0741",
|
||||||
|
"0xa7dD84573f5ffF821baf2205745f768F8edCDD58",
|
||||||
|
"0x027a49d11d118c0060746F1990273FcB8c2fC196",
|
||||||
|
"0x689E3fE51F45760Ab73D237d28fc1d2C8EaC6D71",
|
||||||
|
"0x97D509F0b388daE6D000C33193F4645D1e71Dc54",
|
||||||
|
"0xa4Fd5bD20Cf5A7CF1c5A6015D2b3e08A3eC1b1a7",
|
||||||
|
"0x230AE42Daf56B494E4b9E6D8Cce99F5E14FE29c1",
|
||||||
|
"0xC19D1EDB7FC943f2abbF576f6058c2425B347AB9",
|
||||||
|
"0x4f936Bb00CaaD116adc3861146dd8f68BF66F4E6",
|
||||||
|
"0xE74287ECA7B7151Fd194cdf7680EB50752671c47",
|
||||||
|
"0x5d32a30FBc5bddF39293CE3a9D74E4505dEb621D",
|
||||||
|
"0x27cBC66cbE3625c2857ce3CF77A9933e589545DF",
|
||||||
|
"0xE2A5f301EA7e461880Fe9A6B4b7EC1aBD023129A",
|
||||||
|
"0xe0DFdDA1D174aB7315C753EA198885ee88B52763",
|
||||||
|
"0x843655C78939365298FD9515b489939bADca64Ec",
|
||||||
|
"0x6bB7a54E4ef381e4C64009DDa0A9ED127aab852C",
|
||||||
|
}
|
||||||
|
|
||||||
|
failed, passed := 0, 0
|
||||||
|
for i := 0; i < len(testcases); i++ {
|
||||||
|
ca := ChecksumAddressHex(testcases[i])
|
||||||
|
if testcases[i] == ca {
|
||||||
|
passed++
|
||||||
|
} else {
|
||||||
|
failed++
|
||||||
|
t.Errorf("Failed to compute ChecksumAddressHex for address " + testcases[i] + ": \n\tExpected=" + testcases[i] + "\n\tReceived=" + ca)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
testcases = []string{
|
||||||
|
"52908400098527886E0F7030069857D2E4169EE7",
|
||||||
|
"8617E340B3D01FA5F11F306F4090FD50E238070D",
|
||||||
|
|
||||||
|
"de709f2102306220921060314715629080e2fb77",
|
||||||
|
"27b1fdb04752bbc536007a920d24acb045561c26",
|
||||||
|
|
||||||
|
"5aAeb6053F3E94C9b9A09f33669435E7Ef1BeAed",
|
||||||
|
"fB6916095ca1df60bB79Ce92cE3Ea74c37c5d359",
|
||||||
|
"dbF03B407c01E7cD3CBea99509d93f8DDDC8C6FB",
|
||||||
|
"D1220A0cf47c7B9Be7A2E6BA89F429762e7b9aDb",
|
||||||
|
|
||||||
|
"5A4EAB120fB44eb6684E5e32785702FF45ea344D",
|
||||||
|
"5be4BDC48CeF65dbCbCaD5218B1A7D37F58A0741",
|
||||||
|
"a7dD84573f5ffF821baf2205745f768F8edCDD58",
|
||||||
|
"027a49d11d118c0060746F1990273FcB8c2fC196",
|
||||||
|
"689E3fE51F45760Ab73D237d28fc1d2C8EaC6D71",
|
||||||
|
"97D509F0b388daE6D000C33193F4645D1e71Dc54",
|
||||||
|
"a4Fd5bD20Cf5A7CF1c5A6015D2b3e08A3eC1b1a7",
|
||||||
|
"230AE42Daf56B494E4b9E6D8Cce99F5E14FE29c1",
|
||||||
|
"C19D1EDB7FC943f2abbF576f6058c2425B347AB9",
|
||||||
|
"4f936Bb00CaaD116adc3861146dd8f68BF66F4E6",
|
||||||
|
"E74287ECA7B7151Fd194cdf7680EB50752671c47",
|
||||||
|
"5d32a30FBc5bddF39293CE3a9D74E4505dEb621D",
|
||||||
|
"27cBC66cbE3625c2857ce3CF77A9933e589545DF",
|
||||||
|
"E2A5f301EA7e461880Fe9A6B4b7EC1aBD023129A",
|
||||||
|
"e0DFdDA1D174aB7315C753EA198885ee88B52763",
|
||||||
|
"843655C78939365298FD9515b489939bADca64Ec",
|
||||||
|
"6bB7a54E4ef381e4C64009DDa0A9ED127aab852C",
|
||||||
|
}
|
||||||
|
|
||||||
|
for i := 0; i < len(testcases); i++ {
|
||||||
|
ca := ChecksumAddressHex(testcases[i])
|
||||||
|
if "0x"+testcases[i] == ca {
|
||||||
|
passed++
|
||||||
|
} else {
|
||||||
|
failed++
|
||||||
|
t.Errorf("Failed to compute ChecksumAddressHex for address " + testcases[i] + ": \n\tExpected=" + testcases[i] + "\n\tReceived=" + ca)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fmt.Printf("Passed %d tests and failed %d tests out of %d.\n", passed, failed, passed+failed)
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue