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。

412 lines 19.7 kB
"use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; var __generator = (this && this.__generator) || function (thisArg, body) { var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; function verb(n) { return function (v) { return step([n, v]); }; } function step(op) { if (f) throw new TypeError("Generator is already executing."); while (_) try { if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; if (y = 0, t) op = [op[0] & 2, t.value]; switch (op[0]) { case 0: case 1: t = op; break; case 4: _.label++; return { value: op[1], done: false }; case 5: _.label++; y = op[1]; op = [0]; continue; case 7: op = _.ops.pop(); _.trys.pop(); continue; default: if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } if (t[2]) _.ops.pop(); _.trys.pop(); continue; } op = body.call(thisArg, _); } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; } }; Object.defineProperty(exports, "__esModule", { value: true }); exports.VirtualMachine = exports.isZero = exports.MemoryView = void 0; var utils_1 = require("./utils"); var contract_1 = require("./contract"); var types_1 = require("./types"); var hosts_1 = require("./hosts"); var BN = require("../bn"); var rlp = require("./rlp"); var utf16Decoder = new TextDecoder('utf-16'); var utf8Decoder = new TextDecoder(); /** * 对字符串进行 utf16 编码,用于向 WebAssembly 内存中导入 * @param str */ function strEncodeUTF16(str) { var buf = new ArrayBuffer(str.length * 2); var bufView = new Uint16Array(buf); for (var i = 0, strLen = str.length; i < strLen; i++) { bufView[i] = str.charCodeAt(i); } return buf; } var MemoryView = /** @class */ (function () { function MemoryView(mem) { this.view = new DataView(mem.buffer); } MemoryView.prototype.loadUTF8 = function (offset, length) { return utf8Decoder.decode(this.loadN(offset, length)); }; MemoryView.prototype.loadUTF16 = function (offset) { return utf16Decoder.decode(this.loadBuffer(Number(offset))); }; MemoryView.prototype.loadU32 = function (offset) { return this.view.getUint32(Number(offset), true); }; MemoryView.prototype.loadBuffer = function (offset) { var len = this.loadU32(Number(offset) - 4); return this.loadN(offset, len); }; MemoryView.prototype.loadN = function (offset, length) { return this.view.buffer.slice(Number(offset), Number(offset) + Number(length)); }; MemoryView.prototype.put = function (offset, data) { new Uint8Array(this.view.buffer).set(new Uint8Array(data), Number(offset)); }; return MemoryView; }()); exports.MemoryView = MemoryView; function isZero(n) { return n === 0 || n === BigInt(0); } exports.isZero = isZero; /** * virtual machine for chrome debugging */ var VirtualMachine = /** @class */ (function () { function VirtualMachine() { // current block height this.height = 0; // current block hash this.hash = (new Uint8Array(32)).buffer; // contract address -> url this.contractCode = new Map(); // cache for abi this.abiCache = new Map(); // record nonce this.nonceMap = new Map(); this.balanceMap = new Map(); this.storage = new Map(); if (typeof WebAssembly !== 'object') throw new Error('webassembly not available here'); this.nextBlock(); } VirtualMachine.prototype.normParams = function (abi, params) { var p = contract_1.normalizeParams(params); if (Array.isArray(p)) return p; var ret = []; abi.inputs.forEach(function (i) { ret.push(params[i.name]); }); return ret; }; VirtualMachine.prototype.putParams = function (instance, abi, params) { var arr; if (Array.isArray(params)) { arr = params; } else { arr = []; abi.inputs.forEach(function (x) { return arr.push(params[x.name]); }); } for (var i = 0; i < abi.inputs.length; i++) { var t = types_1.ABI_DATA_TYPE[abi.inputs[i].type]; var id = instance.exports.__idof(t); } }; VirtualMachine.prototype.malloc = function (instance, val, type) { var view = new MemoryView(instance.exports.memory); var data; var id = Number(instance.exports.__idof(type)); var offset; switch (type) { case types_1.ABI_DATA_TYPE.f64: case types_1.ABI_DATA_TYPE.bool: case types_1.ABI_DATA_TYPE.i64: case types_1.ABI_DATA_TYPE.u64: { var converted = utils_1.convert(val, type); if (type === types_1.ABI_DATA_TYPE.f64) { return utils_1.bytesToF64(converted); } if (type == types_1.ABI_DATA_TYPE.bool) { return converted.toNumber(); } var l = (converted instanceof Uint8Array ? new BN(converted, 10, 'be') : converted); return BigInt(l.toString(10)); } case types_1.ABI_DATA_TYPE.string: { var converted = utils_1.convert(val, type); data = strEncodeUTF16(converted); offset = instance.exports.__alloc(data.byteLength, id); break; } case types_1.ABI_DATA_TYPE.bytes: { data = utils_1.convert(val, types_1.ABI_DATA_TYPE.bytes).buffer; offset = instance.exports.__alloc(data.byteLength, id); break; } case types_1.ABI_DATA_TYPE.u256: { var converted = utils_1.convert(val, type); var buf = utils_1.encodeBE(converted).buffer; var ptr = this.malloc(instance, buf, types_1.ABI_DATA_TYPE.bytes); data = utils_1.encodeUint32(ptr); offset = instance.exports.__alloc(4, id); break; } case types_1.ABI_DATA_TYPE.address: { var buf = utils_1.convert(val, types_1.ABI_DATA_TYPE.address).buffer; offset = instance.exports.__alloc(4, id); var ptr = this.malloc(instance, buf, types_1.ABI_DATA_TYPE.bytes); data = utils_1.encodeUint32(ptr); break; } } view.put(offset, data); instance.exports.__retain(offset); return offset; }; VirtualMachine.prototype.alloc = function (address, amount) { this.balanceMap.set(utils_1.bin2hex(utils_1.normalizeAddress(address)), utils_1.convert(amount, types_1.ABI_DATA_TYPE.u256)); }; // 模拟下一区块的生成 VirtualMachine.prototype.nextBlock = function () { this.height++; this.parentHash = this.hash; this.hash = utils_1.digest(rlp.encode(this.height)).buffer; this.now = Math.floor((new Date()).valueOf() / 1000); }; VirtualMachine.prototype.addBalance = function (addr, amount) { var hex = utils_1.bin2hex(utils_1.normalizeAddress(addr)); var balance = this.balanceMap.get(hex) || types_1.ZERO; balance = balance.add(utils_1.dig2BN(amount || types_1.ZERO)); this.balanceMap.set(hex, balance); }; VirtualMachine.prototype.subBalance = function (addr, amount) { var hex = utils_1.bin2hex(utils_1.normalizeAddress(addr)); var balance = this.balanceMap.get(hex) || types_1.ZERO; var a = utils_1.dig2BN(amount || types_1.ZERO); if (balance.cmp(a) < 0) throw new Error("the balance of " + hex + " is not enough"); balance = balance.sub(a); this.balanceMap.set(hex, balance); }; VirtualMachine.prototype.increaseNonce = function (sender) { var senderHex = utils_1.bin2hex(utils_1.normalizeAddress(sender)); var n = (this.nonceMap.get(senderHex) || 0) + 1; this.nonceMap.set(senderHex, n); return n; }; VirtualMachine.prototype.call = function (sender, addr, method, params, amount) { var origin = utils_1.normalizeAddress(sender).buffer; var n = this.increaseNonce(sender); return this.callInternal(method, { type: null, sender: origin, to: utils_1.normalizeAddress(addr).buffer, amount: utils_1.dig2BN(amount || types_1.ZERO), nonce: n, origin: origin, txHash: utils_1.digest(rlp.encode([utils_1.normalizeAddress(sender), n])).buffer, contractAddress: utils_1.normalizeAddress(addr).buffer, readonly: false }, params); }; VirtualMachine.prototype.callInternal = function (method, ctx, params) { return __awaiter(this, void 0, void 0, function () { var file, abi, mem, env, hosts, module, instance, a, arr, args, i, ret; return __generator(this, function (_a) { switch (_a.label) { case 0: // 1. substract amount this.subBalance(ctx.sender, ctx.amount); this.addBalance(ctx.contractAddress, ctx.amount); ctx.type = method === 'init' ? 16 : 17; file = this.contractCode.get(utils_1.bin2hex(ctx.contractAddress)); return [4 /*yield*/, this.fetchABI(file)]; case 1: abi = _a.sent(); mem = new WebAssembly.Memory({ initial: 10, maximum: 65535 }); env = { memory: mem, }; hosts = [ new hosts_1.Log(this), new hosts_1.Abort(this), new hosts_1.Util(this), new hosts_1.HashHost(this), new hosts_1.EventHost(this, ctx), new hosts_1.DBHost(this, ctx), new hosts_1.ContextHost(this, ctx), new hosts_1.RLPHost(this), new hosts_1.Reflect(this), new hosts_1.Transfer(this, ctx), new hosts_1.Uint256Host(this) ]; hosts.forEach(function (h) { h.init(env); env[h.name()] = function () { var args = []; for (var _i = 0; _i < arguments.length; _i++) { args[_i] = arguments[_i]; } return h.execute(args); }; }); return [4 /*yield*/, WebAssembly.compileStreaming(fetch(file))]; case 2: module = _a.sent(); console.log(module); return [4 /*yield*/, WebAssembly.instantiateStreaming(fetch(file), { env: env, })]; case 3: instance = (_a.sent()).instance; console.log('initialized'); if (typeof instance.exports[method] !== 'function') { throw new Error("call internal failed: " + method + " not found"); } a = abi.filter(function (x) { return x.type === 'function' && x.name === method; })[0]; arr = this.normParams(a, params); args = []; for (i = 0; i < a.inputs.length; i++) { args.push(this.malloc(instance, arr[i], types_1.ABI_DATA_TYPE[a.inputs[i].type])); } console.log('call!!!!'); ret = instance.exports[method].apply(window, args); if (a.outputs && a.outputs.length) return [2 /*return*/, this.extractRet(instance, ret, types_1.ABI_DATA_TYPE[a.outputs[0].type])]; return [2 /*return*/]; } }); }); }; VirtualMachine.prototype.extractRet = function (ins, offset, type) { var ret = this.extractRetInternal(ins, offset, type); if (!(ret instanceof ArrayBuffer)) { return ret; } switch (type) { case types_1.ABI_DATA_TYPE.bytes: return utils_1.bin2hex(ret); case types_1.ABI_DATA_TYPE.address: return utils_1.publicKeyHash2Address(ret); case types_1.ABI_DATA_TYPE.u256: return utils_1.toSafeInt(ret); default: throw new Error('unexpected'); } }; VirtualMachine.prototype.extractRetInternal = function (ins, offset, type) { var view = new MemoryView(ins.exports.memory); switch (type) { case types_1.ABI_DATA_TYPE.bool: return Number(offset) !== 0; case types_1.ABI_DATA_TYPE.i64: return utils_1.toSafeInt(offset); case types_1.ABI_DATA_TYPE.u64: { // 即使webassembly 返回类型是 uint, bigint 也会出现小于 0 的情况,需要自行转换 if (offset < 0) { var buf = new ArrayBuffer(8); new DataView(buf).setBigInt64(0, BigInt(offset)); return utils_1.toSafeInt(buf); } return utils_1.toSafeInt(offset); } case types_1.ABI_DATA_TYPE.f64: { return offset; } case types_1.ABI_DATA_TYPE.string: { return utf16Decoder.decode(this.extractRetInternal(ins, offset, types_1.ABI_DATA_TYPE.bytes)); } case types_1.ABI_DATA_TYPE.bytes: { var len = view.loadU32(Number(offset) - 4); return view.loadN(offset, len); } case types_1.ABI_DATA_TYPE.address: case types_1.ABI_DATA_TYPE.u256: { var ptr = view.loadU32(offset); return this.extractRetInternal(ins, ptr, types_1.ABI_DATA_TYPE.bytes); } } }; VirtualMachine.prototype.view = function () { return __awaiter(this, void 0, void 0, function () { return __generator(this, function (_a) { return [2 /*return*/, null]; }); }); }; // 合约部署 VirtualMachine.prototype.deploy = function (sender, wasmFile, parameters, amount) { return __awaiter(this, void 0, void 0, function () { var senderAddress, n, txHash, contractAddress, contractAddressHex, abi, a; return __generator(this, function (_a) { switch (_a.label) { case 0: senderAddress = utils_1.normalizeAddress(sender); n = this.increaseNonce(sender); txHash = utils_1.digest(rlp.encode([utils_1.normalizeAddress(sender), n])); contractAddress = utils_1.normalizeAddress(contract_1.getContractAddress(txHash)); contractAddressHex = utils_1.bin2hex(contractAddress); return [4 /*yield*/, this.fetchABI(wasmFile)]; case 1: abi = _a.sent(); this.abiCache.set(contractAddressHex, abi); this.contractCode.set(contractAddressHex, wasmFile); a = abi.filter(function (x) { return x.type === 'function' && x.name === 'init'; })[0]; // try to execute init function if (a) { return [2 /*return*/, this.callInternal('init', { type: null, sender: senderAddress, to: new Uint8Array(20).buffer, amount: utils_1.dig2BN(amount || types_1.ZERO), nonce: n, origin: senderAddress, txHash: txHash.buffer, contractAddress: contractAddress.buffer, readonly: false }, parameters)]; } this.nextBlock(); return [2 /*return*/, null]; } }); }); }; // 根据文件名规范获取 abi VirtualMachine.prototype.fetchABI = function (wasmFile) { return __awaiter(this, void 0, void 0, function () { var f, resp, buf; return __generator(this, function (_a) { switch (_a.label) { case 0: f = wasmFile.replace(/^(.*)\.wasm$/, '$1.abi.json'); if (this.abiCache.has(f)) return [2 /*return*/, this.abiCache.get(f)]; return [4 /*yield*/, fetch(f)]; case 1: resp = _a.sent(); return [4 /*yield*/, resp.arrayBuffer()]; case 2: buf = _a.sent(); return [2 /*return*/, JSON.parse(utils_1.bin2str(buf))]; } }); }); }; return VirtualMachine; }()); exports.VirtualMachine = VirtualMachine; //# sourceMappingURL=vm.js.map