meta-contract
Version:
Meta Contract SDK
213 lines (212 loc) • 10.6 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.TokenTransferCheckFactory = exports.TokenTransferCheck = exports.TOKEN_TRANSFER_TYPE = void 0;
const BN = require("../../bn.js");
const mvc = require("../../mvc");
const ContractAdapter_1 = require("../../common/ContractAdapter");
const dummy_1 = require("../../common/dummy");
const TokenUtil = require("../../common/tokenUtil");
const utils_1 = require("../../common/utils");
const scryptlib_1 = require("../../scryptlib");
const token_proto_1 = require("../contract-proto/token.proto");
const proto = require("../contract-proto/tokenTransferCheck.proto");
const token_1 = require("./token");
var TOKEN_TRANSFER_TYPE;
(function (TOKEN_TRANSFER_TYPE) {
TOKEN_TRANSFER_TYPE[TOKEN_TRANSFER_TYPE["IN_3_OUT_3"] = 1] = "IN_3_OUT_3";
TOKEN_TRANSFER_TYPE[TOKEN_TRANSFER_TYPE["IN_6_OUT_6"] = 2] = "IN_6_OUT_6";
TOKEN_TRANSFER_TYPE[TOKEN_TRANSFER_TYPE["IN_10_OUT_10"] = 3] = "IN_10_OUT_10";
TOKEN_TRANSFER_TYPE[TOKEN_TRANSFER_TYPE["IN_20_OUT_3"] = 4] = "IN_20_OUT_3";
TOKEN_TRANSFER_TYPE[TOKEN_TRANSFER_TYPE["IN_3_OUT_100"] = 5] = "IN_3_OUT_100";
TOKEN_TRANSFER_TYPE[TOKEN_TRANSFER_TYPE["UNSUPPORT"] = 6] = "UNSUPPORT";
})(TOKEN_TRANSFER_TYPE = exports.TOKEN_TRANSFER_TYPE || (exports.TOKEN_TRANSFER_TYPE = {}));
let _tokenTransferTypeInfos = [
{
type: TOKEN_TRANSFER_TYPE.IN_3_OUT_3,
in: 3,
out: 3,
lockingScriptSize: 0,
},
{
type: TOKEN_TRANSFER_TYPE.IN_6_OUT_6,
in: 6,
out: 6,
lockingScriptSize: 0,
},
{
type: TOKEN_TRANSFER_TYPE.IN_10_OUT_10,
in: 10,
out: 10,
lockingScriptSize: 0,
},
{
type: TOKEN_TRANSFER_TYPE.IN_20_OUT_3,
in: 20,
out: 3,
lockingScriptSize: 0,
},
{
type: TOKEN_TRANSFER_TYPE.IN_3_OUT_100,
in: 3,
out: 100,
lockingScriptSize: 0,
},
];
class TokenTransferCheck extends ContractAdapter_1.ContractAdapter {
constructor(constuctParams) {
let desc;
switch (constuctParams.checkType) {
case TOKEN_TRANSFER_TYPE.IN_3_OUT_3:
desc = require('../contract-desc/tokenTransferCheck_desc.json');
break;
case TOKEN_TRANSFER_TYPE.IN_6_OUT_6:
desc = require('../contract-desc/tokenTransferCheck_6To6_desc.json');
break;
case TOKEN_TRANSFER_TYPE.IN_10_OUT_10:
desc = require('../contract-desc/tokenTransferCheck_10To10_desc.json');
break;
case TOKEN_TRANSFER_TYPE.IN_3_OUT_100:
desc = require('../contract-desc/tokenTransferCheck_3To100_desc.json');
break;
case TOKEN_TRANSFER_TYPE.IN_20_OUT_3:
desc = require('../contract-desc/tokenTransferCheck_20To3_desc.json');
break;
default:
throw 'invalid checkType';
}
let ClassObj = (0, scryptlib_1.buildContractClass)(desc);
let contract = new ClassObj();
super(contract);
this.constuctParams = constuctParams;
this._formatedDataPart = {};
}
clone() {
let contract = new TokenTransferCheck(this.constuctParams);
contract.setFormatedDataPart(this.getFormatedDataPart());
return contract;
}
setFormatedDataPart(dataPart) {
this._formatedDataPart = Object.assign({}, this._formatedDataPart, dataPart);
super.setDataPart((0, scryptlib_1.toHex)(proto.newDataPart(this._formatedDataPart)));
}
getFormatedDataPart() {
return this._formatedDataPart;
}
unlock({ txPreimage, tokenScript, prevouts, rabinMsgArray, rabinPaddingArray, rabinSigArray, rabinPubKeyIndexArray, rabinPubKeyVerifyArray, rabinPubKeyHashArray, inputTokenAddressArray, inputTokenAmountArray, receiverSatoshiArray, changeSatoshis, changeAddress, opReturnScript, }) {
return this._contract.unlock(txPreimage, tokenScript, prevouts, rabinMsgArray, rabinPaddingArray, rabinSigArray, rabinPubKeyIndexArray, rabinPubKeyVerifyArray, rabinPubKeyHashArray, inputTokenAddressArray, inputTokenAmountArray, receiverSatoshiArray, changeSatoshis, changeAddress, opReturnScript);
}
}
exports.TokenTransferCheck = TokenTransferCheck;
class TokenTransferCheckFactory {
static getLockingScriptSize(checkType) {
return this.tokenTransferTypeInfos.find((v) => v.type == checkType).lockingScriptSize;
}
static getOptimumType(inCount, outCount) {
let typeInfo = this.tokenTransferTypeInfos.find((v) => inCount <= v.in && outCount <= v.out);
if (!typeInfo) {
return TOKEN_TRANSFER_TYPE.UNSUPPORT;
}
return typeInfo.type;
}
static createContract(tokenTransferType) {
return new TokenTransferCheck({ checkType: tokenTransferType });
}
static getDummyInstance(checkType) {
let v = this.tokenTransferTypeInfos.find((v) => v.type == checkType);
let tokenInputArray = new Array(v.in).fill(0);
let tokenOutputArray = new Array(v.out).fill({
address: dummy_1.dummyAddress,
tokenAmount: BN.Zero,
});
let contract = this.createContract(v.type);
contract.setFormatedDataPart({
nSenders: tokenInputArray.length,
receiverTokenAmountArray: tokenOutputArray.map((v) => v.tokenAmount),
receiverArray: tokenOutputArray.map((v) => v.address),
nReceivers: tokenOutputArray.length,
tokenCodeHash: (0, scryptlib_1.toHex)(dummy_1.dummyCodehash),
tokenID: (0, scryptlib_1.toHex)(dummy_1.dummyCodehash),
});
return contract;
}
static calLockingScriptSize(checkType) {
let contract = this.getDummyInstance(checkType);
return contract.lockingScript.toBuffer().length;
}
static calUnlockingScriptSize(checkType, bsvInputLen, tokenInputLen, tokenOutputLen, opreturnData) {
let opreturnScriptHex = '';
if (opreturnData) {
let script = mvc.Script.buildSafeDataOut(opreturnData);
opreturnScriptHex = script.toHex();
}
let contract = this.getDummyInstance(checkType);
let tokenContractInstance = token_1.TokenFactory.getDummyInstance();
const preimage = (0, scryptlib_1.getPreimage)(dummy_1.dummyTx, contract.lockingScript.toASM(), 1);
const sig = Buffer.from(utils_1.PLACE_HOLDER_SIG, 'hex');
const rabinMsg = dummy_1.dummyPayload;
let checkRabinMsgArray = Buffer.alloc(0);
let checkRabinSigArray = Buffer.alloc(0);
let checkRabinPaddingArray = Buffer.alloc(0);
let paddingCountBuf = Buffer.alloc(2, 0);
paddingCountBuf.writeUInt16LE(dummy_1.dummyPadding.length / 2);
const padding = Buffer.alloc(dummy_1.dummyPadding.length / 2, 0);
padding.write(dummy_1.dummyPadding, 'hex');
const rabinPaddingArray = [];
const rabinSigArray = [];
const rabinPubKeyIndexArray = [];
const rabinPubKeyArray = [];
const sigBuf = TokenUtil.toBufferLE(dummy_1.dummySigBE, TokenUtil.RABIN_SIG_LEN);
let inputTokenAddressArray = Buffer.alloc(0);
let inputTokenAmountArray = Buffer.alloc(0);
let tokenAmount = Buffer.alloc(8);
tokenAmount.writeInt32BE(100000);
for (let i = 0; i < tokenInputLen; i++) {
inputTokenAddressArray = Buffer.concat([inputTokenAddressArray, dummy_1.dummyAddress.toBuffer()]);
inputTokenAmountArray = Buffer.concat([inputTokenAmountArray, tokenAmount]);
for (let j = 0; j < token_proto_1.SIGNER_VERIFY_NUM; j++) {
if (j == 0) {
checkRabinMsgArray = Buffer.concat([checkRabinMsgArray, Buffer.from(dummy_1.dummyPayload, 'hex')]);
}
checkRabinSigArray = Buffer.concat([checkRabinSigArray, sigBuf]);
checkRabinPaddingArray = Buffer.concat([checkRabinPaddingArray, paddingCountBuf, padding]);
}
}
for (let i = 0; i < token_proto_1.SIGNER_VERIFY_NUM; i++) {
rabinPaddingArray.push(new scryptlib_1.Bytes(dummy_1.dummyPadding));
rabinSigArray.push(new scryptlib_1.Int(BN.fromString(dummy_1.dummySigBE, 16).toString(10)));
rabinPubKeyIndexArray.push(i);
rabinPubKeyArray.push(new scryptlib_1.Int(dummy_1.dummyRabinPubKey.toString(10)));
}
const tokenInputIndex = 0;
let prevouts = Buffer.alloc(0);
const indexBuf = TokenUtil.getUInt32Buf(0);
const txidBuf = TokenUtil.getTxIdBuf(dummy_1.dummyTxId);
for (let i = 0; i < tokenInputLen + bsvInputLen + 1; i++) {
prevouts = Buffer.concat([prevouts, txidBuf, indexBuf]);
}
let receiverSatoshiArray = Buffer.alloc(0);
for (let i = 0; i < tokenOutputLen; i++) {
receiverSatoshiArray = Buffer.concat([receiverSatoshiArray, Buffer.alloc(8)]);
}
let unlockedContract = contract.unlock({
txPreimage: new scryptlib_1.SigHashPreimage((0, scryptlib_1.toHex)(preimage)),
tokenScript: new scryptlib_1.Bytes(tokenContractInstance.lockingScript.toHex()),
prevouts: new scryptlib_1.Bytes((0, scryptlib_1.toHex)(prevouts)),
rabinMsgArray: new scryptlib_1.Bytes((0, scryptlib_1.toHex)(checkRabinMsgArray)),
rabinPaddingArray: new scryptlib_1.Bytes((0, scryptlib_1.toHex)(checkRabinPaddingArray)),
rabinSigArray: new scryptlib_1.Bytes((0, scryptlib_1.toHex)(checkRabinSigArray)),
rabinPubKeyIndexArray,
rabinPubKeyVerifyArray: rabinPubKeyArray,
rabinPubKeyHashArray: new scryptlib_1.Bytes((0, scryptlib_1.toHex)(dummy_1.dummyRabinPubKeyHashArray)),
inputTokenAddressArray: new scryptlib_1.Bytes((0, scryptlib_1.toHex)(inputTokenAddressArray)),
inputTokenAmountArray: new scryptlib_1.Bytes((0, scryptlib_1.toHex)(inputTokenAmountArray)),
receiverSatoshiArray: new scryptlib_1.Bytes((0, scryptlib_1.toHex)(receiverSatoshiArray)),
changeSatoshis: new scryptlib_1.Int(1000),
changeAddress: new scryptlib_1.Ripemd160((0, scryptlib_1.toHex)(dummy_1.dummyAddress.hashBuffer)),
opReturnScript: new scryptlib_1.Bytes(opreturnScriptHex),
});
return unlockedContract.toScript().toBuffer().length;
}
}
exports.TokenTransferCheckFactory = TokenTransferCheckFactory;
TokenTransferCheckFactory.tokenTransferTypeInfos = _tokenTransferTypeInfos;