ethers.js-6-Low-Level API

Low-Level API

These are advanced, low-level API features that should, for most people not be necessary to worry about.

They are lightly documented here, and in the future will have more documentation, but the emphasis at this point is documenting the more common methods.

对于大多数人来说,这些是高级的、低级的API特性,不需要担心。
这里对它们进行了简单的文档化,将来还会有更多的文档化,但是现在的重点是对更常见的方法进行文档化。

 

ABI Coder

Creating Instances

new ethers . utils . AbiCoder ( [ coerceFunc ] )
Create a new ABI Coder object, which calls coerceFunc for each parsed value during decoding. The coerceFunc should have the signature: function(type, value).
创建一个新的ABI编码器对象,该对象在解码期间为每个解析值调用coerceFunccoerceFunc应该具有以下签名:函数(类型,值)。

Static Properties 其静态属性

ethers . utils . defaultAbiCoder
A default instance of the coder which can be used, which has a coerceFunc which will call toNumber() on BigNumbers whose type is less than 53 bits and is safe for JavaScript Number instances.一个可以使用的编码器的默认实例,它有一个cocefunc,它将对小于53位的BigNumbers调用toNumber(),并且对于JavaScript Number实例是安全的。

Prototype

prototype . encode ( types , values )   =>   hex
Returns a hex string of the values encoded as the types. Throws if a value is invalid for the type.
返回编码为类型的值的十六进制字符串。如果该类型的值无效,则throws。
prototype . decode ( types , data )   =>   Result
Returns an Object by parsing data assuming types, with each parameter accessible as a positional parameters. Throws if data is invalid for the types.
通过解析假设类型的数据返回一个对象,每个参数都可以作为位置参数访问。如果数据对类型无效,则throws

 

HDNode

A Hierarchical Deterministic Wallet represents a large tree of private keys which can reliably be reproduced from an initial seed. Each node in the tree is represented by an HDNode which can be descended into.

HD钱包表示可以从seed可靠地复制的大型私有密钥树。树中的每个节点都由一个HDNode表示。

A mnemonic phrase represents a simple way to generate the initial seed.助记词表示生成初始seed的简单方法。

See the BIP 32 Specification to learn more about HD Wallets and hardened vs non-hardened nodes.

See the BIP 39 Specification to learn more about Mnemonic Phrases.

Creating Instances

ethers . utils . HDNode . fromMnemonic ( mnemonic )   =>   HDNode
Create an HDNode from a mnemonic phrase.使用mnemonic生成HDNode
ethers . utils . HDNode . fromSeed ( seed )   =>   HDNode
Create an HDNode from a seed. 使用seed生成HDNode

Prototype 得到相应的值

prototype . privateKey
The hex string private key for this node.
prototype . publicKey
The (compressed) public key for this node.
prototype . chainCode
The chain code for this node.
prototype . index
The index (from the parent) of this node (0 for the master node).
prototype . depth
The depth within the hierarchy of this node.

Deriving Child Nodes

prototype . derivePath ( path )   =>   HDNode
Derive the path from this node. Path is slash (/) delimited path components. The first component may be “m” for master (which enforces the starting node is in fact a master node) and each subsequent path component should be a positive integer (up to 31 bits), which can optionally include an apostrophe () to indicate hardened derivation for that path components. See below for some examples.
从这个节点派生路径派生。路径是斜杠(/)分隔的路径组件。第一个组件可能是主节点的“m”(它强制起始节点实际上是主节点),而每个后续路径组件应该是一个正整数(最多31位),可以选择包含一个撇号('),以指示该路径组件的经过hardern的派生。请看下面的一些例子

Static Methods

ethers . utils . HDNode . mnemonicToEntropy ( mnemonic )   =>   hex
Convert a mnemonic to its binary entropy. (throws an error if the checksum is invalid)
ethers . utils . HDNode . entropyToMnemonic ( entropy )   =>   string
Convert the binary entropy to the mnemonic phrase.
ethers . utils . HDNode . mnemonicToSeed ( mnemonic )   =>   hex
Compute the BIP39 seed from mnemonic.
ethers . utils . HDNode . isValidMnemonic ( string )   =>   boolean
Returns true if and only if the string is a valid mnemonic (including the checksum)
 
let HDNode = require('ethers').utils.HDNode;

let mnemonic = "radar blur cabbage chef fix engine embark joy scheme fiction master release";

let masterNode = HDNode.fromMnemonic(mnemonic);
console.log(masterNode);//这里得到的masterNode是根结点,从其path值可看出 path: 'm'
// HDNode {
//   keyPair:
//    KeyPair {
//      privateKey:
//       '0xbc9d46102ab7c7655fd22ab24046e57f02f68b47a66f74443e3c239d82593b93',
//      publicKey:
//       '0x04605d5bf64aabe87513169f5f98d6813921d7678012a5140aae5e8aa4cfd1570a29be0a527ef438f10801c793b914af9fc941fcbe19f654870379228da947f686',
//      compressedPublicKey:
//       '0x02605d5bf64aabe87513169f5f98d6813921d7678012a5140aae5e8aa4cfd1570a',
//      publicKeyBytes:
//       [ 2,
//         96,
//         93,
//         91,
//         246,
//         74,
//         171,
//         232,
//         117,
//         19,
//         22,
//         159,
//         95,
//         152,
//         214,
//         129,
//         57,
//         33,
//         215,
//         103,
//         128,
//         18,
//         165,
//         20,
//         10,
//         174,
//         94,
//         138,
//         164,
//         207,
//         209,
//         87,
//         10 ] },
//   privateKey:
//    '0xbc9d46102ab7c7655fd22ab24046e57f02f68b47a66f74443e3c239d82593b93',
//   publicKey:
//    '0x02605d5bf64aabe87513169f5f98d6813921d7678012a5140aae5e8aa4cfd1570a',
//   address: '0x986208F71F84015389Ea40470846B9A730A0dd18',
//   chainCode:
//    '0x58d21a9c66b7d15789b793c90c08252a3ded88fc64ffd8b08381e447e615fca3',
//   index: 0,
//   depth: 0,
//   mnemonic:
//    'radar blur cabbage chef fix engine embark joy scheme fiction master release',
//   path: 'm' }

console.log();
let standardEthereum = masterNode.derivePath("m/44'/60'/0'/0/0");
console.log(standardEthereum);//这个这是在上面的根结点的基础上,派生路径为"m/44'/60'/0'/0/0"的子节点
// HDNode {
//   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 ] },
//   privateKey:
//    '0xb96e9ccb774cc33213cbcb2c69d3cdae17b0fe4888a1ccd343cbd1a17fd98b18',
//   publicKey:
//    '0x0305b7d0996e99c4a49e6c3b83288f4740d53662839eab1d97d14660696944b8bb',
//   address: '0xaC39b311DCEb2A4b2f5d8461c1cdaF756F4F7Ae9',
//   chainCode:
//    '0x41ef8d5b6140f4c88b4568eb2e719016844f89b770279c247ab00a136f1ec9b3',
//   index: 0,
//   depth: 5,
//   mnemonic:
//    'radar blur cabbage chef fix engine embark joy scheme fiction master release',
//   path: "m/2147483692'/2147483708'/2147483648'/0/0" }

 

Interface

The Interface Object is a meta-class that accepts a Solidity (or compatible) Application Binary Interface (ABI) and populates functions to deal with encoding and decoding the parameters to pass in and results returned.

接口对象是一个元类,它接受一个可靠(或兼容)应用程序二进制接口(ABI),并填充函数来处理要传入的参数的编码和解码以及返回的结果。

Creating an Instance

new ethers . utils . Interface ( abi )
Returns a new instance and populates the properties with the ABI constructor, methods and events. The abi may be either a JSON string or the parsed JSON Object.返回一个新实例,并用ABI构造函数、方法和事件填充属性。abi可以是JSON字符串,也可以是解析后的JSON对象。

Prototype通过该对象可更改ABI的相对应的内容

prototype . abi
A copy of the ABI is returned, modifying this object will not alter the ABI.返回ABI的副本,修改此对象不会更改ABI。
prototype . deployFunction
A DeployDesciption for the constructor defined in the ABI, or the default constructor if omitted.对ABI中定义的构造函数进行部署,如果省略了,则使用默认构造函数。
prototype . events
An object of all the events available in the ABI, by name and signature, which map to a EventDescription.ABI中所有可用事件的对象,按名称和签名,映射到事件描述。
prototype . functions
An object of all the functions available in the ABI, by name and signature, which map to a FunctionDescription.ABI中所有可用函数的对象,按名称和签名,映射到函数描述。

Parsing Objects

prototype . parseTransaction ( transaction )   =>   TransactionDescription
Parse transaction and return a description of the call it represents.解析交易并返回它所表示的调用的描述。描述下面有讲
prototype . parseLog ( log )   =>   LogDescription
Parse log and return a description of the event logs it represents.解析日志并返回它所表示的调用的描述。

Object Test Functions

prototype . isInterface ( value )   =>   boolean
Returns true if value is an Interface.
prototype . isIndexed ( value )   =>   boolean
Returns true if value is a dynamic Indexed value, which means the actual value of value is the hash of the actual value.如果值是动态索引值,则返回true,这意味着值的实际值是实际值的散列。

 

Descriptions描述

写出每类描述会显示的内容

Deploy Description构造函数的描述

namedescription
inputs The description of the constructor input parameters
payable Whether the constructor can accept Ether
encode(params) A function which encodes params

Event Description事件描述

namedescription
name The event name (e.g. “Transfer”)
signature The event signature (e.g. “Transfer(address indexed,address indexed,uint256)”)
inputs The event input parameters
anonymous Whether the event is an anonymous event
topic The topic for this event signature
encodeTopics(params) A function which computes filter topics for given params
decode(data, topics) A function to parse the log result data and topics

Function Description函数描述

namedescription
name The method name (e.g. “transfer”)
type The method type (i.e. “call” or “transaction”)
signature The method signature (e.g. “transfer(address to, uint256 amount)”)
sighash The signature hash of the signature (4 bytes)
inputs The description of the method input parameters
outputs The description of the method output parameters
payable Whether the method can accept Ether
gas The maximum gas this method will consume (null if unknown)
encode(params) A function which encodes params
decode(data) A function which decodes the result data

Log Description日志描述

namedescription
name The event name (e.g. “Transfer”)
signature The event signature (e.g. “Transfer(address indexed,address indexed,uint256)”)
topics The event topics
decode(data, topics) A function to parse the logs
values The decoded values of the event

Transaction Description交易描述

namedescription
name The method name (e.g. “transfer”)
args The arguments passed to the method
signature The method signature (e.g. “transfer(address to, uint256 amount)”)
sighash The signature hash of the signature (4 bytes)
decode(data) A function to parse the result data
value The value (in wei) of the transaction
 

Provider (Sub-Classing)

See the Provider API for more common usage. This documentation is designed for developers that are sub-classing BaseProvider.

有关更常见的用法,请参见提供Provider API。此文档是为子类化BaseProvider的开发人员设计的。

Static Methods

BaseProvider . inherits ( childProvider )   =>   void
Set up childProvider as an provider, inheriting the parent prototype and set up a prototype.inherits on the childProvider.将childProvider设置为提供者,继承父原型并设置原型。继承childProvider

Prototype

prototype . perform ( method , params )   =>   Promise<any>
The only method needed to override in a subclass. All values are sanitized and defaults populated in params and the result is sanitized before returning. Returns a Promise, see the example below for overview of method and params.
在子类中唯一需要重写的方法。所有值都经过清理,默认值以参数形式填充,结果在返回之前经过清理。返回Promise,有关方法和参数的概述,请参见下面的示例。
const ethers = require('ethers');

// The new provider Object
function DemoProvider(something) {

    let network = getNetworkSomehow()

    // The super must be called with either a Network or a Promise
    // that resolves to a Network
    ethers.providers.BaseProvider.call(this, network);

    ethers.utils.defineReadOnly(this, 'somethingElse', somethingElse);
}

// Inherit the Provider
ethers.providers.BaseProvider.inherits(DemoProvider);

// Override perform
DemoProvider.prototype.perform = function(method, params) {
    switch (method) {
        case 'getBlockNumber':
            // Params:
            // { }

        case 'getGasPrice':
            // Params:
            // { }

        case 'getBalance':
            // Params:
            // {
            //     address: address,
            //     blockTag: blockTag
            // }

        case 'getTransactionCount':
            // Params:
            // {
            //     address: address,
            //     blockTag: blockTag
            // }

        case 'getCode':
            // Params:
            // {
            //     address: address,
            //     blockTag: blockTag
            // }

        case 'getStorageAt':
            // Params:
            // {
            //     address: address,
            //     position: hexString,
            //     blockTag: blockTag
            // }

        case 'sendTransaction':
            // Params:
            // {
            //     signedTransaction: hexString
            // }

        case 'getBlock':
            // Params:
            // Exactly one of the following will be specified, the other will be absent
            // {
            //     blockHash: blockHash,
            //     blockTag: blockTag
            // }

        case 'getTransaction':
            // Params:
            // {
            //     transactionHash: hexString
            // }

        case 'getTransactionReceipt':
            // Params:
            // {
            //     transactionHash: hexString
            // }

        case 'call':
            // Params:
            // {
            //     transaction: See Transaction Requests (on Providers API)
            // }

        case 'estimateGas':
            // Params:
            // {
            //     transaction: See Transaction Requests (on Providers API)
            // }

        case 'getLogs':
            // Params:
            // {
            //    address: address,
            //    fromBlock: blockTag,
            //    toBlock: blockTag,
            //    topics: array (possibly nested) of topics
            // }

        default:
            break;
    }

    return Promise.reject(new Error('not implemented - ' + method));//到调用的方法没有找到时,就说明没有实现
};

 

Recursive-Length Prefixed Encoding (RLP)

This encoding method is used internally for several aspects of Ethereum, such as encoding transactions and determining contract addresses. For most developers this should not be necessary to use.

这种编码方法在内部用于Ethereum的几个方面,例如编码事务和确定合同地址。对于大多数开发人员来说,没有必要使用它。

RLP can encode nested arrays, with data as hex strings and Uint8Array (or other non-Arrayarrayish objects). A decoded object will always have data represented as hex strings and Arrays.

RLP可以对嵌套数组进行编码,数据可以是十六进制字符串和Uint8Array(或其他非arrayarrayish对象)。解码后的对象总是用十六进制字符串和数组表示数据。

See: https://github.com/ethereum/wiki/wiki/RLP

Static Methods

ethers . utils . RLP . encode( object )   =>   hex
Encodes an object as an RLP hex string. (throws an Error if the object contains invalid items)将对象编码为RLP十六进制字符串。(如果对象包含无效项,则抛出错误)
ethers . utils . RLP . decode( hexStringOrArrayish )   =>   any
Decode hexStringOrArrayish into the encoded object. (throws an Error if invalid RLP-coded data)解码hexStringOrArrayish到编码的对象。(如果rlp编码的数据无效,则抛出错误)
let object = [ ["0x42"], "0x1234", [ [], [] ] ];

let encoded = ethers.utils.RLP.encode(object);
console.log(encoded);
// 0xc8c142821234c2c0c0

let decoded = ethers.utils.RLP.decode(encoded);
console.log(decoded);
// [ [ '0x42' ], '0x1234', [ [], [] ] ]

 

 

 

Signing Key

The SigningKey interface provides an abstraction around the secp256k1 elliptic curve cryptography library, which signs digests, computes public keys from private keys and performs ecrecover which computes a public key from a digest and a signature.

SigningKey接口提供了一个围绕secp256k1椭圆曲线密码库的抽象,它对摘要进行签名,从私钥计算公钥,并执行ecrecovery(从摘要和签名计算公钥)。

Creating Instances

new ethers . utils . SigningKey ( privateKey )
Create a new SigningKey and compute the corresponding public key and address. A private key may be a any hex string or an Arrayish representing 32 bytes.创建一个新的签名密钥并计算相应的公钥和地址。私钥可以是任何十六进制字符串,也可以是表示32字节的数组。

Prototype

prototype . address
The Ethereum checksum address for this key pair.得到密钥对的校验和地址
prototype . privateKey
The private key for the key pair.得到密钥对的私钥
prototype . publicKey
The uncompressed public key for the key pair.得到密钥对的公钥

Cryptographic Operations

prototype . signDigest ( messageDigest )   =>   hex
The flat-format Signature for the digests, signed by this key pair.摘要的flat格式签名,由此密钥对签名。
prototype . computeSharedSecret ( publicOrPrivateKey )   =>   hex
Compute the ECDH shared secret from this keys private key and the publicOrPrivateKey. In is generally considered good practice to further hash this value before using it as a key.从这个密钥、私钥和公钥计算ECDH共享密钥。通常将该值用作键被认为是在进一步散列之前的好操作。
出错:
TypeError: Cannot read property 'computePublicKey' of undefined

解决办法:使用

const secp256k1 = require("ethers/utils/secp256k1");
let compressed = true;
let publicKey = sec256k1.computePublicKey(someKey, compressed);

 

const ethers = require('ethers');
const secp256k1 = require("ethers/utils/secp256k1");

let privateKey = '0x0123456789012345678901234567890123456789012345678901234567890123';
let signingKey = new ethers.utils.SigningKey(privateKey);
console.log(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' }

console.log('Address: ' + signingKey.address);
// "Address: 0x14791697260E4c9A71f18484C9f997B308e59325"

let message = "Hello World";
let messageBytes = ethers.utils.toUtf8Bytes(message);
console.log(messageBytes);//Uint8Array [ 72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100 ]
let messageDigest = ethers.utils.keccak256(messageBytes);

console.log("Digest: " + messageDigest);
// "Digest: 0x592fa743889fc7f92ac2a37bb1f5ba1daf2a5c84741ca0e0061d243a2e6707ba"

let signature = signingKey.signDigest(messageDigest);

console.log(signature);
// {
//    v: 27,
//    r: "0x79f56f3422dc67f57b2aeeb0b20295a99ec90420b203177f83d419c98beda7fe",
//    s: "0x1a9d05433883bdc7e6d882740f4ea7921ef458a61b2cfe6197c2bb1bc47236fd"
// }

let privateShare = signingKey.computeSharedSecret(privateKey);//与下面使用publicKey得到的值时是相同的
console.log('privateShare : '+privateShare);//privateShare : 0xa442c51323b66fa73009ab663eb4ad3793a6becc400fb28582413750b84fcb28


let recovered = ethers.utils.recoverAddress(messageDigest, signature);

console.log("Recovered: " + recovered);
// "Recovered: 0x14791697260E4c9A71f18484C9f997B308e59325"


let publicKey = signingKey.publicKey;

console.log('Public Key: ' + publicKey);
// "Public Key: 0x046655feed4d214c261e0a6b554395596f1f1476a77d999560e5a8df9b8a1a3515217e88dd05e938efdd71b2cce322bf01da96cd42087b236e8f5043157a9c068e"

let publicShare = signingKey.computeSharedSecret(publicKey);
console.log('publicShare : '+publicShare);//publicShare : 0xa442c51323b66fa73009ab663eb4ad3793a6becc400fb28582413750b84fcb28

let compressedPublicKey = secp256k1.computePublicKey(publicKey, true);
let uncompressedPublicKey = secp256k1.computePublicKey(publicKey, false);

console.log(compressedPublicKey);
// "0x026655feed4d214c261e0a6b554395596f1f1476a77d999560e5a8df9b8a1a3515"

console.log(uncompressedPublicKey);
// "0x046655feed4d214c261e0a6b554395596f1f1476a77d999560e5a8df9b8a1a35" +
//   "15217e88dd05e938efdd71b2cce322bf01da96cd42087b236e8f5043157a9c068e"

let address = ethers.utils.computeAddress(publicKey);

console.log('Address: ' + address);
// "Address: 0x14791697260E4c9A71f18484C9f997B308e59325"

 

posted @ 2018-11-26 20:36  慢行厚积  阅读(1698)  评论(0编辑  收藏  举报