UNPKG

meta-contract

Version:

Meta Contract SDK

259 lines (258 loc) 10.6 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.getQuerySensibleID = exports.getQueryGenesis = exports.getQueryCodehash = exports.updateScript = exports.parseDataPart = exports.newDataPart = exports.getNewTokenScript = exports.getDataPart = exports.getContractCodeHash = exports.getContractCode = exports.getTokenName = exports.getTokenSymbol = exports.getGenesisFlag = exports.getDecimalNum = exports.getTokenAddress = exports.getGenesisHash = exports.getRabinPubKeyHashArrayHash = exports.getSensibleID = exports.getTokenID = exports.getTokenAmount = exports.getHeaderLen = exports.GENESIS_FLAG = exports.FT_OP_TYPE = exports.OP_UNLOCK_FROM_CONTRACT = exports.OP_TRANSFER = exports.nonGenesisFlag = exports.EMPTY_ADDRESS = exports.GENESIS_TOKEN_ID = exports.PROTO_VERSION = void 0; const BN = require("../../bn.js/index.js"); const mvc = require("../../mvc"); const proto = require("../../common/protoheader"); const Utils = require("../../common/utils"); const scryptlib_1 = require("../../scryptlib"); exports.PROTO_VERSION = 1; // <op_pushdata> + <type specific data> + <proto header> + <data_len(4 bytes)> + <version(1 bytes)> // <token type specific data> = <name(40 bytes)> + <symbol(20 bytes)> + <decimal(1 bytes)> + <address(20 bytes)> + <token amount(8 bytes)> + <genesisHash(20 bytes)> + <genesisTxid(36 bytes)> // name 40 // symbol 20 // decimal 1 // address 20 // token amount/token value 8 // genesis hash 20 // genesis txid 36 // token version // 4 // token type // 4 // protp flag // 12 const TOKEN_ID_LEN = 20; const GENESIS_TX_ID_LEN = 36; const RABIN_PUBKEY_HASH_ARRAY_HASH_LEN = 20; const GENESIS_HASH_LEN = 20; const TOKEN_AMOUNT_LEN = 8; const TOKEN_ADDRESS_LEN = 20; const DECIMAL_NUM_LEN = 1; const GENESIS_FLAG_LEN = 1; const TOKEN_SYMBOL_LEN = 10; const TOKEN_NAME_LEN = 40; const GENESIS_TX_ID_OFFSET = GENESIS_TX_ID_LEN + proto.getHeaderLen(); const RABIN_PUBKEY_HASH_ARRAY_HASH_OFFSET = GENESIS_TX_ID_OFFSET + RABIN_PUBKEY_HASH_ARRAY_HASH_LEN; const GENESIS_HASH_OFFSET = RABIN_PUBKEY_HASH_ARRAY_HASH_OFFSET + GENESIS_HASH_LEN; const TOKEN_AMOUNT_OFFSET = GENESIS_HASH_OFFSET + TOKEN_AMOUNT_LEN; const TOKEN_ADDRESS_OFFSET = TOKEN_AMOUNT_OFFSET + TOKEN_ADDRESS_LEN; const DECIMAL_NUM_OFFSET = TOKEN_ADDRESS_OFFSET + DECIMAL_NUM_LEN; const GENESIS_FLAG_OFFSET = DECIMAL_NUM_OFFSET + GENESIS_FLAG_LEN; const TOKEN_SYMBOL_OFFSET = GENESIS_FLAG_OFFSET + TOKEN_SYMBOL_LEN; const TOKEN_NAME_OFFSET = TOKEN_SYMBOL_OFFSET + TOKEN_NAME_LEN; const TOKEN_HEADER_LEN = TOKEN_NAME_OFFSET; exports.GENESIS_TOKEN_ID = Buffer.alloc(TOKEN_ID_LEN, 0); exports.EMPTY_ADDRESS = Buffer.alloc(TOKEN_ADDRESS_LEN, 0); exports.nonGenesisFlag = Buffer.alloc(1, 0); exports.OP_TRANSFER = 1; exports.OP_UNLOCK_FROM_CONTRACT = 2; var FT_OP_TYPE; (function (FT_OP_TYPE) { FT_OP_TYPE[FT_OP_TYPE["TRANSFER"] = 1] = "TRANSFER"; FT_OP_TYPE[FT_OP_TYPE["UNLOCK_FROM_CONTRACT"] = 2] = "UNLOCK_FROM_CONTRACT"; })(FT_OP_TYPE = exports.FT_OP_TYPE || (exports.FT_OP_TYPE = {})); var GENESIS_FLAG; (function (GENESIS_FLAG) { GENESIS_FLAG[GENESIS_FLAG["FALSE"] = 0] = "FALSE"; GENESIS_FLAG[GENESIS_FLAG["TRUE"] = 1] = "TRUE"; })(GENESIS_FLAG = exports.GENESIS_FLAG || (exports.GENESIS_FLAG = {})); function getHeaderLen() { return TOKEN_HEADER_LEN; } exports.getHeaderLen = getHeaderLen; function getTokenAmount(script) { if (script.length < TOKEN_AMOUNT_OFFSET) return BN.Zero; return BN.fromBuffer(script.slice(script.length - TOKEN_AMOUNT_OFFSET, script.length - TOKEN_AMOUNT_OFFSET + TOKEN_AMOUNT_LEN), { endian: 'little' }); } exports.getTokenAmount = getTokenAmount; function getTokenID(script) { return mvc.crypto.Hash.sha256ripemd160(script.slice(script.length - GENESIS_HASH_OFFSET, script.length - proto.getHeaderLen())); } exports.getTokenID = getTokenID; function getSensibleID(script0) { if (script0.length < GENESIS_TX_ID_OFFSET) return { txid: '', index: 0 }; let script = Buffer.from(script0); let sensibleIDBuf = script.slice(script.length - GENESIS_TX_ID_OFFSET, script.length - GENESIS_TX_ID_OFFSET + GENESIS_TX_ID_LEN); let txid = sensibleIDBuf.slice(0, 32).reverse().toString('hex'); //reverse会改变原对象 let index = sensibleIDBuf.readUIntLE(32, 4); let sensibleID = { txid, index }; return sensibleID; } exports.getSensibleID = getSensibleID; function getRabinPubKeyHashArrayHash(script) { return script .slice(script.length - RABIN_PUBKEY_HASH_ARRAY_HASH_OFFSET, script.length - RABIN_PUBKEY_HASH_ARRAY_HASH_OFFSET + RABIN_PUBKEY_HASH_ARRAY_HASH_LEN) .toString('hex'); } exports.getRabinPubKeyHashArrayHash = getRabinPubKeyHashArrayHash; function getGenesisHash(script) { return script .slice(script.length - GENESIS_HASH_OFFSET, script.length - GENESIS_HASH_OFFSET + GENESIS_HASH_LEN) .toString('hex'); } exports.getGenesisHash = getGenesisHash; function getTokenAddress(script) { if (script.length < TOKEN_ADDRESS_OFFSET) return ''; return script .slice(script.length - TOKEN_ADDRESS_OFFSET, script.length - TOKEN_ADDRESS_OFFSET + TOKEN_ADDRESS_LEN) .toString('hex'); } exports.getTokenAddress = getTokenAddress; function getDecimalNum(script) { if (script.length < DECIMAL_NUM_OFFSET) return 0; return script.readUIntLE(script.length - DECIMAL_NUM_OFFSET, DECIMAL_NUM_LEN); } exports.getDecimalNum = getDecimalNum; function getGenesisFlag(script) { if (script.length < GENESIS_FLAG_OFFSET) return 0; return script.readUIntLE(script.length - GENESIS_FLAG_OFFSET, GENESIS_FLAG_LEN); } exports.getGenesisFlag = getGenesisFlag; function getTokenSymbol(script) { if (script.length < TOKEN_SYMBOL_OFFSET) return ''; let buf = script.slice(script.length - TOKEN_SYMBOL_OFFSET, script.length - TOKEN_SYMBOL_OFFSET + TOKEN_SYMBOL_LEN); return buf.toString(); } exports.getTokenSymbol = getTokenSymbol; function getTokenName(script) { if (script.length < TOKEN_NAME_OFFSET) return ''; let buf = script.slice(script.length - TOKEN_NAME_OFFSET, script.length - TOKEN_NAME_OFFSET + TOKEN_NAME_LEN); return buf.toString(); } exports.getTokenName = getTokenName; function getContractCode(script) { return script.slice(0, script.length - TOKEN_HEADER_LEN - Utils.getVarPushdataHeader(TOKEN_HEADER_LEN).length); } exports.getContractCode = getContractCode; function getContractCodeHash(script) { return mvc.crypto.Hash.sha256ripemd160(getContractCode(script)); } exports.getContractCodeHash = getContractCodeHash; function getDataPart(script) { return script.slice(script.length - TOKEN_HEADER_LEN, script.length); } exports.getDataPart = getDataPart; function getNewTokenScript(scriptBuf, address, tokenAmount) { const amountBuf = tokenAmount.toBuffer({ endian: 'little', size: 8 }); const firstBuf = scriptBuf.slice(0, scriptBuf.length - TOKEN_ADDRESS_OFFSET); const newScript = Buffer.concat([ firstBuf, address, amountBuf, scriptBuf.slice(scriptBuf.length - GENESIS_HASH_OFFSET, scriptBuf.length), ]); return newScript; } exports.getNewTokenScript = getNewTokenScript; function newDataPart({ tokenName, tokenSymbol, decimalNum, genesisHash, address, // bufferValue = 总为80 genesisTxid, protoType, protoVersion, }) { const tokenNameBuf = Buffer.alloc(TOKEN_NAME_LEN, 0); if (tokenName) { tokenNameBuf.write(tokenName); } const tokenSymbolBuf = Buffer.alloc(TOKEN_SYMBOL_LEN, 0); if (tokenSymbol) { tokenSymbolBuf.write(tokenSymbol); } const decimalBuf = Buffer.alloc(DECIMAL_NUM_LEN, 0); if (decimalNum) { decimalBuf.writeUInt8(decimalNum); } const addressBuf = Buffer.alloc(20, 0); if (address) { addressBuf.write(address, 'hex'); } const buffValue = Buffer.alloc(8, 0); const genesisHashBuf = Buffer.alloc(GENESIS_HASH_LEN, 0); if (genesisHash) { genesisHashBuf.write(genesisHash, 'hex'); } const genesisTxidBuf = Buffer.alloc(GENESIS_HASH_LEN, 0); if (genesisTxid) { genesisTxidBuf.write(genesisTxid); } const protoTypeBuf = Buffer.alloc(proto.PROTO_TYPE_LEN, 0); if (protoType) { protoTypeBuf.writeUInt32LE(protoType); } const protoVersionBuf = Buffer.alloc(proto.PROTO_VERSION_LEN); if (protoVersion) { protoVersionBuf.writeUInt32LE(protoVersion); } /** TOKEN_NAME, TOKEN_SYMBOL, DECIMAL_NUM, address1.hashBuffer, buffValue, genesisHash, genesisTxidBuf, tokenVersion, = protoVersion tokenType, = protoType PROTO_FLAG, */ return Buffer.concat([ tokenNameBuf, tokenSymbolBuf, decimalBuf, addressBuf, buffValue, genesisHashBuf, genesisTxidBuf, protoVersionBuf, protoTypeBuf, proto.PROTO_FLAG, ]); } exports.newDataPart = newDataPart; function parseDataPart(scriptBuf) { let tokenName = getTokenName(scriptBuf); let tokenSymbol = getTokenSymbol(scriptBuf); let decimalNum = getDecimalNum(scriptBuf); let genesisFlag = getGenesisFlag(scriptBuf); let tokenAddress = getTokenAddress(scriptBuf); let tokenAmount = getTokenAmount(scriptBuf); let genesisHash = getGenesisHash(scriptBuf); let sensibleID = getSensibleID(scriptBuf); let protoVersion = proto.getProtoVersion(scriptBuf); let protoType = proto.getProtoType(scriptBuf); return { tokenName, tokenSymbol, decimalNum, genesisFlag, tokenAddress, tokenAmount, genesisHash, sensibleID, protoVersion, protoType, }; } exports.parseDataPart = parseDataPart; function updateScript(scriptBuf, dataPartObj) { const firstBuf = scriptBuf.slice(0, scriptBuf.length - TOKEN_HEADER_LEN); const dataPart = newDataPart(dataPartObj); return Buffer.concat([firstBuf, dataPart]); } exports.updateScript = updateScript; function getQueryCodehash(script) { return (0, scryptlib_1.toHex)(getContractCodeHash(script)); } exports.getQueryCodehash = getQueryCodehash; function getQueryGenesis(script) { return (0, scryptlib_1.toHex)(getTokenID(script)); } exports.getQueryGenesis = getQueryGenesis; function getQuerySensibleID(script0) { let script = Buffer.from(script0); let sensibleIDBuf = script.slice(script.length - GENESIS_TX_ID_OFFSET, script.length - GENESIS_TX_ID_OFFSET + GENESIS_TX_ID_LEN); return (0, scryptlib_1.toHex)(sensibleIDBuf); } exports.getQuerySensibleID = getQuerySensibleID;