助记词创建以太坊钱包源码_墨客科普 | MOAC区块链钱包账号管理
本文簡(jiǎn)單描述錢包賬號(hào)管理的一些方法。
一、術(shù)語(yǔ)
1.1 gas,Gas Limit和Gas Price
在墨客區(qū)塊鏈上,發(fā)送代幣或調(diào)用智能合約、執(zhí)行寫入操作,需要支付礦工計(jì)算費(fèi)用,計(jì)費(fèi)是按照Gas計(jì)算的,Gas使用moac來(lái)支付。無(wú)論調(diào)用的方法是成功還是失敗,都需要支付計(jì)算費(fèi)用。即使失敗,礦工也驗(yàn)證并執(zhí)行交易(計(jì)算),因此必須和成功交易一樣支付礦工費(fèi)。
Gas Limit稱為限額,它是用戶愿意在一筆交易中花費(fèi)Gas的最大數(shù)量。交易所需的Gas是通過(guò)調(diào)用智能合約執(zhí)行多少代碼來(lái)定義。如果您不想花太多的Gas,通過(guò)降低Gas Limit將不會(huì)有太大的幫助。因?yàn)槟仨毎ㄗ銐虻腉as來(lái)支付的計(jì)算資源,否則由于Gas不夠?qū)е陆灰资?#xff0c;您所設(shè)置的所有Gas limit也將消耗光。建議您在有充足moac情況下,將Gas Limit盡量設(shè)高,所有未使用的Gas將在轉(zhuǎn)賬結(jié)束時(shí)退還給您。
通過(guò)降低Gas Price可以節(jié)省礦工費(fèi)用,但是也會(huì)減慢礦工打包的速度。礦工會(huì)優(yōu)先打包 Gas Price設(shè)置高的交易,如果您想加快轉(zhuǎn)賬,您可以把Gas Price設(shè)置得更高,這樣您就可以排隊(duì)靠前。如果您不急,您只需要設(shè)置一個(gè)安全的 Gas Price,礦工也會(huì)打包您的交易。
1.2 moac單位
moac最小的單位是sha,最常用的單位是mc。
1.3 keystore
keystore是賬戶的一種表現(xiàn)形式,里面包含了賬戶的地址,賬戶密文的私鑰和MAC地址等等一系列的信息,下面是一個(gè)keystore的完整信息。
1.5 元交易
元交易是這樣一種發(fā)送交易的模式:發(fā)送方先對(duì)一個(gè)合法的交易簽名,然后把該交易和簽名通過(guò)鏈下傳遞的方式轉(zhuǎn)交給一個(gè)中繼方,該中繼方愿意承擔(dān)該筆交易的 gas 費(fèi)并最終發(fā)送交易到網(wǎng)絡(luò)中。
這種元交易模式很有用,因?yàn)榘l(fā)送方不再需要在發(fā)送賬戶中存有moac,從用戶體驗(yàn)角度這很有益處。
元交易最終的目標(biāo)地址一般都是某個(gè)合約,且在某種程度上,該合約知道,交易的簽名方并不是交易實(shí)際的發(fā)送者。此時(shí),交易 API 的 msg.sender 字段會(huì)返回中繼方的地址,但其很可能并沒(méi)有代表簽名方操作的權(quán)利,所以在這個(gè)場(chǎng)景下(僅僅查看 msg.sender 字段)并沒(méi)有太大意義。因此,許多元交易依賴鏈上的簽名校驗(yàn)(通過(guò) API 的 ecRecover 函數(shù))來(lái)保證簽名方賬戶的確是在一份合適的白名單里面(有權(quán)限操作該交易想要執(zhí)行的指令)。
1.6 其他
Nonce:交易計(jì)數(shù)器,即該賬戶主動(dòng)發(fā)起的交易數(shù)量,從0開(kāi)始計(jì)數(shù)。
助記詞:通過(guò)算法從詞庫(kù)里面產(chǎn)生12-24個(gè)單詞,目前支持多種語(yǔ)言。
隨機(jī)種子:使用助記詞通過(guò)算法產(chǎn)生的一個(gè)隨機(jī)字符串。
私鑰:錢包中最重要的東西,錢包實(shí)際上就對(duì)私鑰進(jìn)行管理,現(xiàn)在私鑰有主私鑰和派生私鑰的說(shuō)法。
主私鑰:錢包私鑰,由助記詞產(chǎn)生的隨機(jī)種子生成,主私鑰被盜的話,你的整個(gè)錢包的錢將全部被盜。
派生私鑰:由主私鑰通過(guò)bip分層協(xié)議生成的私鑰,派生私鑰丟失,只會(huì)丟失單一賬戶上的數(shù)字資產(chǎn)。
備份錢包:其實(shí)也叫備份助記詞,現(xiàn)在的錢包基本上都是用助記詞恢復(fù)的。
備份私鑰:對(duì)錢包的主私鑰或者派生私鑰進(jìn)行備份,通過(guò)主私鑰可以找回錢包中所有的賬戶,通過(guò)派生私鑰只能找回其中的一個(gè)賬戶。
導(dǎo)入錢包:通過(guò)導(dǎo)入助記詞或者私鑰的方式生成以前的錢包。
導(dǎo)入私鑰:通過(guò)導(dǎo)入私鑰生成多鏈多賬戶錢包,或者單鏈單賬戶錢包。
單鏈錢包:只支持一條鏈的錢包,比方說(shuō)比特幣錢包。
多鏈錢包:支持所有幣種的錢包。
單賬戶錢包:每種幣只支持一個(gè)賬戶。
多賬戶錢包:每種幣支持多個(gè)賬戶。
地址:類似于銀行卡賬戶,通過(guò)地址可以查詢到目前賬戶上的余額。
公鑰:對(duì)所有人公開(kāi)的秘鑰。
簽名:在發(fā)起數(shù)字資產(chǎn)轉(zhuǎn)賬時(shí),所有的幣種都要對(duì)轉(zhuǎn)賬的數(shù)據(jù)進(jìn)行簽名,簽名的數(shù)據(jù)量對(duì)于不同的幣種不一樣。
空投:就是批量打幣。
bip協(xié)議簇:HD分層錢包中的一個(gè)重要的規(guī)定,是數(shù)字貨幣發(fā)展的必然產(chǎn)物。
非確定性錢包:每個(gè)賬戶對(duì)應(yīng)一個(gè)私鑰,私鑰不好管理。
確定性錢包:有主私鑰,通過(guò)主私鑰可以生產(chǎn)其他所有幣種的私鑰,但不能支持多賬戶。
確定性分層錢包:有主私鑰,通過(guò)主私鑰可以生產(chǎn)其他所有幣種的私鑰,支持多賬戶。
二、開(kāi)源庫(kù)keythereum
Keythereum是一個(gè)用于生成,導(dǎo)入和導(dǎo)出密鑰的JavaScript工具。這提供了一種在本地和Web錢包中使用同一帳戶的簡(jiǎn)單方法。它可用于可驗(yàn)證和存儲(chǔ)錢包。
Keythereum使用相同的密鑰派生函數(shù)(PBKDF2-SHA256或scrypt),對(duì)稱密碼(AES-128-CTR或AES-128-CBC)和消息驗(yàn)證代碼。您可以將生成的密鑰導(dǎo)出到文件,將其復(fù)制到數(shù)據(jù)目錄的密鑰庫(kù),然后立即開(kāi)始在您的本地客戶端中使用它。
從版本0.5.0開(kāi)始,keythereum的加密和解密函數(shù)都返回Buffers而不是字符串。對(duì)于直接使用這些功能的人來(lái)說(shuō),這是一個(gè)重大改變。
2.1 使用keythereum生產(chǎn)keystore:
在生成keystore之前,你必須有一個(gè)nodeJs的環(huán)境,并且安裝好keythereum。
或者使用壓縮的瀏覽器文件dist/keythereum.min.js,以便在瀏覽器中使用。使用代碼引入。
生成一個(gè)新的隨機(jī)私鑰(256位),以及密鑰派生函數(shù)使用的salt(256位),用于AES-128-CTR的初始化向量(128位)對(duì)密鑰進(jìn)行加密。如果傳遞回調(diào)函數(shù),則create是異步的,否則是同步的。
下面是生成keystore的代碼:
運(yùn)行結(jié)果:
2.2 將keystore保存到文件中:
dump創(chuàng)建一個(gè)對(duì)象而不是JSON字符串。在Node中,exportToFile方法提供了一種將此格式化的密鑰對(duì)象導(dǎo)出到文件的簡(jiǎn)便方法。它在keystore子目錄中創(chuàng)建一個(gè)JSON文件,并使用geth的當(dāng)前文件命名約定(ISO時(shí)間戳與密鑰派生的以太坊地址連接)。
代碼如下:
成功之后在你的keystore目錄下將看到一個(gè)keystore格式的賬號(hào)文件,如果出現(xiàn)錯(cuò)誤,最可能的原因就是你的目錄下沒(méi)有keystore這個(gè)目錄,當(dāng)然以上代碼中你也可以指定keystore的存儲(chǔ)目錄。
2.3 keystore的導(dǎo)入:
從keystore密鑰庫(kù)導(dǎo)入密鑰只能在Node上完成。將JSON文件解析為與上面的keyObject具有相同結(jié)構(gòu)的對(duì)象。以下代碼需要在keystore目錄下已經(jīng)存在keystore格式的賬號(hào)文件。
運(yùn)行結(jié)果:
2.4 從keystore中恢復(fù)私鑰:
這里恢復(fù)出來(lái)的私鑰是buffer格式的,password是你設(shè)置的密碼,keyObject就是keystore。
運(yùn)行結(jié)果:
三、開(kāi)源庫(kù)eth-crypto
3.1 安裝
3.2 創(chuàng)建賬號(hào)
node環(huán)境下運(yùn)行以下代碼,可以離線生成賬號(hào),得到私鑰、公鑰和地址。
const EthCrypto = require('eth-crypto'); const identity = EthCrypto.createIdentity(); //可以直接顯示私鑰、公鑰和地址console.log('privateKey:'+identity.privateKey);console.log('publicKey: '+identity.publicKey);console.log('address: '+identity.address); /* > privateKey:0xafd2fa1a57103993c16e2318f45206417c5cf840bb204603912b8dc54b7d8800publicKey: 37b7d6b1b7bc05947d42ecfd3b63dee6cd54ff3ebfd5c6637f3224f45d05c2f4ad0b8ffea1abd2c2313965662cfd7a09e2c9dd683eec4eeab4b19838e01b9f1caddress: 0x16F119734F845a5348dd37175ca81059E66C90B3*/
3.3 從私鑰得到公鑰
const EthCrypto = require('eth-crypto');var privateKey = "0xafd2fa1a57103993c16e2318f45206417c5cf840bb204603912b8dc54b7d8800"; //從私鑰得到公鑰const publicKey = EthCrypto.publicKeyByPrivateKey(privateKey);console.log('publicKeyByPrivateKey: '+publicKey); /* > publicKeyByPrivateKey: 37b7d6b1b7bc05947d42ecfd3b63dee6cd54ff3ebfd5c6637f3224f45d05c2f4ad0b8ffea1abd2c2313965662cfd7a09e2c9dd683eec4eeab4b19838e01b9f1c*/
3.4 從公鑰得到地址
const EthCrypto = require('eth-crypto');const publicKey = "37b7d6b1b7bc05947d42ecfd3b63dee6cd54ff3ebfd5c6637f3224f45d05c2f4ad0b8ffea1abd2c2313965662cfd7a09e2c9dd683eec4eeab4b19838e01b9f1c"; //從公鑰得到地址const address = EthCrypto.publicKey.toAddress(publicKey);console.log('addressByPublicKey: '+address); /* > addressByPublicKey: 0x16F119734F845a5348dd37175ca81059E66C90B3*/
3.5 簽名
const EthCrypto = require('eth-crypto');const privateKey = "0xafd2fa1a57103993c16e2318f45206417c5cf840bb204603912b8dc54b7d8800";const message = 'hello,world!';const messageHash = EthCrypto.hash.keccak256(message); const signature = EthCrypto.sign(privateKey,messageHash);console.log('signature: ' + signature); /*signature: 0x6f9188a50f13d75fd64df378f11b025a48f089f1d51d60264e84f3690d9fd6c6117abff827b06ab9de98e9c2837d6d9a6451ed113cf4492c8e28a4e2bd377bf51c*/
3.6 從簽名信息獲得地址
此處需要知道明文信息。
const EthCrypto = require('eth-crypto');const signature = "0x6f9188a50f13d75fd64df378f11b025a48f089f1d51d60264e84f3690d9fd6c6117abff827b06ab9de98e9c2837d6d9a6451ed113cf4492c8e28a4e2bd377bf51c"; const signer = EthCrypto.recover(signature,EthCrypto.hash.keccak256('hello,world!'));console.log('signer: ' + signer); /*signer: 0x16F119734F845a5348dd37175ca81059E66C90B3*/
3.7 從簽名信息獲得公鑰
此處需要知道明文信息。
const EthCrypto = require('eth-crypto');const signature = "0x6f9188a50f13d75fd64df378f11b025a48f089f1d51d60264e84f3690d9fd6c6117abff827b06ab9de98e9c2837d6d9a6451ed113cf4492c8e28a4e2bd377bf51c"; const signer = EthCrypto.recoverPublicKey(signature,EthCrypto.hash.keccak256('hello,world!'));console.log('signer: ' + signer); /*signer: 37b7d6b1b7bc05947d42ecfd3b63dee6cd54ff3ebfd5c6637f3224f45d05c2f4ad0b8ffea1abd2c2313965662cfd7a09e2c9dd683eec4eeab4b19838e01b9f1c*/
四、交易
4.1交易確認(rèn)
并不是我們查詢區(qū)塊鏈中的交易就說(shuō)明這筆交易已經(jīng)成功了,墨客是默認(rèn)確認(rèn)12次之后,此交易幾乎不會(huì)被篡改,那么怎么計(jì)算確認(rèn)次數(shù)呢?
確認(rèn)次數(shù) = 當(dāng)前區(qū)塊高度 - 交易所在區(qū)塊高度 + 1
此處注意事項(xiàng):交易有可能會(huì)被孤立,在執(zhí)行此公式時(shí)需要驗(yàn)證一下區(qū)塊中此交易是否還是在那個(gè)區(qū)塊上,是否已經(jīng)被回滾。
交易的gas費(fèi)算是常識(shí)性的內(nèi)容,可給用戶一些參考值,讓用戶選擇愿意支付的手續(xù)費(fèi)。最笨拙而又有效的方法是定期觀察一下區(qū)塊鏈上交易成功的交易的 gasPrice 的大概范圍,動(dòng)態(tài)的調(diào)整一下價(jià)格,而 gasLimit 在不影響交易的情況下,盡可能稍微多一些,因?yàn)榇瞬糠秩绻词褂眠€會(huì)退換到交易發(fā)起賬戶中。
4.2交易中nonce維護(hù)
轉(zhuǎn)賬地址的合法性檢查,此合法性檢查可以避免后續(xù)很多問(wèn)題的出現(xiàn),比如 nonce 值的維護(hù)。
交易的金額檢查,nonce 值檢查(nonce 值會(huì)遇到的問(wèn)題前面已經(jīng)提到過(guò)),特別是私鑰與節(jié)點(diǎn)分離之后自己來(lái)維護(hù)私鑰時(shí) nonce 值會(huì)是一個(gè)很大的問(wèn)題,比如前一筆交易失敗,nonce 值需要回退,此時(shí)后一筆交易已經(jīng)發(fā)出,因?yàn)榍耙还P nonce 沒(méi)有被補(bǔ)齊,后一筆遲遲不會(huì)被交易。這些都需要業(yè)務(wù)進(jìn)行特殊判斷和處理。
查詢一個(gè)地址 nonce,mc.getTransactionCount。
4.3交易記錄
墨客區(qū)塊鏈只能通過(guò)遍歷區(qū)塊交易的方法來(lái)判斷是否有對(duì)應(yīng)賬戶的交易。相關(guān)操作步驟主要包括:
*查詢區(qū)塊高度,比對(duì)是否是新生成的區(qū)塊,mc.blockNumber;
*查看區(qū)塊內(nèi)容及詳細(xì)交易,mc.gethBlock;
*比對(duì)交易的 toAddress 是否為本錢包的地址,如果是則記錄此筆交易到數(shù)據(jù)庫(kù),并記錄交易狀態(tài)(確認(rèn)次數(shù)等);
*保證入庫(kù)和記賬的冪等性,因?yàn)闀?huì)多次查詢到同一筆交易;
*作為錢包開(kāi)發(fā)來(lái)說(shuō),實(shí)際需要解析所有交易,并保存到數(shù)據(jù)庫(kù)備查。
總結(jié)
以上是生活随笔為你收集整理的助记词创建以太坊钱包源码_墨客科普 | MOAC区块链钱包账号管理的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
                            
                        - 上一篇: 我国一季度GDP公布!全年GDP增长或超
 - 下一篇: 2021微信零钱通收益排名前八的基金是什