UNPKG

keystore_wdc

Version:

``` npm i keystore_wdc; const KeyStore = require('keystore_wdc'); const ks = new KeyStore(); ``` #### 生成keystore ``` async function create(){ const keystore = await ks.Create("your password"); } ``` * 返回keystore,密码格式不正确返回-1。

197 lines (182 loc) 6.5 kB
/** * 事务 */ import { AbiInput, ABI_DATA_TYPE, Binary, constants, Digital, Readable } from "./types" import { bin2str, concatArray, convert, dig2str, digest, extendPrivateKey, hex2bin, padPrefix, toSafeInt } from "./utils" import { bin2hex } from "./utils" import BN = require("../bn") import rlp = require('./rlp') import nacl = require('../nacl.min.js') import { Encoder } from "./rlp" import { ABI, Contract } from "./contract" export class Transaction implements Encoder { version: string type: string nonce: string from: string gasPrice: string amount: string payload: string to: string signature: string __abi?: ABI[] __inputs?: Readable[] | Record<string, Readable> /** * constructor of transaction */ constructor(version?: Digital, type?: Digital, nonce?: Digital, from?: Binary, gasPrice?: Digital, amount?: Digital, payload?: Binary, to?: Binary, signature?: Binary, __abi?: any, __inputs?: any) { this.version = dig2str(version || 0) this.type = dig2str(type || 0) this.nonce = dig2str(nonce || 0) this.from = bin2hex(from || '') this.gasPrice = dig2str(gasPrice || 0) this.amount = dig2str(amount || 0) this.payload = bin2hex(payload || '') this.to = bin2hex(to || '') this.signature = bin2hex(signature || '') this.__abi = __abi this.__inputs = __inputs } static clone(o: any): Transaction { return new Transaction(o.version, o.type, o.nonce, o.from, o.gasPrice, o.amount, o.payload, o.to, o.signature) } /** * 解析16进制字符串的事务,包含哈希值 * @param x */ static fromRPCBytes(x: Binary): Transaction{ return Transaction.fromRaw(x, true) } /** * * @param x 解析16进制字符串的事务 */ static fromRaw(x: Binary, hash = false): Transaction { const args = [] let offset = 0 const shift = (n: number) => { offset = offset + n return offset } const u8 = hex2bin(x) // version args.push(u8[offset++]) // skip hash if(hash) offset += 32 // type args.push(u8[offset++]) // nonce args.push( new BN(u8.slice(offset, shift(8)), 'hex', 'be') ) // from args.push(u8.slice(offset, shift(32))) // gasprice args.push( new BN(u8.slice(offset, shift(8)), 'hex', 'be') ) // amount args.push( new BN(u8.slice(offset, shift(8)), 'hex', 'be') ) // signature const sig = u8.slice(offset, shift(64)) // to const to = u8.slice(offset, shift(20)) // payload length const len = (new BN(u8.slice(offset, shift(4)), 'hex', 'be')).toNumber() // payload const p = u8.slice(offset, shift(len)) args.push(p, to, sig) return new Transaction(...args) } /** * 计算事务哈希值 */ getHash(): Uint8Array { return digest(this.getRaw(false)) } /** * 生成事务签名或者哈希值计算需要的原文 * 如果需要签名的话 getRaw 填写 true */ getRaw(nullSig: boolean): Uint8Array { let sig = nullSig ? new Uint8Array(64) : hex2bin(this.signature) const p = hex2bin(this.payload) return concatArray( [ new Uint8Array([parseInt(this.version)]), new Uint8Array([parseInt(this.type)]), padPrefix((new BN(this.nonce)).toArrayLike(Uint8Array, 'be'), 0, 8), hex2bin(this.from), padPrefix((new BN(this.gasPrice)).toArrayLike(Uint8Array, 'be'), 0, 8), padPrefix((new BN(this.amount)).toArrayLike(Uint8Array, 'be'), 0, 8), sig, hex2bin(this.to), padPrefix((new BN(p.length)).toArrayLike(Uint8Array, 'be'), 0, 4), p ] ) } /** * rlp 编码结果 */ getEncoded(): Uint8Array { const arr = this.__toArr() return rlp.encode(arr) } __toArr(): Array<string | Uint8Array | BN> { return [ convert(this.version || 0, ABI_DATA_TYPE.u64), convert(this.type || 0, ABI_DATA_TYPE.u64), convert(this.nonce || '0', ABI_DATA_TYPE.u64), convert(this.from || '', ABI_DATA_TYPE.bytes), convert(this.gasPrice || '0', ABI_DATA_TYPE.u256), convert(this.amount || '0', ABI_DATA_TYPE.u256), convert(this.payload || '', ABI_DATA_TYPE.bytes), hex2bin(this.to), convert(this.signature || '', ABI_DATA_TYPE.bytes) ] } /** * 签名 */ sign(_sk: Binary): void { let sk = hex2bin(_sk) sk = extendPrivateKey(sk) this.signature = bin2hex(nacl.sign(this.getRaw(true), sk).slice(0, 64)) } __setInputs(__inputs: AbiInput[] | Record<string, AbiInput>): void { const cnv: (x: AbiInput) => Readable = (x) => { if (x instanceof ArrayBuffer || x instanceof Uint8Array) return bin2hex(x) if (x instanceof BN || typeof x === 'bigint') return toSafeInt(x) return x } if (Array.isArray(__inputs)) { this.__inputs = __inputs.map(cnv) } else { this.__inputs = {} for (let k of Object.keys(__inputs)) { this.__inputs[k] = cnv(__inputs[k]) } } if (Array.isArray(this.__inputs)) { const c = new Contract('', this.__abi) const a = c.getABI(this.getMethod(), 'function') if (a.inputsObj()) { this.__inputs = <Record<string, Readable>>a.toObj(this.__inputs, true) } } } getMethod(): string { const t = parseInt(this.type) return t === constants.WASM_DEPLOY ? 'init' : bin2str(<Uint8Array>(rlp.decode(hex2bin(this.payload)))[1]) } isDeployOrCall(): boolean { const t = parseInt(this.type) return t === constants.WASM_DEPLOY || t === constants.WASM_CALL } }