ethers.js-2-wallets and signers
Application Programming Interface (API)
Wallets and Signers
A Wallet manages a private/public key pair which is used to cryptographically sign transactions and prove ownership on the Ethereum network.钱包管理一个私有/公钥对,该对用于在Ethereum网络上对交易进行加密签名并证明所有权。
Wallet
The Wallet implements the Signer API and can be used anywhere a Signer is expected and has all the required properties.钱包实现了签名者API,可以在需要签名者的任何地方使用,并具有所有必需的属性。
Creating Instances
- new Wallet ( privateKey [ , provider ] )
- Creates a new instance from privateKey and optionally connect a provider
- 使用私钥创建新实例并可选地连接provider
- Wallet. createRandom ( [ options ] ) => Wallet
-
Creates a new random wallet. Ensure this wallet is stored somewhere safe, if lost there is NO way to recover it.
随机创建钱包。保证钱包存储在某个安全的地方,如果丢失了是没有办法恢复的
Options may have the properties:可选项的属性
- extraEntropy — additional entropy to stir into the random source额外的熵加入到随机源中
- Wallet. fromEncryptedJson ( json, password [ , progressCallback ] ) => Wallet (回调)
- Decrypt an encrypted Secret Storage JSON Wallet (from Geth, parity, Crowdsale tools, or that was created using prototype.encrypt )
- 对加密的秘密存储JSON钱包进行解密
- Wallet. fromMnemonic ( mnemonic [ , path = “m/44’/60’/0’/0/0” [ , wordlist ] ] ) => Wallet
-
Generate a BIP-039 + BIP-044 wallet from mnemonic deriving path using the wordlist. The default language is English (en).
通过使用wordlist并从path派生的助记词来创建 BIP-039 + BIP-044钱包。默认的语言是英语
In the browserified
dist/ethers.min.jsonly the English wordlist is available. Each additional wordlist may be included by adding a<script>for thedist/wordlist-*.js想使用别的语言就在后面加上后缀The current supported wordlists are:
Language node.js Browser English (US) ethers.wordlists.enincluded Italian ethers.wordlists.itdist/wordlist-it.jsJapanese ethers.wordlists.jadist/wordlist-ja.jsKorean ethers.wordlists.kodist/wordlist-ko.jsChinese (simplified) ethers.wordlists.zh_cndist/wordlist-zh.jsChinese (traditional) ethers.wordlists.zh_twdist/wordlist-zh.jsprototype . connect ( provider ) => Wallet
Creates a new Wallet instance from an existing instance, connected to a new provider.通过现成的实例去创建一个新的钱包实例,然后连接一个新的provider
实现例子:
1.load a private key
const ethers = require('ethers');
let privateKey = "0x0123456789012345678901234567890123456789012345678901234567890123";
let wallet = new ethers.Wallet(privateKey); // Connect a wallet to mainnet
let provider = ethers.getDefaultProvider();
console.log(provider);
// FallbackProvider {
// _network:
// { name: 'homestead',
// chainId: 1,
// ensAddress: '0x314159265dd8dbb310642f98f50c066173c1259b',
// _defaultProvider: [Function] },
// ready:
// Promise {
// { name: 'homestead',
// chainId: 1,
// ensAddress: '0x314159265dd8dbb310642f98f50c066173c1259b',
// _defaultProvider: [Function] } },
// _lastBlockNumber: -2,
// _balances: {},
// _events: [],
// _pollingInterval: 4000,
// _emitted: { block: -2 },
// _fastQueryDate: 0,
// _providers:
// [ InfuraProvider {
// _network:
// { name: 'homestead',
// chainId: 1,
// ensAddress: '0x314159265dd8dbb310642f98f50c066173c1259b',
// _defaultProvider: [Function] },
// ready:
// Promise {
// { name: 'homestead',
// chainId: 1,
// ensAddress: '0x314159265dd8dbb310642f98f50c066173c1259b',
// _defaultProvider: [Function] } },
// _lastBlockNumber: -2,
// _balances: {},
// _events: [],
// _pollingInterval: 4000,
// _emitted: { block: -2 },
// _fastQueryDate: 0,
// connection: { url: 'https://mainnet.infura.io/' },//连接的network
// apiAccessToken: null },
// EtherscanProvider {
// _network:
// { name: 'homestead',
// chainId: 1,
// ensAddress: '0x314159265dd8dbb310642f98f50c066173c1259b',
// _defaultProvider: [Function] },
// ready:
// Promise {
// { name: 'homestead',
// chainId: 1,
// ensAddress: '0x314159265dd8dbb310642f98f50c066173c1259b',
// _defaultProvider: [Function] } },
// _lastBlockNumber: -2,
// _balances: {},
// _events: [],
// _pollingInterval: 4000,
// _emitted: { block: -2 },
// _fastQueryDate: 0,
// baseUrl: 'https://api.etherscan.io',
// apiKey: undefined } ] } console.log();
let walletWithProvider = new ethers.Wallet(privateKey, provider);
console.log(walletWithProvider); // Wallet {
// signingKey:
// SigningKey {
// privateKey:
// '0x0123456789012345678901234567890123456789012345678901234567890123',
// keyPair:
// KeyPair {
// privateKey:
// '0x0123456789012345678901234567890123456789012345678901234567890123',
// publicKey:
// '0x046655feed4d214c261e0a6b554395596f1f1476a77d999560e5a8df9b8a1a3515217e88dd05e938efdd71b2cce322bf01da96cd42087b236e8f5043157a9c068e',
// compressedPublicKey:
// '0x026655feed4d214c261e0a6b554395596f1f1476a77d999560e5a8df9b8a1a3515',
// publicKeyBytes:
// [ 2,
// 102,
// 85,
// 254,
// 237,
// 77,
// 33,
// 76,
// 38,
// 30,
// 10,
// 107,
// 85,
// 67,
// 149,
// 89,
// 111,
// 31,
// 20,
// 118,
// 167,
// 125,
// 153,
// 149,
// 96,
// 229,
// 168,
// 223,
// 155,
// 138,
// 26,
// 53,
// 21 ] },
// publicKey:
// '0x046655feed4d214c261e0a6b554395596f1f1476a77d999560e5a8df9b8a1a3515217e88dd05e938efdd71b2cce322bf01da96cd42087b236e8f5043157a9c068e',
// address: '0x14791697260E4c9A71f18484C9f997B308e59325' },//上面的私钥对应的address
// provider:
// FallbackProvider {
// _network:
// { name: 'homestead',
// chainId: 1,
// ensAddress: '0x314159265dd8dbb310642f98f50c066173c1259b',
// _defaultProvider: [Function] },
// ready:
// Promise {
// { name: 'homestead',
// chainId: 1,
// ensAddress: '0x314159265dd8dbb310642f98f50c066173c1259b',
// _defaultProvider: [Function] } },
// _lastBlockNumber: -2,
// _balances: {},
// _events: [],
// _pollingInterval: 4000,
// _emitted: { block: -2 },
// _fastQueryDate: 0,
// _providers:
// [ InfuraProvider {
// _network:
// { name: 'homestead',
// chainId: 1,
// ensAddress: '0x314159265dd8dbb310642f98f50c066173c1259b',
// _defaultProvider: [Function] },
// ready:
// Promise {
// { name: 'homestead',
// chainId: 1,
// ensAddress: '0x314159265dd8dbb310642f98f50c066173c1259b',
// _defaultProvider: [Function] } },
// _lastBlockNumber: -2,
// _balances: {},
// _events: [],
// _pollingInterval: 4000,
// _emitted: { block: -2 },
// _fastQueryDate: 0,
// connection: { url: 'https://mainnet.infura.io/' },
// apiAccessToken: null },
// EtherscanProvider {
// _network:
// { name: 'homestead',
// chainId: 1,
// ensAddress: '0x314159265dd8dbb310642f98f50c066173c1259b',
// _defaultProvider: [Function] },
// ready:
// Promise {
// { name: 'homestead',
// chainId: 1,
// ensAddress: '0x314159265dd8dbb310642f98f50c066173c1259b',
// _defaultProvider: [Function] } },
// _lastBlockNumber: -2,
// _balances: {},
// _events: [],
// _pollingInterval: 4000,
// _emitted: { block: -2 },
// _fastQueryDate: 0,
// baseUrl: 'https://api.etherscan.io',
// apiKey: undefined } ] } }2.create a new random account
const ethers = require('ethers');
let randomWallet = ethers.Wallet.createRandom();
console.log(randomWallet) // Wallet {
// signingKey:
// SigningKey {
// mnemonic:
// 'lend actress blossom tomorrow taste wolf harsh parent this hawk staff piece',
// path: "m/2147483692'/2147483708'/2147483648'/0/0",//path不是"m/44'/60'/0'/0/0"
// privateKey:
// '0xee7a2b6165a624535c3dc3cb0b9f58d01bf326bbab239f16a43ee704659eb234',
// keyPair:
// KeyPair {
// privateKey:
// '0xee7a2b6165a624535c3dc3cb0b9f58d01bf326bbab239f16a43ee704659eb234',
// publicKey:
// '0x04c9bdc4a2d31375540efaf5414c53d2e778da976bc2a3ddb2d5eefa5e6ac85ee3dd794af0b679fceb92df9bb0417267d3d5147ccf3a30c2e734edb7f933c98b63',
// compressedPublicKey:
// '0x03c9bdc4a2d31375540efaf5414c53d2e778da976bc2a3ddb2d5eefa5e6ac85ee3',
// publicKeyBytes:
// [ 3,
// 201,
// 189,
// 196,
// 162,
// 211,
// 19,
// 117,
// 84,
// 14,
// 250,
// 245,
// 65,
// 76,
// 83,
// 210,
// 231,
// 120,
// 218,
// 151,
// 107,
// 194,
// 163,
// 221,
// 178,
// 213,
// 238,
// 250,
// 94,
// 106,
// 200,
// 94,
// 227 ] },
// publicKey:
// '0x04c9bdc4a2d31375540efaf5414c53d2e778da976bc2a3ddb2d5eefa5e6ac85ee3dd794af0b679fceb92df9bb0417267d3d5147ccf3a30c2e734edb7f933c98b63',
// address: '0x6C1383Bb5Fb9A993F158918bC25A1efcCB1F3813' },
// provider: undefined }3.load a JSON wallet(回调)
const ethers = require('ethers');
let data = {
id: "fb1280c0-d646-4e40-9550-7026b1be504a",
address: "88a5c2d9919e46f883eb62f7b8dd9d0cc45bc290",
Crypto: {
kdfparams: {
dklen: ,
p: ,
salt: "bbfa53547e3e3bfcc9786a2cbef8504a5031d82734ecef02153e29daeed658fd",
r: ,
n:
},
kdf: "scrypt",
ciphertext: "10adcc8bcaf49474c6710460e0dc974331f71ee4c7baa7314b4a23d25fd6c406",
mac: "1cf53b5ae8d75f8c037b453e7c3c61b010225d916768a6b145adf5cf9cb3a703",
cipher: "aes-128-ctr",
cipherparams: {
iv: "1dcdf13e49cea706994ed38804f6d171"
}
},
"version" :
}; let json = JSON.stringify(data);//转成字符串格式
let password = "foo"; ethers.Wallet.fromEncryptedJson(json, password).then(function(wallet) {
console.log("Address: " + wallet.address);
// "Address: 0x88a5C2d9919e46F883EB62F7b8Dd9d0CC45bc290"
});4.load a mnemonic phrase
⚠️这里的'm/44\'/60\'/0\'/0/0'在显示时显示为 "m/2147483692'/2147483708'/2147483648'/0/0",所以
"m/44'/60'/1'/0/0" 对应的就是 "m/2147483692'/2147483708'/2147483649'/0/0"
const ethers = require('ethers');
let mnemonic = "radar blur cabbage chef fix engine embark joy scheme fiction master release";
let mnemonicWallet = ethers.Wallet.fromMnemonic(mnemonic);
console.log(mnemonicWallet); // Wallet {
// signingKey:
// SigningKey {
// mnemonic:
// 'radar blur cabbage chef fix engine embark joy scheme fiction master release',
// path: "m/2147483692'/2147483708'/2147483648'/0/0",
// privateKey:
// '0xb96e9ccb774cc33213cbcb2c69d3cdae17b0fe4888a1ccd343cbd1a17fd98b18',
// keyPair:
// KeyPair {
// privateKey:
// '0xb96e9ccb774cc33213cbcb2c69d3cdae17b0fe4888a1ccd343cbd1a17fd98b18',
// publicKey:
// '0x0405b7d0996e99c4a49e6c3b83288f4740d53662839eab1d97d14660696944b8bbe24fabdd03888410ace3fa4c5a809e398f036f7b99d04f82a012dca95701d103',
// compressedPublicKey:
// '0x0305b7d0996e99c4a49e6c3b83288f4740d53662839eab1d97d14660696944b8bb',
// publicKeyBytes:
// [ 3,
// 5,
// 183,
// 208,
// 153,
// 110,
// 153,
// 196,
// 164,
// 158,
// 108,
// 59,
// 131,
// 40,
// 143,
// 71,
// 64,
// 213,
// 54,
// 98,
// 131,
// 158,
// 171,
// 29,
// 151,
// 209,
// 70,
// 96,
// 105,
// 105,
// 68,
// 184,
// 187 ] },
// publicKey:
// '0x0405b7d0996e99c4a49e6c3b83288f4740d53662839eab1d97d14660696944b8bbe24fabdd03888410ace3fa4c5a809e398f036f7b99d04f82a012dca95701d103',
// address: '0xaC39b311DCEb2A4b2f5d8461c1cdaF756F4F7Ae9' },
// provider: undefined } console.log(); // Load the second account from a mnemonic
let path = "m/44'/60'/1'/0/0";
let secondMnemonicWallet1 = ethers.Wallet.fromMnemonic(mnemonic, path);
console.log(secondMnemonicWallet1); // Wallet {
// signingKey:
// SigningKey {
// mnemonic:
// 'radar blur cabbage chef fix engine embark joy scheme fiction master release',//这个账户与上面的账户虽然mnemonic是相同的,但是他的path不同,所以产生的账户是不同的
// path: "m/2147483692'/2147483708'/2147483649'/0/0",
// privateKey:
// '0xfb848dd410a29bc784745d01c877a2934a3711a2dd53b8e5c5c651139a3b3689',
// keyPair:
// KeyPair {
// privateKey:
// '0xfb848dd410a29bc784745d01c877a2934a3711a2dd53b8e5c5c651139a3b3689',
// publicKey:
// '0x04b56a6ea9ee08ceb0758d8564b2a33139e4da0ea36991d0fcc9fcba62e3a76f7834c86b3bc04342c697c4df9233a9a53b1c17e152a18751804f80f3b11a692baf',
// compressedPublicKey:
// '0x03b56a6ea9ee08ceb0758d8564b2a33139e4da0ea36991d0fcc9fcba62e3a76f78',
// publicKeyBytes:
// [ 3,
// 181,
// 106,
// 110,
// 169,
// 238,
// 8,
// 206,
// 176,
// 117,
// 141,
// 133,
// 100,
// 178,
// 163,
// 49,
// 57,
// 228,
// 218,
// 14,
// 163,
// 105,
// 145,
// 208,
// 252,
// 201,
// 252,
// 186,
// 98,
// 227,
// 167,
// 111,
// 120 ] },
// publicKey:
// '0x04b56a6ea9ee08ceb0758d8564b2a33139e4da0ea36991d0fcc9fcba62e3a76f7834c86b3bc04342c697c4df9233a9a53b1c17e152a18751804f80f3b11a692baf',
// address: '0x9F7ffcb016b0f7b142529bF27ef1eC5b0039C32C' },
// provider: undefined } console.log();
// Load using a non-english locale wordlist (the path "null" will use the default)
let secondMnemonicWallet2 = ethers.Wallet.fromMnemonic(mnemonic, null, ethers.wordlists.ko);
//报错:Error: invalid mnemonic,因为mnemonic的内容为英文
console.log(secondMnemonicWallet2);5.connect provider
connect也没有办法将provider添加到wallet上。connect()没有用,wallet的provider还是undefined
const ethers = require('ethers');
let mnemonic = "success rifle romance major host prosper subway regular edge old lake achieve";
let mnemonicWallet = ethers.Wallet.fromMnemonic(mnemonic);
// console.log(mnemonicWallet);
// console.log();
let customHttpProvider = new ethers.providers.JsonRpcProvider("http://localhost:8545");
console.log();
mnemonicWallet.connect(customHttpProvider);
console.log(mnemonicWallet);更改:写成下面这样就好了,要连在一起写
const ethers = require('ethers');
let mnemonic = "success rifle romance major host prosper subway regular edge old lake achieve"; let customHttpProvider = new ethers.providers.JsonRpcProvider("http://localhost:8545"); let mnemonicWallet = ethers.Wallet.fromMnemonic(mnemonic).connect(customHttpProvider);
console.log(mnemonicWallet);返回:
Wallet {
signingKey:
SigningKey {
mnemonic:
'success rifle romance major host prosper subway regular edge old lake achieve',
path: "m/2147483692'/2147483708'/2147483648'/0/0",
privateKey:
'0x9af0f29100b9575ffe7d5596d87003b6ada89076ca84342f1fe57d85acde4ca6',
keyPair:
KeyPair {
privateKey:
'0x9af0f29100b9575ffe7d5596d87003b6ada89076ca84342f1fe57d85acde4ca6',
publicKey:
'0x04e5a5bca0b02b9b96b9009023adf1ef37bc79e4962b6ea11e1429cc03dc0a41ae3520322e2d5bfddc175a0c0883478bd372fee2b81dd28629fa1f8e10f390bfad',
compressedPublicKey:
'0x03e5a5bca0b02b9b96b9009023adf1ef37bc79e4962b6ea11e1429cc03dc0a41ae',
publicKeyBytes:
[ ,
,
,
,
,
,
,
,
,
,
,
,
,
,
,
,
,
,
,
,
,
,
,
,
,
,
,
,
,
,
,
,
] },
publicKey:
'0x04e5a5bca0b02b9b96b9009023adf1ef37bc79e4962b6ea11e1429cc03dc0a41ae3520322e2d5bfddc175a0c0883478bd372fee2b81dd28629fa1f8e10f390bfad',
address: '0x3455f15cc11F2E77c055f931A6C918ccc7c18fd8' },
provider:
JsonRpcProvider {
ready: Promise { <pending> },
_lastBlockNumber: -,
_balances: {},
_events: [],
_pollingInterval: ,
_emitted: { block: - },
_fastQueryDate: ,
connection: { url: 'http://localhost:8545' } } }Prototype
- prototype . address
- The public address of a wallet钱包的账户地址
- prototype . privateKey
- The private key of a wallet; keep this secret钱包私钥,秘密保存
- prototype . provider
-
A connected Provider which allows the wallet to connect to the Ethereum network to query its state and send transactions, or null if no provider is connected.允许钱包连接以太坊网络的连接provider,用来查询状态和发送交易。当没有provider连接时,其值为null
To change the provider, use the connect method, which will return a new instance of the Wallet connected to the provider.使用connect方法可以改变provider,且返回一个新的连接该provider的钱包实例
- prototype . mnemonic
- The mnemonic phrase for this wallet, or null if the mnemonic is unknown.钱包的mnemonic,如果未知则值为null
- prototype . path mnemonic的path,如果mnemonic未知则值为null
- The mnemonic path for this wallet, or null if the mnemonic is unknown.
Signing
- prototype . sign ( transaction ) => Promise<string>
-
Signs transaction and returns a Promise that resolves to the signed transaction as a hex string.
对交易签名并返回带着签名交易十六进制字符串的Promise
In general, the sendTransaction method is preferred to
sign, as it can automatically populate values asynchronously.通常sendTransaction方法将优先进行签名操作,因为它可以自动异步填充值
The properties for transaction are all optional and include:交易属性都是可选的,包括
- to
- gasLimit
- gasPrice
- nonce
- data
- value
- chainId
- prototype . signMessage ( message ) => Promise<string>
-
Signs message and returns a Promise that resolves to the flat-format signature.
对消息进行签名并返回带有flat格式签名的Promise
If message is a string, it is converted to UTF-8 bytes, otherwise it is preserved as a binary representation of the Arrayish data.
如果签名是一个字符串,将转换成UTF-8字节,否则,它将被保留为Arrayish数据的二进制表示形式
1.signing transactions
出现问题:
{ Error: Transaction hash mismatch from Provider.sendTransaction. (expectedHash="0xb48c1995addcf3268bdbe1a33878b7048de1fbfd5bc2ccb571ce63d2a4ab8953", returnedHash="0xb2047727e995b52c883c29b71819969c15d0f6e933e42ad19e84df08e14fa7fa", version=4.0.)发现版本6.1.8的ganache-cli解决了这个问题,如果使用的是最新版的6.2.3版本,还是会抱这个错误,解决看ganache-cli
const ethers = require('ethers');
const utils = require('ethers/utils'); let privateKey = "9af0f29100b9575ffe7d5596d87003b6ada89076ca84342f1fe57d85acde4ca6"; let customHttpProvider = new ethers.providers.JsonRpcProvider("http://localhost:8545"); let wallet = new ethers.Wallet(privateKey,customHttpProvider);
console.log(wallet.address);//0x3455f15cc11F2E77c055f931A6C918ccc7c18fd8 console.log(); let transaction = {
nonce: ,//(node:1036) UnhandledPromiseRejectionWarning: Error: nonce has already been used (version=4.0.13) gasLimit: ,
gasPrice: utils.bigNumberify(""), to: "0x7DdaD6a67544efB0c51808c77009a7B98Cc81630",
// ... or supports ENS names
// to: "ricmoo.firefly.eth", //(node:1037) UnhandledPromiseRejectionWarning: Error: insufficient funds (version=4.0.13),所以将value设为0
value: ,
data: "0x", // This ensures the transaction cannot be replayed on different networks
// chainId:
}; let signPromise = wallet.sign(transaction) signPromise.then((signedTransaction) => { console.log(signedTransaction);
//0xf865808504a817c80083033450947ddad6a67544efb0c51808c77009a7b98cc8163080801ca0ae2b8b042371a68d2e00b3ad5949575e24428f0eb432d3094af4d72ee0cc63fea04de5df55127c7e9d9dedaa8d754afbb14fc32686ea31cfa01d1d06409dcf24be customHttpProvider.sendTransaction(signedTransaction).then((tx) => { console.log(tx);
// {
// // These will match the above values (excluded properties are zero)
// "nonce", "gasLimit", "gasPrice", "to", "value", "data", "chainId"
//
// // These will now be present
// "from", "hash", "r", "s", "v"
// }
// Hash: // { nonce: 0,
// gasPrice: BigNumber { _hex: '0x04a817c800' },
// gasLimit: BigNumber { _hex: '0x033450' },
// to: '0x7DdaD6a67544efB0c51808c77009a7B98Cc81630',
// value: BigNumber { _hex: '0x00' },
// data: '0x',
// chainId: 0,
// v: 28,
// r:
// '0xae2b8b042371a68d2e00b3ad5949575e24428f0eb432d3094af4d72ee0cc63fe',
// s:
// '0x4de5df55127c7e9d9dedaa8d754afbb14fc32686ea31cfa01d1d06409dcf24be',
// from: '0x3455f15cc11F2E77c055f931A6C918ccc7c18fd8',
// hash:
// '0xb48c1995addcf3268bdbe1a33878b7048de1fbfd5bc2ccb571ce63d2a4ab8953',
// wait: [Function] }
}).catch((e) => {
console.log(e);
});
}).catch((e) => {
console.log(e);
});⚠️这里的sendTransaction使用的是provider.sendTransaction,如果使用wallet.provider,则会报错:
{ Error: invalid object (argument="object", value="0xf865028504a817c80083033450947ddad6a67544efb0c51808c77009a7b98cc8163080801ba05aff2cfaeea6300c27300fc44eeba439911c5aff606bb3b58427a6812c092eb8a02867804ba9d2443a60be158cf52ade06a49a810833aaf96f029b507d1e7d51b8", version=4.0.)2.signing text messages
const ethers = require('ethers');
let privateKey = "0x3141592653589793238462643383279502884197169399375105820974944592"
let wallet = new ethers.Wallet(privateKey); // Sign a text message
let signPromise = wallet.signMessage("Hello World!") signPromise.then((signature) => { // Flat-format
console.log(signature);
// "0xea09d6e94e52b48489bd66754c9c02a772f029d4a2f136bba9917ab3042a0474
// 301198d8c2afb71351753436b7e5a420745fed77b6c3089bbcca64113575ec3c
// 1c" // Expanded-format
console.log(ethers.utils.splitSignature(signature));
// {
// r: "0xea09d6e94e52b48489bd66754c9c02a772f029d4a2f136bba9917ab3042a0474",
// s: "0x301198d8c2afb71351753436b7e5a420745fed77b6c3089bbcca64113575ec3c",
// v: 28,
// recoveryParam: 1
// }
});3.
const ethers = require('ethers');
let privateKey = "0x3141592653589793238462643383279502884197169399375105820974944592"
let wallet = new ethers.Wallet(privateKey); // The 66 character hex string MUST be converted to a 32-byte array first!
let hash = "0x3ea2f1d0abf3fc66cf29eebb70cbd4e7fe762ef8a09bcc06c8edf641230afec0";
let binaryData = ethers.utils.arrayify(hash); let signPromise = wallet.signMessage(binaryData) signPromise.then((signature) => { console.log(signature);
// "0x5e9b7a7bd77ac21372939d386342ae58081a33bf53479152c87c1e787c27d06b
// 118d3eccff0ace49891e192049e16b5210047068384772ba1fdb33bbcba58039
// 1c"
});Blockchain Operations
These operations require the wallet have a provider attached to it.
- prototype . getBalance ( [ blockTag = “latest” ] ) => Promise<BigNumber>得到钱包在blockTag区块的账户的余额
- Returns a Promise that resolves to the balance of the wallet (as a BigNumber, in wei) at the blockTag.
- prototype . getTransactionCount ( [ blockTag = “latest” ] ) => Promise<number>得到钱包到blockTag区块为止进行的交易数量
- Returns a Promise that resovles to the number of transactions this account has ever sent (also called the nonce) at the blockTag.
- prototype . estimateGas ( transaction ) => Promise<BigNumber>估计交易需要使用的gas值
- Returns a Promise with the estimated cost for transaction (as a BigNumber, in gas)
- prototype . sendTransaction ( transaction ) => Promise<TransactionResponse>进行交易
- Sends the transaction (see Transaction Requests) to the network and returns a Promise that resolves to a Transaction Response. Any propties that are not provided will be populated from the network.
1.query the network
⚠️使用wallet.estimateGas报错:
TypeError: wallet.estimateGas is not a function
改成provider.estimateGas
const ethers = require('ethers');
const utils = require('ethers/utils');
let privateKey = "0x9af0f29100b9575ffe7d5596d87003b6ada89076ca84342f1fe57d85acde4ca6"; let customHttpProvider = new ethers.providers.JsonRpcProvider("http://localhost:8545"); let wallet = new ethers.Wallet(privateKey,customHttpProvider);
console.log(wallet.address);
wallet.getBalance().then((balance) => {
console.log(balance);//BigNumber { _hex: '0x56bc5e0308441c000' }
}).catch((e) => {
console.log(e);
}); wallet.getTransactionCount().then((count) => {
console.log(count);//
}).catch((e) => {
console.log(e);
}); let transaction = {
nonce: ,
gasLimit: ,
gasPrice: utils.bigNumberify(""), to: "0x7DdaD6a67544efB0c51808c77009a7B98Cc81630",
value: ,
data: "0x",
}; customHttpProvider.estimateGas(transaction).then((gas) => {
console.log(gas);//BigNumber { _hex: '0x5208' }
}).catch((e) => {
console.log(e);
});2.transfer ether
const ethers = require('ethers');
let privateKey = "0x9af0f29100b9575ffe7d5596d87003b6ada89076ca84342f1fe57d85acde4ca6"; let customHttpProvider = new ethers.providers.JsonRpcProvider("http://localhost:8545"); let wallet = new ethers.Wallet(privateKey,customHttpProvider);
console.log(wallet.address); let transaction = {
nonce: ,
gasLimit: ,
gasPrice: ethers.utils.bigNumberify(""), to: "0x7DdaD6a67544efB0c51808c77009a7B98Cc81630",
value: ethers.utils.parseEther('1.0'),
data: "0x",
}; wallet.sendTransaction(transaction).then((hash) => {
console.log(hash);
}).catch((e) => {
console.log(e);
});返回:
userdeMacBook-Pro:test-ethers user$ node index.js
0x3455f15cc11F2E77c055f931A6C918ccc7c18fd8
{ nonce: ,
gasPrice: BigNumber { _hex: '0x04a817c800' },
gasLimit: BigNumber { _hex: '0x033450' },
to: '0x7DdaD6a67544efB0c51808c77009a7B98Cc81630',
value: BigNumber { _hex: '0x0de0b6b3a7640000' },
data: '0x',
chainId: ,
v: ,
r:
'0x76bcd7c3d8a29ac8c61923b8bb09ffa612d370f1a6a487e49cf1a4954e4d66ba',
s:
'0x7628db1233925ab6576bc2f1114381ccc57fe24c71a14339739de351150941b9',
from: '0x3455f15cc11F2E77c055f931A6C918ccc7c18fd8',
hash:
'0x0d3ae20685f546518cd1cd061f765c755adcda00c07bf1e3fe6084a603762c75',
wait: [Function] }Encrypted JSON Wallets(得到UTC文件)
Many systems store private keys as encrypted JSON wallets, in various formats. There are several formats and algorithms that are used, all of which are supported to be read. Only the secure scrypt variation can be generated.
许多系统将私有密钥存储为加密的JSON钱包,格式各不相同。这里使用了几种格式和算法,它们都支持读取。只有安全scrypt变量才能生成。
See Wallet.fromEncryptedJson for creating a Wallet instance from a JSON wallet.上面有例子
- prototype . encrypt ( password [ , options [ , progressCallback ] ] ) => Promise<string>
-
Encrypts the wallet as an encrypted JSON wallet, with the password.使用password加密钱包成为加密的JSON钱包
All options are optional. The valid options are可选选项:
- salt — the salt to use for scrypt
- iv — the initialization vecotr to use for aes-ctr-128
- uuid — the UUID to use for the wallet
- scrypt — the scrypt parameters to use (N, r and p)
- entropy — the mnemonic entropy of this wallet; generally you should not specify this
- mnemonic — the mnemonic phrase of this wallet; generally you should not specify this
- path — the mnemonic path of this wallet; generally you should not specify this
If the progressCallback is specified, it will be called periodically during encryption with a value between 0 and 1, inclusive indicating the progress.如果指定了progressCallback,将在加密期间定期调用它,其值在0到1之间,包括指示进展的值。
1.encrypt a wallet as an encrypted JSON wallet
const ethers = require('ethers');
let privateKey = "9af0f29100b9575ffe7d5596d87003b6ada89076ca84342f1fe57d85acde4ca6"; let customHttpProvider = new ethers.providers.JsonRpcProvider("http://localhost:8545"); let wallet = new ethers.Wallet(privateKey,customHttpProvider); let password = "password123"; function callback(progress) {
console.log("Encrypting: " + parseInt(progress * ) + "% complete");
} let encryptPromise = wallet.encrypt(password, callback); encryptPromise.then(function(json) {
console.log(json);
});返回:
Encrypting: % complete
...
Encrypting: % complete
Encrypting: % complete
Encrypting: % complete
Encrypting: % complete
{"address":"3455f15cc11f2e77c055f931a6c918ccc7c18fd8","id":"9aabbebf-5189-4b64-b6f9-0f1fc36a1e00","version":,"Crypto":{"cipher":"aes-128-ctr","cipherparams":{"iv":"94d7b56547b04519f5e5cb792e88afba"},"ciphertext":"0d0703b21c7cd18a097d653d0cd952abbb339dd7ab13db89d077c2f6228d993f","kdf":"scrypt","kdfparams":{"salt":"4152023e125784aba95d7059f814b0dd22c71c5e98b8d0700a6c178031c83840","n":,"dklen":,"p":,"r":},"mac":"2bae299f8cda556b4ab9f6026241bb7ccd473d15c30d5efbaed718e81d3fb44d"}}Signer API
The Signer API is an abstract class which makes it easy to extend and add new signers, that can be used by this library and extension libraries. The Wallet extends the Signer API, as do the JsonRpcSigner and the Ledger Hardware Wallet Signer.
签名者API是一个抽象类,它可以方便地扩展和添加新的签名者,这些签名者可以被这个库和扩展库使用。
To implement a Signer, inherit the abstract class ethers.types.Signer and implement the following properties:
要实现签名者,继承抽象类ethers.types。签名者和实现以下属性:
- object . provider 得到连接的provider
- A Provider that is connected to the network. This is optional, however, without a provider, only write-only operations should be expected to work.
- object . getAddress ( ) => Promise<Address> 得到账户地址
- Returns a Promise that resolves to the account address.
- object . signMessage ( message ) => Promise<hex> 签署消息
-
Returns a Promise that resolves to the Flat-Format Signature for the message.
If message is a string, it is converted to UTF-8 bytes, otherwise it is preserved as a binary representation of the Arrayish data.
- object . sendTransaction ( transaction ) => Promise<TransactionResponse> 发送交易
- Sends the transaction (see Transaction Requests) to the network and returns a Promise that resolves to a Transaction Response. Any propties that are not provided will be populated from the network.
const ethers = require('ethers');
let privateKey = "9af0f29100b9575ffe7d5596d87003b6ada89076ca84342f1fe57d85acde4ca6"; let customHttpProvider = new ethers.providers.JsonRpcProvider("http://localhost:8545"); let wallet = new ethers.Wallet(privateKey,customHttpProvider);
console.log(wallet.provider);
// JsonRpcProvider {
// ready: Promise { <pending> },
// _lastBlockNumber: -2,
// _balances: {},
// _events: [],
// _pollingInterval: 4000,
// _emitted: { block: -2 },
// _fastQueryDate: 0,
// connection: { url: 'http://localhost:8545' } } wallet.getAddress().then((address) =>{
console.log(address);//0x3455f15cc11F2E77c055f931A6C918ccc7c18fd8
}).catch((e)=>{
console.log(e);
});
ethers.js-2-wallets and signers的更多相关文章
- ethers.js-1
https://docs.ethers.io/ethers.js/html/ What is ethers.js The ethers.js library aims to be a complete ...
- ethers.js-5-Utilities
https://docs.ethers.io/ethers.js/html/api-utils.html 使用时再进行查看即可
- 【转】干货 | 【虚拟货币钱包】从 BIP32、BIP39、BIP44 到 Ethereum HD Wallet
虚拟货币钱包 钱包顾名思义是存放$$$.但在虚拟货币世界有点不一样,我的帐户资讯(像是我有多少钱)是储存在区块链上,实际存在钱包中的是我的帐户对应的 key.有了这把 key 我就可以在虚拟货币世界证 ...
- 以太坊钱包开发系列4 - 发送Token(代币)
以太坊去中心化网页钱包开发系列,将从零开始开发出一个可以实际使用的钱包,本系列文章是理论与实战相结合,一共有四篇:创建钱包账号.账号Keystore文件导入导出.展示钱包信息及发起签名交易.发送Tok ...
- 以太坊钱包开发系列2 - 账号Keystore文件导入导出
以太坊去中心化网页钱包开发系列,将从零开始开发出一个可以实际使用的钱包,本系列文章是理论与实战相结合,一共有四篇:创建钱包账号.账号Keystore文件导入导出.展示钱包信息及发起签名交易.发送Tok ...
- 使用Etherscan API通过区块号获取块及叔块奖励
本文原文链接 点击这里获取Etherscan API 中文文档(完整版) 完整内容排版更好,推荐读者前往阅读. 区块(Blocks) 区块相关的 API,接口的参数说明请参考Etherscan API ...
- Etherscan API 中文文档-交易以及检查交易收据状态
本文原文链接 点击这里获取Etherscan API 中文文档(完整版) 完整内容排版更好,推荐读者前往阅读. 交易(Transaction) 交易相关的 API,接口的参数说明请参考Ethersca ...
- Etherscan API 中文文档-智能合约
本文原文链接 点击这里获取Etherscan API 中文文档(完整版) 完整内容排版更好,推荐读者前往阅读. 智能合约(Contracts) 智能合约相关的 API,接口的参数说明请参考Ethers ...
- Etherscan API 中文文档-账号
本文原文链接 点击这里获取Etherscan API 中文文档(完整版) 完整内容排版更好,推荐读者前往阅读. 账号(Account) 账号及地址相关的 API,接口的参数说明请参考Etherscan ...
随机推荐
- MYSQL与MSSQL对比学习
最近在将公司的一个产品里面相关的MSSQL语句修改为可以在MYSQL上执行的语句 l 优点分析: MYSQL短小精悍,容易上手,操作简单,免费供用的.相对其它数据库有特色又实用的语法多一些.SQL怎 ...
- idea 版本升级至最新版
前言:当前最新版为官网上的2018.2.3版本 一.下载最新版 官网地址:http://www.jetbrains.com/idea/download/#section=windows 百度网盘地址: ...
- 软件架构系列二:Clean架构
外圈的层次可以依赖内层,反之不可以:内圈核心的实体代表业务,不可以依赖其所处的技术环境. 这是著名软件大师Bob大叔提出的一种架构,也是当前各种语言开发架构.干净架构提出了一种单向依赖关系,从而在逻辑 ...
- VS本地调试 Visual Studio远程调试监视器(MSVSMON.EXE)的32位版本不能用于调试64位进程或64位转储
vs2017 调试一致都没啥问题,今天莫名报这个错误,感觉好奇怪,网上搜索了半天也没解决,最后看着错误信息感觉很诡异,我本地调试你给我启动远程调试监测器干嘛,localhost也访问不了,ping了一 ...
- jQuery基础(动画篇 animate,显示隐藏,淡入淡出,下拉切换)
1.jQuery中隐藏元素的hide方法 让页面上的元素不可见,一般可以通过设置css的display为none属性.但是通过css直接修改是静态的布局,如果在代码执行的时候,一般是通过js控制元 ...
- 使用镶嵌数据集 MosaicDataSet管理不同分辨率影像数据
镶嵌数据集 MosaicDataSet是Esri推出的一种用于管理海量影像数据的数据模型,它是Geodatabase数据模型的一个子集定义. 该数据模型强大之处在于它能统一管理不同采集时间.不同采集来 ...
- Java 之常用API(二)
Object类 & System类 日期相关类 包装类 & 正则表达式 Object类 & System类 1.1 Object类 1.1.1 概述 Object类是Java语 ...
- redis sortedSet
zset 和set 相比: zset 类型和set类型一样,不允许有重复的元素.zset是有序的,zset 有一个double类型的分数,这个分数可以重复,zset正是通过这个分数对集合中的元素从小到 ...
- 记录一次测试环境遇到的push消息记录
测试环境测试push消息,调用消息中心同事的api接口,感觉怎么都调用不通.纠结了一天,最终发现原因:一是版本的问题,不同的测试包有不同的版本,不同的版本 可能push的消息不同.二是 用户有没有 开 ...
- C语言const与#define
const 定义的是变量不是常量,只是这个变量的值不允许改变是常变量!带有类型.编译运行的时候起作用存在类型检查. define 定义的是不带类型的常数,只进行简单的字符替换.在预编译的时候起作用,不 ...