以太坊解析-(1) 公鑰私鑰地址字符串公鑰推導(dǎo)

以太坊中私鑰和HASH都為32位意荤,公鑰為65位其中第一位是壓縮字節(jié)0x04啊片,壓縮公鑰為33字節(jié),地址是是公鑰的后64位hash后取后20個字節(jié)?作為地址玖像。簽名數(shù)據(jù)為65位紫谷,R,S各32位捐寥,65位為0和1.?

生成私鑰

//生成私鑰
    key, err := crypto.GenerateKey()
    if err != nil {
        t.Fatalf("failed GenerateKey with %s.", err)
    }
  //帶有0x的私鑰
    fmt.Println("private key have 0x   \n", hexutil.Encode(crypto.FromECDSA(key)))
    //不含0x的私鑰
    fmt.Println("private key no 0x \n", hex.EncodeToString(crypto.FromECDSA(key)))
private key have 0x   
 0xb1fb9a42d8478cf19bbc1cb4e75625ced1728c8de8691845f546b2ad84a7d379
private key no 0x 
 b1fb9a42d8478cf19bbc1cb4e75625ced1728c8de8691845f546b2ad84a7d379

私鑰存儲

//本地生成privatekey文件,保存私鑰
    if err := crypto.SaveECDSA("privatekey", key); err != nil {
        log.Error(fmt.Sprintf("Failed to persist node key: %v", err))
    }
b1fb9a42d8478cf19bbc1cb4e75625ced1728c8de8691845f546b2ad84a7d379

公鑰16進(jìn)制打印

    fmt.Println("public key have 0x   \n", hexutil.Encode(crypto.FromECDSAPub(&key.PublicKey)))
    fmt.Println("public key no 0x \n", hex.EncodeToString(crypto.FromECDSAPub(&key.PublicKey)))
public key have 0x   
 0x0425b775a01b5df335cd71170f6a16d8b43704e68b8eb87a8e6ebfd3deafbfc1151d76bbe078002ffb7caaca06441b1c3976c3ca3b1e1fda9cf0f4591d799758e4
public key no 0x 
 0425b775a01b5df335cd71170f6a16d8b43704e68b8eb87a8e6ebfd3deafbfc1151d76bbe078002ffb7caaca06441b1c3976c3ca3b1e1fda9cf0f4591d799758e4

字符串轉(zhuǎn)私鑰和地址

    //由私鑰字符串轉(zhuǎn)換私鑰和地址
    //由私鑰字符串轉(zhuǎn)換私鑰
    acc1Key, _ := crypto.HexToECDSA("8a1f9a8f95be41cd7ccb6168179afb4504aefe388d1e14474d32c45c72ce7b7a")
    address1 := crypto.PubkeyToAddress(acc1Key.PublicKey)
    fmt.Println("address ", address1.String())

    dummyAddr := common.HexToAddress("9b2055d370f73ec7d8a03e965129118dc8f5bf83")
    fmt.Println("dummyAddr",dummyAddr.String())
address  0x703c4b2bD70c169f5717101CaeE543299Fc946C7
dummyAddr 0x9B2055d370F73eC7d8a03E965129118dC8F5bf83

字節(jié)轉(zhuǎn)HASH和地址

    //字節(jié)轉(zhuǎn)地址
    addr3      := common.BytesToAddress([]byte("ethereum"))
    fmt.Println("address ",addr3.String())

    //字節(jié)轉(zhuǎn)hash
    hash1 := common.BytesToHash([]byte("topic1"))
    fmt.Println("hash ",hash1.String())
address  0x000000000000000000000000657468657265756D
hash  0x0000000000000000000000000000000000000000000000000000746f70696331

簽名和摘要推出公鑰

    var testAddrHex = "970e8128ab834e8eac17ab8e3812f010678cf791"
    var testPrivHex = "289c2857d4598e37fb9647507e47a309d6133539bf21a8b9cb6df88fd5232032"
    key1, _ := crypto.HexToECDSA(testPrivHex)
    addrtest := common.HexToAddress(testAddrHex)

    msg := crypto.Keccak256([]byte("foo"))
    sig, err := crypto.Sign(msg, key1)
    //推出公鑰字節(jié)
    recoveredPub, err := crypto.Ecrecover(msg, sig)
    //字節(jié)轉(zhuǎn)公鑰
    pubKey, _ := crypto.UnmarshalPubkey(recoveredPub)
    recoveredAddr := crypto.PubkeyToAddress(*pubKey)

    // 摘要和簽名推出公鑰
    recoveredPub2, _ := crypto.SigToPub(msg, sig)
    recoveredAddr2 := crypto.PubkeyToAddress(*recoveredPub2)

    fmt.Println("addrtest ",addrtest.String())
    fmt.Println("recoveredAddr ",recoveredAddr.String())
    fmt.Println("recoveredAddr2 ",recoveredAddr2.String())
addrtest  0x970E8128AB834E8EAC17Ab8E3812F010678CF791
recoveredAddr  0x970E8128AB834E8EAC17Ab8E3812F010678CF791
recoveredAddr2  0x970E8128AB834E8EAC17Ab8E3812F010678CF791

壓縮公鑰

//壓縮公鑰為33字節(jié)
compressed := CompressPubkey(key)
// 解壓縮33字節(jié)數(shù)據(jù)為公鑰
DecompressPubkey

完整代碼

在以太坊頂級目錄新建test目錄,新建file_test.go文件,拷貝代碼即可運行

package test

import (
    "encoding/hex"
    "fmt"
    "github.com/ethereum/go-ethereum/common"
    "github.com/ethereum/go-ethereum/common/hexutil"
    "github.com/ethereum/go-ethereum/crypto"
    "github.com/ethereum/go-ethereum/log"
    "testing"
)

func TestGenerateKey(t *testing.T) {
    key, err := crypto.GenerateKey()
    if err != nil {
        t.Fatalf("failed GenerateKey with %s.", err)
    }

    fmt.Println("private key have 0x   \n", hexutil.Encode(crypto.FromECDSA(key)))
    fmt.Println("private key no 0x \n", hex.EncodeToString(crypto.FromECDSA(key)))

    if err := crypto.SaveECDSA("privatekey", key); err != nil {
        log.Error(fmt.Sprintf("Failed to persist node key: %v", err))
    }

    fmt.Println("public key have 0x   \n", hexutil.Encode(crypto.FromECDSAPub(&key.PublicKey)))
    fmt.Println("public key no 0x \n", hex.EncodeToString(crypto.FromECDSAPub(&key.PublicKey)))

    //由私鑰字符串轉(zhuǎn)換私鑰
    acc1Key, _ := crypto.HexToECDSA("8a1f9a8f95be41cd7ccb6168179afb4504aefe388d1e14474d32c45c72ce7b7a")
    address1 := crypto.PubkeyToAddress(acc1Key.PublicKey)
    fmt.Println("address ", address1.String())

    dummyAddr := common.HexToAddress("9b2055d370f73ec7d8a03e965129118dc8f5bf83")
    fmt.Println("dummyAddr",dummyAddr.String())

    //字節(jié)轉(zhuǎn)地址
    addr3      := common.BytesToAddress([]byte("ethereum"))
    fmt.Println("address ",addr3.String())

    //字節(jié)轉(zhuǎn)hash
    hash1 := common.BytesToHash([]byte("topic1"))
    fmt.Println("hash ",hash1.String())


    var testAddrHex = "970e8128ab834e8eac17ab8e3812f010678cf791"
    var testPrivHex = "289c2857d4598e37fb9647507e47a309d6133539bf21a8b9cb6df88fd5232032"
    key1, _ := crypto.HexToECDSA(testPrivHex)
    addrtest := common.HexToAddress(testAddrHex)

    msg := crypto.Keccak256([]byte("foo"))
    sig, err := crypto.Sign(msg, key1)
    recoveredPub, err := crypto.Ecrecover(msg, sig)
    pubKey, _ := crypto.UnmarshalPubkey(recoveredPub)
    recoveredAddr := crypto.PubkeyToAddress(*pubKey)

    // should be equal to SigToPub
    recoveredPub2, _ := crypto.SigToPub(msg, sig)
    recoveredAddr2 := crypto.PubkeyToAddress(*recoveredPub2)

    fmt.Println("addrtest ",addrtest.String())
    fmt.Println("recoveredAddr ",recoveredAddr.String())
    fmt.Println("recoveredAddr2 ",recoveredAddr2.String())
}

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末笤昨,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子握恳,更是在濱河造成了極大的恐慌瞒窒,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,826評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件乡洼,死亡現(xiàn)場離奇詭異崇裁,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)束昵,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,968評論 3 395
  • 文/潘曉璐 我一進(jìn)店門拔稳,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人锹雏,你說我怎么就攤上這事壳炎。” “怎么了?”我有些...
    開封第一講書人閱讀 164,234評論 0 354
  • 文/不壞的土叔 我叫張陵匿辩,是天一觀的道長腰耙。 經(jīng)常有香客問我,道長铲球,這世上最難降的妖魔是什么挺庞? 我笑而不...
    開封第一講書人閱讀 58,562評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮稼病,結(jié)果婚禮上选侨,老公的妹妹穿的比我還像新娘。我一直安慰自己然走,他們只是感情好援制,可當(dāng)我...
    茶點故事閱讀 67,611評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著芍瑞,像睡著了一般晨仑。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上拆檬,一...
    開封第一講書人閱讀 51,482評論 1 302
  • 那天洪己,我揣著相機(jī)與錄音,去河邊找鬼竟贯。 笑死答捕,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的屑那。 我是一名探鬼主播拱镐,決...
    沈念sama閱讀 40,271評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼持际!你這毒婦竟也來了痢站?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,166評論 0 276
  • 序言:老撾萬榮一對情侶失蹤选酗,失蹤者是張志新(化名)和其女友劉穎阵难,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體芒填,經(jīng)...
    沈念sama閱讀 45,608評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡呜叫,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,814評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了殿衰。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片朱庆。...
    茶點故事閱讀 39,926評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖闷祥,靈堂內(nèi)的尸體忽然破棺而出娱颊,到底是詐尸還是另有隱情傲诵,我是刑警寧澤,帶...
    沈念sama閱讀 35,644評論 5 346
  • 正文 年R本政府宣布箱硕,位于F島的核電站拴竹,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏剧罩。R本人自食惡果不足惜栓拜,卻給世界環(huán)境...
    茶點故事閱讀 41,249評論 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望惠昔。 院中可真熱鬧幕与,春花似錦、人聲如沸镇防。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,866評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽来氧。三九已至诫给,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間饲漾,已是汗流浹背蝙搔。 一陣腳步聲響...
    開封第一講書人閱讀 32,991評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留僚楞,地道東北人枉层。 一個月前我還...
    沈念sama閱讀 48,063評論 3 370
  • 正文 我出身青樓泉褐,卻偏偏與公主長得像,于是被迫代替她去往敵國和親鸟蜡。 傳聞我的和親對象是個殘疾皇子膜赃,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,871評論 2 354