public static ExchangeList GetListExchangePaginated(int offset, int limit) { if (offset < 0 || limit < 0) { throw new ArgumentException("offset and limit value must be >= 0"); } long latest_num = Manager.Instance.DBManager.DynamicProperties.GetLatestExchangeNum(); if (latest_num <= offset) { throw new ArgumentException("latest num is " + latest_num + ". offset num must be smaller than latest."); } limit = limit > Parameter.DatabaseParameters.EXCHANGE_COUNT_LIMIT_MAX ? Parameter.DatabaseParameters.EXCHANGE_COUNT_LIMIT_MAX : limit; long end = offset + limit; end = end > latest_num ? latest_num : end; ExchangeList result = new ExchangeList(); for (int i = offset; i < end; i++) { ExchangeCapsule exchange = Manager.Instance.DBManager.ExchangeFinal.Get(ExchangeCapsule.CalculateDatabaseKey(i)); if (exchange != null) { result.Exchanges.Add(exchange.Instance); } } return(result); }
public override bool Execute(TransactionResultCapsule result) { long fee = CalcFee(); try { ExchangeTransactionContract exchage_tx_contract = this.contract.Unpack <ExchangeTransactionContract>(); AccountCapsule account = this.db_manager.Account.Get(exchage_tx_contract.OwnerAddress.ToByteArray()); ExchangeCapsule exchange = this.db_manager.ExchangeFinal.Get(BitConverter.GetBytes(exchage_tx_contract.ExchangeId)); byte[] first_token_id = exchange.FirstTokenId.ToByteArray(); byte[] second_token_id = exchange.SecondTokenId.ToByteArray(); byte[] token_id = exchage_tx_contract.TokenId.ToByteArray(); long token_quantity = exchage_tx_contract.Quant; byte[] other_token_id = null; long other_token_quantity = exchange.Transaction(token_id, token_quantity); other_token_id = token_id.SequenceEqual(first_token_id) ? second_token_id : first_token_id; long new_balance = account.Balance - CalcFee(); account.Balance = new_balance; if (token_id.SequenceEqual(COMPARE_CHARICTOR)) { account.Balance = new_balance - token_quantity; } else { account.ReduceAssetAmountV2(token_id, token_quantity, this.db_manager); } if (other_token_id.SequenceEqual(COMPARE_CHARICTOR)) { account.Balance = new_balance + other_token_quantity; } else { account.AddAssetAmountV2(other_token_id, other_token_quantity, this.db_manager); } this.db_manager.Account.Put(account.CreateDatabaseKey(), account); this.db_manager.PutExchangeCapsule(exchange); result.ExchangeReceivedAmount = other_token_quantity; result.SetStatus(fee, code.Sucess); } catch (ItemNotFoundException e) { Logger.Debug(e.Message); result.SetStatus(fee, code.Failed); throw new ContractExeException(e.Message); } catch (InvalidProtocolBufferException e) { Logger.Debug(e.Message); result.SetStatus(fee, code.Failed); throw new ContractExeException(e.Message); } return(true); }
public override bool Execute(TransactionResultCapsule result) { long fee = CalcFee(); try { ExchangeCreateContract exchange_create_contract = this.contract.Unpack <ExchangeCreateContract>(); AccountCapsule account = this.db_manager.Account.Get(exchange_create_contract.OwnerAddress.ToByteArray()); byte[] first_token_id = exchange_create_contract.FirstTokenId.ToByteArray(); byte[] secodn_token_id = exchange_create_contract.SecondTokenId.ToByteArray(); long first_token_balance = exchange_create_contract.FirstTokenBalance; long second_token_balance = exchange_create_contract.SecondTokenBalance; long new_balance = account.Balance - fee; account.Balance = new_balance; if (first_token_id.SequenceEqual(COMPARE_CHARICTOR)) { account.Balance = new_balance - first_token_balance; } else { account.ReduceAssetAmountV2(first_token_id, first_token_balance, this.db_manager); } if (secodn_token_id.SequenceEqual(COMPARE_CHARICTOR)) { account.Balance = new_balance - second_token_balance; } else { account.ReduceAssetAmountV2(secodn_token_id, second_token_balance, this.db_manager); } long id = this.db_manager.DynamicProperties.GetLatestExchangeNum() + 1; long now = this.db_manager.GetHeadBlockTimestamp(); if (this.db_manager.DynamicProperties.GetAllowSameTokenName() == 0) { ExchangeCapsule exchange = new ExchangeCapsule( exchange_create_contract.OwnerAddress, id, now, first_token_id, secodn_token_id); exchange.SetBalance(first_token_balance, second_token_balance); this.db_manager.Exchange.Put(exchange.CreateDatabaseKey(), exchange); if (!first_token_id.SequenceEqual(COMPARE_CHARICTOR)) { string first_id = this.db_manager.AssetIssue.Get(first_token_id).Id; first_token_id = Encoding.UTF8.GetBytes(first_id); } if (!secodn_token_id.SequenceEqual(COMPARE_CHARICTOR)) { string second_id = this.db_manager.AssetIssue.Get(secodn_token_id).Id; secodn_token_id = Encoding.UTF8.GetBytes(second_id); } } ExchangeCapsule exchange_v2 = new ExchangeCapsule( exchange_create_contract.OwnerAddress, id, now, first_token_id, secodn_token_id); exchange_v2.SetBalance(first_token_balance, second_token_balance); this.db_manager.ExchangeV2.Put(exchange_v2.CreateDatabaseKey(), exchange_v2); this.db_manager.Account.Put(account.CreateDatabaseKey(), account); this.db_manager.DynamicProperties.PutLatestExchangeNum(id); this.db_manager.AdjustBalance(this.db_manager.Account.GetBlackHole().CreateDatabaseKey(), fee); result.ExchangeId = id; result.SetStatus(fee, code.Sucess); } catch (BalanceInsufficientException e) { Logger.Debug(e.Message); result.SetStatus(fee, code.Failed); throw new ContractExeException(e.Message); } catch (InvalidProtocolBufferException e) { Logger.Debug(e.Message); result.SetStatus(fee, code.Failed); throw new ContractExeException(e.Message); } return(true); }
public override bool Validate() { if (this.contract == null) { throw new ContractValidateException("No contract!"); } if (this.db_manager == null) { throw new ContractValidateException("No this.db_manager!"); } if (!this.contract.Is(ExchangeInjectContract.Descriptor)) { ExchangeInjectContract contract; try { contract = this.contract.Unpack <ExchangeInjectContract>(); } catch (InvalidProtocolBufferException e) { throw new ContractValidateException(e.Message); } byte[] owner_address = contract.OwnerAddress.ToByteArray(); if (!Wallet.IsValidAddress(owner_address)) { throw new ContractValidateException("Invalid address"); } if (!this.db_manager.Account.Contains(owner_address)) { throw new ContractValidateException("account[" + owner_address.ToHexString() + "] not exists"); } AccountCapsule account = this.db_manager.Account.Get(owner_address); if (account.Balance < CalcFee()) { throw new ContractValidateException("No enough balance for exchange inject fee!"); } ExchangeCapsule exchange = null; try { exchange = this.db_manager.ExchangeFinal.Get(BitConverter.GetBytes(contract.ExchangeId)); } catch (ItemNotFoundException e) { throw new ContractValidateException("Exchange[" + contract.ExchangeId + "] not exists", e); } if (!account.Address.Equals(exchange.CreatorAddress)) { throw new ContractValidateException("account[" + owner_address.ToHexString() + "] is not creator"); } byte[] first_token_id = exchange.FirstTokenId.ToByteArray(); byte[] second_token_id = exchange.SecondTokenId.ToByteArray(); long first_token_balance = exchange.FirstTokenBalance; long second_token_balance = exchange.SecondTokenBalance; byte[] token_id = contract.TokenId.ToByteArray(); long token_quantity = contract.Quant; byte[] other_token_id = null; long other_token_quantity = 0; if (this.db_manager.DynamicProperties.GetAllowSameTokenName() == 1) { if (!token_id.SequenceEqual(COMPARE_CHARICTOR) && !TransactionUtil.IsNumber(token_id)) { throw new ContractValidateException("token id is not a valid number"); } } if (!token_id.SequenceEqual(first_token_id) && !token_id.SequenceEqual(second_token_id)) { throw new ContractValidateException("token id is not in exchange"); } if (first_token_balance == 0 || second_token_balance == 0) { throw new ContractValidateException("Token balance in exchange is equal with 0," + "the exchange has been closed"); } if (token_quantity <= 0) { throw new ContractValidateException("injected token quant must greater than zero"); } BigInteger first_balance = new BigInteger(first_token_balance); BigInteger second_balance = new BigInteger(second_token_balance); BigInteger quantity = new BigInteger(token_quantity); long new_token_balance = 0; long new_other_token_balance = 0; if (token_id.SequenceEqual(first_token_id)) { other_token_id = second_token_id; other_token_quantity = (long)BigInteger.Multiply(second_balance, token_quantity); other_token_quantity = (long)BigInteger.Divide(other_token_quantity, first_balance); new_token_balance = first_token_balance + token_quantity; new_other_token_balance = second_token_balance + other_token_quantity; } else { other_token_id = first_token_id; other_token_quantity = (long)BigInteger.Multiply(first_balance, token_quantity); other_token_quantity = (long)BigInteger.Divide(other_token_quantity, second_balance); new_token_balance = second_token_balance + token_quantity; new_other_token_balance = first_token_balance + other_token_quantity; } if (other_token_quantity <= 0) { throw new ContractValidateException("the calculated token quant must be greater than 0"); } long balance_limit = this.db_manager.DynamicProperties.GetExchangeBalanceLimit(); if (new_token_balance > balance_limit || new_other_token_balance > balance_limit) { throw new ContractValidateException("token balance must less than " + balance_limit); } if (token_id.SequenceEqual(COMPARE_CHARICTOR)) { if (account.Balance < (token_quantity + CalcFee())) { throw new ContractValidateException("balance is not enough"); } } else { if (!account.AssetBalanceEnoughV2(token_id, token_quantity, this.db_manager)) { throw new ContractValidateException("token balance is not enough"); } } if (other_token_id.SequenceEqual(COMPARE_CHARICTOR)) { if (account.Balance < (other_token_quantity + CalcFee())) { throw new ContractValidateException("balance is not enough"); } } else { if (!account.AssetBalanceEnoughV2(other_token_id, other_token_quantity, this.db_manager)) { throw new ContractValidateException("other token balance is not enough"); } } } else { throw new ContractValidateException( "contract type error,expected type [ExchangeInjectContract],real type[" + this.contract.GetType().Name + "]"); } return(true); }
public override bool Execute(TransactionResultCapsule result) { long fee = CalcFee(); try { ExchangeWithdrawContract ew_contract = this.contract.Unpack <ExchangeWithdrawContract>(); AccountCapsule account = this.db_manager.Account.Get(ew_contract.OwnerAddress.ToByteArray()); ExchangeCapsule exchange = this.db_manager.ExchangeFinal.Get(BitConverter.GetBytes(ew_contract.ExchangeId)); byte[] first_token_id = exchange.FirstTokenId.ToByteArray(); byte[] second_token_id = exchange.SecondTokenId.ToByteArray(); long first_token_balance = exchange.FirstTokenBalance; long second_token_balance = exchange.SecondTokenBalance; byte[] token_id = ew_contract.TokenId.ToByteArray(); long token_quantity = ew_contract.Quant; byte[] other_token_id = null; long other_token_quantity = 0; BigInteger first_balance = new BigInteger(first_token_balance); BigInteger second_balance = new BigInteger(second_token_balance); BigInteger quantity = new BigInteger(token_quantity); if (token_id.SequenceEqual(first_token_id)) { other_token_id = second_token_id; other_token_quantity = (long)BigInteger.Multiply(second_balance, quantity); other_token_quantity = (long)BigInteger.Divide(other_token_quantity, first_balance); exchange.SetBalance(first_token_balance - token_quantity, second_token_balance - other_token_quantity); } else { other_token_id = first_token_id; other_token_quantity = (long)BigInteger.Multiply(first_balance, quantity); other_token_quantity = (long)BigInteger.Divide(other_token_quantity, second_balance); exchange.SetBalance(first_token_balance - other_token_quantity, second_token_balance - token_quantity); } long new_balance = account.Balance - CalcFee(); if (token_id.SequenceEqual(COMPARE_CHARICTOR)) { account.Balance = new_balance + token_quantity; } else { account.AddAssetAmountV2(token_id, token_quantity, this.db_manager); } if (other_token_id.SequenceEqual(COMPARE_CHARICTOR)) { account.Balance = new_balance + other_token_quantity; } else { account.AddAssetAmountV2(other_token_id, other_token_quantity, this.db_manager); } this.db_manager.Account.Put(account.CreateDatabaseKey(), account); this.db_manager.PutExchangeCapsule(exchange); result.ExchangeWithdrawAnotherAmount = other_token_quantity; result.SetStatus(fee, code.Sucess); } catch (ItemNotFoundException e) { Logger.Debug(e.Message); result.SetStatus(fee, code.Failed); throw new ContractExeException(e.Message); } catch (InvalidProtocolBufferException e) { Logger.Debug(e.Message); result.SetStatus(fee, code.Failed); throw new ContractExeException(e.Message); } return(true); }
public override bool Validate() { if (this.contract == null) { throw new ContractValidateException("No contract!"); } if (this.db_manager == null) { throw new ContractValidateException("No this.db_manager!"); } if (this.contract.Is(ExchangeWithdrawContract.Descriptor)) { ExchangeWithdrawContract contract = null; try { contract = this.contract.Unpack <ExchangeWithdrawContract>(); } catch (InvalidProtocolBufferException e) { throw new ContractValidateException(e.Message); } byte[] owner_address = contract.OwnerAddress.ToByteArray(); if (!Wallet.IsValidAddress(owner_address)) { throw new ContractValidateException("Invalid address"); } if (!this.db_manager.Account.Contains(owner_address)) { throw new ContractValidateException("account[" + owner_address.ToHexString() + "] not exists"); } AccountCapsule account = this.db_manager.Account.Get(owner_address); if (account.Balance < CalcFee()) { throw new ContractValidateException("No enough balance for exchange withdraw fee!"); } ExchangeCapsule exchange = null; try { exchange = this.db_manager.ExchangeFinal.Get(BitConverter.GetBytes(contract.ExchangeId)); } catch (ItemNotFoundException e) { throw new ContractValidateException("Exchange[" + contract.ExchangeId + "] not exists", e); } if (!account.Address.Equals(exchange.CreatorAddress)) { throw new ContractValidateException("account[" + owner_address.ToHexString() + "] is not creator"); } byte[] first_token_id = exchange.FirstTokenId.ToByteArray(); byte[] second_token_id = exchange.SecondTokenId.ToByteArray(); long first_token_balance = exchange.FirstTokenBalance; long second_token_balance = exchange.SecondTokenBalance; byte[] token_id = contract.TokenId.ToByteArray(); long token_quantity = contract.Quant; long other_token_quantity = 0; if (this.db_manager.DynamicProperties.GetAllowSameTokenName() == 1) { if (!token_id.SequenceEqual(COMPARE_CHARICTOR) && !TransactionUtil.IsNumber(token_id)) { throw new ContractValidateException("token id is not a valid number"); } } if (!token_id.SequenceEqual(first_token_id) && !token_id.SequenceEqual(second_token_id)) { throw new ContractValidateException("token is not in exchange"); } if (token_quantity <= 0) { throw new ContractValidateException("withdraw token quant must greater than zero"); } if (first_token_balance == 0 || second_token_balance == 0) { throw new ContractValidateException("Token balance in exchange is equal with 0," + "the exchange has been closed"); } BigDecimal first_balance = new BigDecimal(first_token_balance); BigDecimal second_balance = new BigDecimal(second_token_balance); BigDecimal bigTokenQuant = new BigDecimal(token_quantity); if (token_id.SequenceEqual(first_token_id)) { other_token_quantity = second_balance.Multiply(bigTokenQuant) .DivideToIntegralValue(first_balance).ToInt64(); if (first_token_balance < token_quantity || second_token_balance < other_token_quantity) { throw new ContractValidateException("exchange balance is not enough"); } if (other_token_quantity <= 0) { throw new ContractValidateException("withdraw another token quant must greater than zero"); } double remainder = second_balance.Multiply(bigTokenQuant) .Divide(first_balance, 4, RoundingMode.HalfUp).ToDouble(); remainder -= other_token_quantity; if (remainder / other_token_quantity > 0.0001) { throw new ContractValidateException("Not precise enough"); } } else { other_token_quantity = first_balance.Multiply(bigTokenQuant) .DivideToIntegralValue(second_balance).ToInt64(); if (second_token_balance < token_quantity || first_token_balance < other_token_quantity) { throw new ContractValidateException("exchange balance is not enough"); } if (other_token_quantity <= 0) { throw new ContractValidateException("withdraw another token quant must greater than zero"); } double remainder = first_balance.Multiply(bigTokenQuant) .Divide(second_balance, 4, RoundingMode.HalfUp).ToDouble(); remainder -= other_token_quantity; if (remainder / other_token_quantity > 0.0001) { throw new ContractValidateException("Not precise enough"); } } } else { throw new ContractValidateException( "contract type error,expected type [ExchangeWithdrawContract],real type[" + this.contract.GetType().Name + "]"); } return(true); }