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。

362 lines (306 loc) 10.7 kB
import { RLPList, RLP } from "./rlp"; import { Util, U256 } from "./util"; /** * host function interface * @param type */ export function ___idof(type: ABI_DATA_TYPE): u32 { switch (type) { case ABI_DATA_TYPE.STRING: return idof<string>(); case ABI_DATA_TYPE.BYTES: return idof<ArrayBuffer>(); case ABI_DATA_TYPE.ADDRESS: return idof<Address>(); case ABI_DATA_TYPE.U256: return idof<U256>(); } return 0; } function __getAbiOf<T>(): ABI_DATA_TYPE { if (isBoolean<T>()) { return ABI_DATA_TYPE.BOOL; } if (isInteger<T>()) { if (isSigned<T>()) { return ABI_DATA_TYPE.I64; } else { return ABI_DATA_TYPE.U64; } } if (isFloat<T>()) return ABI_DATA_TYPE.F64; if (isString<T>()) return ABI_DATA_TYPE.STRING; if (idof<T>() == idof<Address>()) return ABI_DATA_TYPE.ADDRESS; if (idof<T>() == idof<U256>()) return ABI_DATA_TYPE.U256; assert(false, 'unexpected type ' + nameof<T>()); return ABI_DATA_TYPE.BOOL; } export enum ABI_DATA_TYPE { BOOL, // 0 I64, // 1 U64, // 2 BN F64, STRING, // 3 string BYTES, // 4 ADDRESS, // 5 U256, // 6 } // @ts-ignore @external("env", "_context") // type, dst, put ? declare function _context(type: u64, arg0: u64, arg1: u64, arg2: u64, arg3: u64): u64; // @ts-ignore @external("env", "_reflect") // type, address, method, parameters, dst // type, binary, parameters, 0, 0, amount , dst declare function _reflect(type: u64, ptr0: u64, ptr0Len: u64, ptr1: u64, ptr1Len: u64, ptr2: u64, ptr2Len: u64, amount_ptr: u64, amount_len: u64, dst: u64): u64; // @ts-ignore @external("env", "_transfer") // type, address, amount declare function _transfer(type: u64, ptr0: u64, ptr1Len: u64, amount_ptr: u64, amount_len: u64): void; // @ts-ignore @external("env", "_event") //result z declare function _event( arg0: u64, arg1: u64, arg2: u64, arg3: u64 ): void; function getBytes(type: u32): ArrayBuffer { const len = u32(_context(type, 0, 0, 0, 0)); const buf = new ArrayBuffer(u32(len)); _context(type, changetype<usize>(buf), 1, 0, 0); return buf; } function getU64(type: u32): u64 { return _context(type, 0, 0, 0, 0); } enum ReflectType { CALL_WITHOUT_PUT, // call without put into memory CALL_WITH_PUT, // call and put into memory CREATE } export class Address { @operator(">") static __op_gt(left: Address, right: Address): bool { return Util.compareBytes(left.buf, right.buf) > 0; } @operator(">=") static __op_gte(left: Address, right: Address): bool { return Util.compareBytes(left.buf, right.buf) >= 0; } @operator("<") static __op_lt(left: Address, right: Address): bool { return Util.compareBytes(left.buf, right.buf) < 0; } @operator("<=") static __op_lte(left: Address, right: Address): bool { return Util.compareBytes(left.buf, right.buf) <= 0; } @operator("==") static __op_eq(left: Address, right: Address): bool { return Util.compareBytes(left.buf, right.buf) == 0; } @operator("!=") static __op_ne(left: Address, right: Address): bool { return Util.compareBytes(left.buf, right.buf) != 0; } constructor(readonly buf: ArrayBuffer) { } transfer(amount: U256): void { const ptr = changetype<usize>(this.buf); _transfer(0, ptr, this.buf.byteLength, changetype<usize>(amount.buf), amount.buf.byteLength); } call<T>(method: string, parameters: Parameters, amount: U256): T { let abiType: ArrayBuffer = isVoid<T>() ? RLP.emptyList() : RLP.encodeU64(__getAbiOf<T>()); abiType = isVoid<T>() ? abiType : RLP.encodeElements([abiType]); const arr: Array<ArrayBuffer> = [RLP.encodeElements(parameters.types), RLP.encodeElements(parameters.li), abiType]; const buf = RLP.encodeElements(arr); const ptr0 = changetype<usize>(this.buf); const ptr0len = this.buf.byteLength; const str = String.UTF8.encode(method); const ptr1 = changetype<usize>(str); const ptr1len = str.byteLength; const ptr2 = changetype<usize>(buf); const ptr2len = buf.byteLength; const len = _reflect(ReflectType.CALL_WITHOUT_PUT, ptr0, ptr0len, ptr1, ptr1len, ptr2, ptr2len, changetype<usize>(amount.buf), amount.buf.byteLength, 0); const ret = new ArrayBuffer(u32(len)); _reflect(ReflectType.CALL_WITH_PUT, ptr0, ptr0len, ptr1, ptr1len, ptr2, ptr2len, changetype<usize>(amount.buf), amount.buf.byteLength, changetype<usize>(ret)); if (!isVoid<T>()) { return RLP.decode<T>(RLPList.fromEncoded(ret).getRaw(0)); } } balance(): U256 { const len = _context(ContextType.ACCOUNT_BALANCE, changetype<usize>(this.buf), this.buf.byteLength, 0, 0); const ret = new ArrayBuffer(u32(len)); _context(ContextType.ACCOUNT_BALANCE, changetype<usize>(this.buf), this.buf.byteLength, changetype<usize>(ret), 1); return new U256(ret); } nonce(): u64 { const ptr = changetype<usize>(this.buf); return _context(ContextType.ACCOUNT_NONCE, ptr, this.buf.byteLength, 0, 0); } // get contract code code(): ArrayBuffer { const ptr = changetype<usize>(this.buf); const len = _context(ContextType.CONTRACT_CODE, ptr, this.buf.byteLength, 0, 0); const ret = new ArrayBuffer(u32(len)); _context(ContextType.CONTRACT_CODE, ptr, this.buf.byteLength, changetype<usize>(ret), 1); return ret; } // get contract abi abi(): ArrayBuffer { const ptr = changetype<usize>(this.buf); const len = _context(ContextType.CONTRACT_ABI, ptr, this.buf.byteLength, 0, 0); const ret = new ArrayBuffer(u32(len)); _context(ContextType.CONTRACT_ABI, ptr, this.buf.byteLength, changetype<usize>(ret), 1); return ret; } toString(): string { return Util.encodeHex(this.buf); } } enum ContextType { HEADER_PARENT_HASH, HEADER_CREATED_AT, HEADER_HEIGHT, TX_TYPE, TX_CREATED_AT, TX_NONCE, TX_ORIGIN, TX_GAS_PRICE, TX_AMOUNT, TX_TO, TX_SIGNATURE, TX_HASH, CONTRACT_ADDRESS, CONTRACT_NONCE, ACCOUNT_NONCE, ACCOUNT_BALANCE, MSG_SENDER, MSG_AMOUNT, CONTRACT_CODE, CONTRACT_ABI } export enum TransactionType { COIN_BASE, TRANSFER, CONTRACT_DEPLOY, CONTRACT_CALL } export class ParametersBuilder { private readonly types: Array<ArrayBuffer>; private readonly elements: Array<ArrayBuffer>; constructor() { this.elements = new Array<ArrayBuffer>(); this.types = new Array<ArrayBuffer>(); } push<T>(data: T): void { this.types.push(RLP.encodeU64(__getAbiOf<T>())); this.elements.push(RLP.encode<T>(data)); } build(): Parameters { const ar = RLP.encodeElements(this.elements); return new Parameters(this.types, this.elements); } } export class Parameters { static EMPTY: Parameters = new Parameters([], []); constructor( readonly types: Array<ArrayBuffer>, readonly li: Array<ArrayBuffer> ) { } } export class Header { constructor( readonly parentHash: ArrayBuffer, readonly createdAt: u64, readonly height: u64 ) { } } export class Msg { constructor( readonly sender: Address, readonly amount: U256, ) { } } export class Transaction { constructor( readonly nonce: u64, readonly origin: Address, readonly gasPrice: U256, readonly amount: U256, readonly to: Address, readonly signature: ArrayBuffer, readonly hash: ArrayBuffer ) { } } export class Contract { constructor( readonly address: Address, readonly nonce: u64 ) { } } export class Context { /** * get address of current contract */ static self(): Address { return new Address(getBytes(ContextType.CONTRACT_ADDRESS)); } static emit<T>(t: T): void { const name = nameof<T>(); const nameBuf = Util.str2bin(name); if (isManaged<T>()) assert(false, 'class ' + name + ' should be annotated with @unmanaged') const buf = RLP.encode<T>(t); _event(changetype<usize>(nameBuf), nameBuf.byteLength, changetype<usize>(buf), buf.byteLength); } static header(): Header { return new Header( getBytes(ContextType.HEADER_PARENT_HASH), getU64(ContextType.HEADER_CREATED_AT), getU64(ContextType.HEADER_HEIGHT) ); } static msg(): Msg { return new Msg( new Address(getBytes(ContextType.MSG_SENDER)), new U256(getBytes(ContextType.MSG_AMOUNT)) ); } static transaction(): Transaction { return new Transaction( getU64(ContextType.TX_NONCE), new Address(getBytes(ContextType.TX_ORIGIN)), new U256(getBytes(ContextType.TX_GAS_PRICE)), new U256(getBytes(ContextType.TX_AMOUNT)), new Address(getBytes(ContextType.TX_TO)), getBytes(ContextType.TX_SIGNATURE), getBytes(ContextType.TX_HASH), ); } static contract(): Contract { return new Contract( new Address(getBytes(ContextType.CONTRACT_ADDRESS)), getU64(ContextType.CONTRACT_NONCE) ); } static create(code: ArrayBuffer, abi: ArrayBuffer, parameters: Parameters, amount: U256): Address { const ptr0 = changetype<usize>(code); const ptr0len = code.byteLength; const arr: Array<ArrayBuffer> = [RLP.encodeElements(parameters.types), RLP.encodeElements(parameters.li), RLP.emptyList()]; const buf = RLP.encodeElements(arr); const ptr1 = changetype<usize>(buf); const ptr1len = buf.byteLength; const ret = new ArrayBuffer(20); _reflect(ReflectType.CREATE, ptr0, ptr0len, ptr1, ptr1len, changetype<usize>(abi), abi.byteLength, changetype<usize>(amount.buf), amount.buf.byteLength, changetype<usize>(ret)); return new Address(ret); } }