UNPKG

test-triam-base-contract

Version:

Low level triam smart cotnract support library

550 lines (549 loc) 24.9 kB
// 'use strict'; // const base = require ('test-triam-base-contract'); // const Bignumber = require ('bignumber.js'); // const Storage = base.Storage; // const State = base.State (); // const TOKEN_RATE = 10000000; // const MIN_TOKEN_IN_ACCOUNT = 20; // // class DiscoveryMiningContract { // /** // * // * @param _storage // */ // constructor (_storage) { // this.storage = new Storage (_storage); // } // // /** // * // * @returns {*} // */ // initialize (_ledgerStart, _ledgerEnd, _ledgerCancellation, _fileName, _fileHash, _minFunding, _assetCode, _tokenIssuer, _profitInSCFlag, _investorsLimit, _ledgerInvestmentEnd,_owner) { // this.storage = new Storage (); // // // validate // const investorsLimit = new Bignumber(_investorsLimit); // const ledgerStart = new Bignumber(_ledgerStart); // const ledgerEnd = new Bignumber(_ledgerEnd); // const ledgerCancellation = new Bignumber(_ledgerCancellation); // const ledgerInvestmentEnd = new Bignumber(_ledgerInvestmentEnd); // //const profitRate = new Bignumber(_profitRate); // // if (!(investorsLimit.gt(0))) { // return base.Failed ( State.contractKey, "Limit of investors must be great than zero"); // } // // if (ledgerStart.gt(ledgerCancellation)) { // return base.Failed ( State.contractKey, "The ledgerStart must be less than ledgerCancellation"); // } // // if (ledgerCancellation.gt(ledgerEnd)) { // return base.Failed ( State.contractKey, "The ledgerCancellation must be less than ledgerEnd"); // } // // if (ledgerStart.gt(ledgerInvestmentEnd)) { // return base.Failed ( State.contractKey, "The ledgerStart must be less than ledgerInvestmentEnd"); // } // // if (ledgerInvestmentEnd.gt(ledgerEnd)) { // return base.Failed ( State.contractKey, "The ledgerInvestmentEnd must be less than ledgerEnd"); // } // // // initializing // this.storage.set ("investors", {}); // json with key is account address // // account address // // // initBalance // // // times of getting profit // // // investorProfit // when user want profit will be added in smart contract // // // profit Rate // // this.storage.set ("profitInSCFlag", _profitInSCFlag); // if it equal 1, profit will be added to investorProfit of every investors // // this.storage.set ("investorsLimit", _investorsLimit); // this.storage.set ("currentNumInvestors", "0"); // // // owner should be a constant which is administrator // this.storage.set ("owner", _owner); // // this.storage.set ("contractBalance", "0"); // this.storage.set ("minFunding", _minFunding); // // this.storage.set ("assetCode", _assetCode); // this.storage.set ("issuer", _tokenIssuer); // // this.storage.set ("ledgerStart", _ledgerStart); // this.storage.set ("ledgerEnd", _ledgerEnd); // this.storage.set ("ledgerCancellation", _ledgerCancellation); // this.storage.set ("ledgerInvestmentEnd", _ledgerInvestmentEnd); // // this.storage.set ("fileName", _fileName); // this.storage.set ("fileHash", _fileHash); // // return base.Success(this.storage.save (), "", State.contractKey, "OK"); // } // // /** // * // * @returns {*} // */ // register() { // // const ledgerStart = new Bignumber (this.storage.get ("ledgerStart")); // const ledgerInvestmentEnd = new Bignumber (this.storage.get ("ledgerInvestmentEnd")); // const ledgerEnd = new Bignumber (this.storage.get ("ledgerEnd")); // // const sender = State.sender; // const owner = this.storage.get('owner'); // let investors = this.storage.show()['investors']; // const currLedgerSeq = new Bignumber (State.ledSeq); // // let investorsLimit = new Bignumber (this.storage.get("investorsLimit")); // let currentNumInvestors = new Bignumber (this.storage.get("currentNumInvestors")); // // if (sender === owner) { // return base.Failed ( State.contractKey, "You are the owner"); // } else { // if (currLedgerSeq.lt(ledgerStart)) { // return base.Failed ( State.contractKey, "Investment hasn't been opened yet!"); // } // // if (currLedgerSeq.gt(ledgerEnd)) { // return base.Failed ( State.contractKey, "Investment has ended!"); // } // // if (currLedgerSeq.gt(ledgerInvestmentEnd)) { // return base.Failed ( State.contractKey, "Register has ended!"); // } // // // investorsLimit need to be great than zero when initializing // if (currentNumInvestors.eq(investorsLimit)) { // return base.Failed ( State.contractKey, "Number of investors is enough!"); // } // // // check: Has sender invested yet? // if (investors.hasOwnProperty(sender)) { // return base.Failed ( State.contractKey, sender + "has already registered!"); // } // // investors[sender]['initBalance'] = "0"; // const profitRate = new Bignumber(State.param[0]); // investors[sender]['profitRate'] = profitRate.div(100).toString(10); // investors[sender]['investorProfit'] = "0"; // investors[sender]['timesOfGetting'] = "0"; // // currentNumInvestors = currentNumInvestors.plus(1); // // this.storage.update ('investors', investors); // this.storage.update ('currentNumInvestors', currentNumInvestors.toString(10)); // } // return base.Success(this.storage.save(), " ", State.contractKey, "0k"); // // } // // /** // * // * @returns {*} // */ // fallback () { // // //start function // const ledgerEnd = new Bignumber (this.storage.get ("ledgerEnd")); // const ledgerStart = new Bignumber (this.storage.get ("ledgerStart")); // const ledgerInvestmentEnd = new Bignumber (this.storage.get ("ledgerInvestmentEnd")); // // const currLedgerSeq = new Bignumber (State.ledSeq); // // let investors = this.storage.show()['investors']; // const sender = State.sender; // // let contractBalance = new Bignumber (this.storage.get("contractBalance")); // let minFunding = new Bignumber (this.storage.get("minFunding")); // // const owner = this.storage.get('owner'); // // // check asset code that user sent // let assetCode = State.param.assetCode.replace(/\0/g, ''); // if (assetCode !== this.storage.get ('assetCode')) { // return base.Failed ( State.contractKey, "Invalid asset code. " + "Expected: " + this.storage.get ('assetCode') + ". Got: " + assetCode + "."); // } // // if (sender !== owner) { // // if (currLedgerSeq.lt(ledgerStart)) { // return base.Failed ( State.contractKey, "Investment hasn't been opened yet!"); // } // // if (currLedgerSeq.gt(ledgerEnd)) { // return base.Failed ( State.contractKey, "Investment has ended!"); // } // // if (currLedgerSeq.gt(ledgerInvestmentEnd)) { // return base.Failed ( State.contractKey, "Register has ended!"); // } // // const receivedAmount = new Bignumber (State.param.amount).div(TOKEN_RATE); // if (minFunding.gt(receivedAmount)) { // return base.Failed ( State.contractKey, "Amount must be great than or equal " + minFunding); // } // // // check: Has sender invested yet? // if (!investors.hasOwnProperty(sender)) { // return base.Failed ( State.contractKey, sender + "has not invested yet!"); // } // // let initBalance = new Bignumber (investors[sender]['initBalance']); // if (initBalance.gt(0)) { // return base.Failed ( State.contractKey, sender + "has has invested"); // } // // investors[sender]['initBalance'] = receivedAmount.toString(10); // // contractBalance = contractBalance.plus(receivedAmount); // // this.storage.update ('investors', investors); // this.storage.update ('contractBalance', contractBalance.toString(10)); // // } else { // // const receivedAmount = new Bignumber (State.param.amount).div(TOKEN_RATE); // contractBalance = contractBalance.plus(receivedAmount); // this.storage.update ('contractBalance', contractBalance.toString(10)); // // } // return base.Success(this.storage.save(), " ", State.contractKey, "0k"); // } // // /** // * // * @returns {*} // */ // withdraw () { // // const owner = this.storage.get ('owner'); // const ledgerInvestmentEnd = new Bignumber (this.storage.get ("ledgerInvestmentEnd")); // let contractBalance = new Bignumber (this.storage.get("contractBalance")); // // const currLedgerSeq = new Bignumber (State.ledSeq); // // //only owner can call this function // if (owner !== State.sender) { // return base.Failed (State.contractKey, "Only owner call it!"); // } // // if (currLedgerSeq.lt(ledgerInvestmentEnd)) { // return base.Failed ( State.contractKey, "Register has not ended yet!"); // } // // if (contractBalance.lt(MIN_TOKEN_IN_ACCOUNT)) { // return base.Failed ( State.contractKey, "Underfunded! Balance of contract is less than min balance"); // } // // //send op for core // let account = new base.Account (State.sender, "0"); // // //create asset // const asset = new base.Asset (this.storage.get ('assetCode'), this.storage.get ('issuer')); // let transaction = new base.TransactionBuilder (account) // .addOperation (base.Operation.callContract ({ // contractId: State.contractKey, // data: new base.ContractInput ("tmp", []) // })) // .addContrOperationForCallContractOp (base.ContrOperation.transfer ({ // destination: this.storage.get ('owner'), // asset: asset, // amount: contractBalance.minus(MIN_TOKEN_IN_ACCOUNT) // }), 1) // .addContrOperationForCallContractOp (base.ContrOperation.invoke ({ // newState: this.storage.save () // in XLM // }), 1) // .build (); // // contractBalance = contractBalance.minus(contractBalance.minus(MIN_TOKEN_IN_ACCOUNT)); // this.storage.update ('contractBalance', contractBalance.toString(10)); // // return base.Success (this.storage.save (), transaction.toEnvelope ().toXDR ().toString ('base64'), State.contractKey, 'OK'); // } // // sharedProfit () { // // let contractBalance = new Bignumber (this.storage.get('contractBalance')); // // let profitTotalMustPay = new Bignumber(0); // // const profitInSCFlag = new Bignumber (this.storage.get('profitInSCFlag')); // // let investors = this.storage.show()['investors']; // // //only owner can call this function // const owner = this.storage.get('owner'); // if (owner !== State.sender) { // return base.Failed (State.contractKey, "Only owner call it!"); // } // // for (const investor in investors) { // if (investors.hasOwnProperty(investor)) { // const initBalance = new Bignumber(investors[investor]['initBalance']); // const profitRate = new Bignumber(investors[investor]['profitRate']); // profitTotalMustPay = profitTotalMustPay.plus((initBalance.times(profitRate)).toFixed(7)); // } // } // // if (contractBalance.lt(profitTotalMustPay.plus(MIN_TOKEN_IN_ACCOUNT))) { // return base.Failed (State.contractKey, "Underfunded! Waiting for owner send more token to contract account"); // } // // if (profitInSCFlag.eq(1)) { // for (const investor in investors) { // if (investors.hasOwnProperty(investor)) { // // investors[sender]['initBalance'] = State.param.amount; // // investors[sender]['investorProfit'] = 0; // // investors[sender]['timesOfGetting'] = 0; // let investorProfit = new Bignumber (this.storage.get(investors[investor]['investorProfit'])); // let timesOfGetting = new Bignumber (this.storage.get(investors[investor]['timesOfGetting'])); // // const initBalance = new Bignumber(investors[investor]['initBalance']); // const profitRate = new Bignumber(investors[investor]['profitRate']); // investorProfit = investorProfit.plus((initBalance.times(profitRate)).toFixed(7)); // investors[investor]['investorProfit'] = investorProfit.toString(10); // // timesOfGetting = timesOfGetting.plus(1); // investors[investor]['timesOfGetting'] = timesOfGetting.toString(10); // // this.storage.update ('investors', investors); // } // } // contractBalance = contractBalance.minus(profitTotalMustPay); // this.storage.update ('contractBalance', contractBalance.toString(10)); // return base.Success(this.storage.save(), " ", State.contractKey, "0k"); // } else { // // //send op for core // let account = new base.Account (State.sender, "0"); // const asset = new base.Asset (this.storage.get ('assetCode'), this.storage.get ('issuer')); // let transaction = new base.TransactionBuilder (account) // .addOperation (base.Operation.callContract ({ // contractId: State.contractKey, // data: new base.ContractInput ("tmp", []) // })); // // for (const investor in investors) { // const initBalance = new Bignumber(investors[investor]['initBalance']); // const profitRate = new Bignumber(investors[investor]['profitRate']); // transaction = transaction.addContrOperationForCallContractOp (base.ContrOperation.transfer ({ // destination: investor, // asset: asset, // amount: ((initBalance.times(profitRate)).toFixed(7)) // }), 1); // } // // transaction = transaction.addContrOperationForCallContractOp (base.ContrOperation.invoke ({ // newState: this.storage.save () // in XLM // }), 1) // .build (); // // contractBalance = contractBalance.minus(profitTotalMustPay); // this.storage.update ('contractBalance', contractBalance.toString(10)); // // //return output // return base.Success (this.storage.save (), transaction.toEnvelope ().toXDR ().toString ('base64'), State.contractKey, 'OK'); // } // } // // cancelContract() { // // let investors = this.storage.show()['investors']; // const profitInSCFlag = new Bignumber (this.storage.get('profitInSCFlag')); // let contractBalance = new Bignumber (this.storage.get('contractBalance')); // // const ledgerCancellation = new Bignumber (this.storage.get ("ledgerCancellation")); // const currLedgerSeq = new Bignumber (State.ledSeq); // // const sender = State.sender; // // if (!investors.hasOwnProperty(sender)) { // return base.Failed (State.contractKey, sender + "has never invested"); // } // // // check cancel time // if (currLedgerSeq.gt(ledgerCancellation)) { // return base.Failed (State.contractKey, "Cancel time has ended"); // } // // if (profitInSCFlag.eq(1)) { // const initBalance = new Bignumber(investors[sender]['initBalance']); // const investorProfit = new Bignumber(investors[sender]['investorProfit']); // if (contractBalance.lt(initBalance.plus(investorProfit).plus(MIN_TOKEN_IN_ACCOUNT))) { // return base.Failed (State.contractKey, "Underfunded! Waiting for owner send token to smart contract"); // } // // create transaction // const asset = new base.Asset (this.storage.get ('assetCode'), this.storage.get ('issuer')); // //send op for core // let account = new base.Account (State.sender, "0"); // let transaction = new base.TransactionBuilder (account) // .addOperation (base.Operation.callContract ({ // contractId: State.contractKey, // data: new base.ContractInput ("tmp", []) // })) // .addContrOperationForCallContractOp (base.ContrOperation.transfer ({ // destination: sender, // asset: asset, // amount: initBalance.plus(investorProfit) // }), 1) // .addContrOperationForCallContractOp (base.ContrOperation.invoke ({ // newState: this.storage.save () // in XLM // }), 1) // .build (); // // // remove sender // delete investors[sender]; // this.storage.update ('investors', investors); // // // update balance // contractBalance = contractBalance.minus(initBalance).minus(investorProfit); // this.storage.update ('contractBalance', contractBalance.toString(10)); // // return base.Success (this.storage.save (), transaction.toEnvelope ().toXDR ().toString ('base64'), State.contractKey, 'OK'); // } else { // // const initBalance = new Bignumber(investors[sender]['initBalance']); // // if (contractBalance.lt(initBalance.plus(MIN_TOKEN_IN_ACCOUNT))) { // return base.Failed (State.contractKey, "Underfunded! Waiting for owner send token to smart contract"); // } // // create transaction // const asset = new base.Asset (this.storage.get ('assetCode'), this.storage.get ('issuer')); // let account = new base.Account (State.sender, "0"); // let transaction = new base.TransactionBuilder (account) // .addOperation (base.Operation.callContract ({ // contractId: State.contractKey, // data: new base.ContractInput ("tmp", []) // })) // .addContrOperationForCallContractOp (base.ContrOperation.transfer ({ // destination: sender, // asset: asset, // amount: initBalance // }), 1) // .addContrOperationForCallContractOp (base.ContrOperation.invoke ({ // newState: this.storage.save () // in XLM // }), 1) // .build (); // // contractBalance = contractBalance.minus(initBalance); // this.storage.update ('contractBalance', contractBalance.toString(10)); // // // remove sender // delete investors[sender]; // this.storage.update ('investors', investors); // // // return base.Success (this.storage.save (), transaction.toEnvelope ().toXDR ().toString ('base64'), State.contractKey, 'OK'); // } // // } // // refund () { // //get contract status // // let status = new Bignumber (this.storage.get ("status")); // //let actualProfit = this.storage.show ()['actualProfits']; // let contractBalance = new Bignumber (this.storage.get('contractBalance')); // // let amountTotal = new Bignumber(0); // // let investors = this.storage.show()['investors']; // // const owner = this.storage.get ('owner'); // const sender = State.sender; // // //only owner can call this function // if (owner !== sender) { // return base.Failed (State.contractKey, "Only owner call it!"); // } // // for (const investor in investors) { // if (investors.hasOwnProperty(investor)) { // const initBalance = new Bignumber(investors[investor]['initBalance']); // const investorProfit = new Bignumber(investors[investor]['investorProfit']); // // amountTotal = amountTotal.plus(initBalance).plus(investorProfit); // } // } // // if (contractBalance.lt(amountTotal.plus(MIN_TOKEN_IN_ACCOUNT))) { // return base.Failed (State.contractKey, "Underfunded! Waiting for owner send more token to contract account"); // } // // let account = new base.Account (State.sender, "0"); // const asset = new base.Asset (this.storage.get ('assetCode'), this.storage.get ('issuer')); // let transaction = new base.TransactionBuilder (account) // .addOperation (base.Operation.callContract ({ // contractId: State.contractKey, // data: new base.ContractInput ("tmp", []) // })); // // for (const investor in investors) { // const initBalance = new Bignumber(investors[investor]['initBalance']); // const investorProfit = new Bignumber(investors[investor]['investorProfit']); // // transaction = transaction.addContrOperationForCallContractOp (base.ContrOperation.transfer ({ // destination: investor, // asset: asset, // amount: initBalance.plus(investorProfit) // }), 1); // } // // transaction = transaction.addContrOperationForCallContractOp (base.ContrOperation.invoke ({ // newState: this.storage.save () // in XLM // }), 1) // .build (); // // contractBalance = contractBalance.minus(amountTotal); // // update balance // this.storage.update ('contractBalance', contractBalance.toString(10)); // // //return output // return base.Success (this.storage.save (), transaction.toEnvelope ().toXDR ().toString ('base64'), State.contractKey, 'OK'); // } // // main (_funcName, _params) { // switch (_funcName) { // case "constructor": { // let ledgerStart = _params[0]; // let ledgerEnd = _params[1]; // let ledgerCancellation = _params[2]; // let fileName = _params[3]; // let fileHash = _params[4]; // let minFunding = _params[5]; // let assetCode = _params[6]; // let tokenIssuer = _params[7]; // let profitInSCFlag = _params[8]; // let investorsLimit = _params[9]; // let ledgerInvestmentEnd = _params[10]; // // owner should be a constant which is administrator // let owner = State.sender; // return this.initialize (ledgerStart, ledgerEnd, ledgerCancellation, fileName, fileHash, minFunding, assetCode, tokenIssuer, profitInSCFlag, investorsLimit, ledgerInvestmentEnd, owner); // } // case "register": { // return this.register(); // } // case "fallback" : { // return this.fallback (); // } // case "withdraw": { // return this.withdraw (); // } // case "profit": { // return this.sharedProfit (); // } // case "refund": { // return this.refund (); // } // case "cancel": { // return this.cancelContract; // } // default: // return base.Failed (State.contractKey, "Cant not map any function name"); // } // } // } // base.exec (DiscoveryMiningContract);