示例#1
0
        public static RpcApiResult CreateTransferAssetContract(byte[] to_address,
                                                               byte[] from_address,
                                                               byte[] asset_name,
                                                               long amount,
                                                               out TransferAssetContract contract)
        {
            contract              = new TransferAssetContract();
            contract.ToAddress    = ByteString.CopyFrom(to_address);
            contract.AssetName    = ByteString.CopyFrom(asset_name);
            contract.OwnerAddress = ByteString.CopyFrom(from_address);
            contract.Amount       = amount;

            return(RpcApiResult.Success);
        }
示例#2
0
        public async Task <TransactionExtention> CreateTransactionAsync(string sender, string receiver, string data)
        {
            var contract = new TransferAssetContract
            {
                Amount       = 1,
                AssetName    = ByteString.CopyFromUtf8(AppConstants.TokenID),
                OwnerAddress = ByteString.CopyFrom(WalletAddress.Decode58Check(sender)),
                ToAddress    = ByteString.CopyFrom(WalletAddress.Decode58Check(receiver))
            };

            var transaction = await Client.TransferAssetAsync(contract);

            if (transaction.Result.Result)
            {
                transaction.Transaction.RawData.Data = ByteString.CopyFromUtf8(data);
            }

            return(transaction);
        }
示例#3
0
 public TransactionCapsule(TransferAssetContract contract)
 {
     CreateTransaction(contract, Transaction.Types.Contract.Types.ContractType.TransferAssetContract);
 }
示例#4
0
 public async Task <TransactionExtention> TransferAssetAsync(TransferAssetContract contract)
 {
     return(await _grpcClient.TransferAsset2Async(contract));
 }
示例#5
0
        public override bool Execute(TransactionResultCapsule result)
        {
            long fee = CalcFee();

            try
            {
                TransferAssetContract transfer_asset_contract = this.contract.Unpack <TransferAssetContract>();
                byte[]         owner_address = transfer_asset_contract.OwnerAddress.ToByteArray();
                byte[]         to_address    = transfer_asset_contract.ToAddress.ToByteArray();
                AccountCapsule to_account    = this.db_manager.Account.Get(to_address);

                if (to_account == null)
                {
                    bool default_permission = this.db_manager.DynamicProperties.GetAllowMultiSign() == 1;

                    to_account = new AccountCapsule(ByteString.CopyFrom(to_address),
                                                    AccountType.Normal,
                                                    this.db_manager.GetHeadBlockTimestamp(),
                                                    default_permission,
                                                    this.db_manager);

                    this.db_manager.Account.Put(to_address, to_account);

                    fee = fee + this.db_manager.DynamicProperties.GetCreateNewAccountFeeInSystemContract();
                }

                ByteString asset_name = transfer_asset_contract.AssetName;
                long       amount     = transfer_asset_contract.Amount;

                this.db_manager.AdjustBalance(owner_address, -fee);
                this.db_manager.AdjustBalance(this.db_manager.Account.GetBlackHole().CreateDatabaseKey(), fee);

                AccountCapsule owner_account = this.db_manager.Account.Get(owner_address);
                if (!owner_account.ReduceAssetAmountV2(asset_name.ToByteArray(), amount, this.db_manager))
                {
                    throw new ContractExeException("reduceAssetAmount failed !");
                }

                this.db_manager.Account.Put(owner_address, owner_account);

                to_account.AddAssetAmountV2(asset_name.ToByteArray(), amount, this.db_manager);
                this.db_manager.Account.Put(to_address, to_account);

                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)
            {
                result.SetStatus(fee, code.Failed);
                throw new ContractExeException(e.Message);
            }
            catch (ArithmeticException e)
            {
                result.SetStatus(fee, code.Failed);
                throw new ContractExeException(e.Message);
            }

            return(true);
        }
示例#6
0
        public override bool Validate()
        {
            if (this.contract == null)
            {
                throw new ContractValidateException("No contract!");
            }

            if (this.db_manager == null)
            {
                throw new ContractValidateException("No dbManager!");
            }

            if (this.contract.Is(TransferAssetContract.Descriptor))
            {
                TransferAssetContract transfer_asset_contract = null;
                try
                {
                    transfer_asset_contract = this.contract.Unpack <TransferAssetContract>();
                }
                catch (InvalidProtocolBufferException e)
                {
                    Logger.Debug(e.Message);
                    throw new ContractValidateException(e.Message);
                }

                long   fee           = CalcFee();
                byte[] owner_address = transfer_asset_contract.OwnerAddress.ToByteArray();
                byte[] to_address    = transfer_asset_contract.ToAddress.ToByteArray();
                byte[] asset_name    = transfer_asset_contract.AssetName.ToByteArray();
                long   amount        = transfer_asset_contract.Amount;

                if (!Wallet.IsValidAddress(owner_address))
                {
                    throw new ContractValidateException("Invalid ownerAddress");
                }

                if (!Wallet.IsValidAddress(to_address))
                {
                    throw new ContractValidateException("Invalid toAddress");
                }

                if (amount <= 0)
                {
                    throw new ContractValidateException("Amount must greater than 0.");
                }

                if (owner_address.SequenceEqual(to_address))
                {
                    throw new ContractValidateException("Cannot transfer asset to yourself.");
                }

                AccountCapsule owner_account = this.db_manager.Account.Get(owner_address);
                if (owner_account == null)
                {
                    throw new ContractValidateException("No owner account!");
                }

                if (!this.db_manager.GetAssetIssueStoreFinal().Contains(asset_name))
                {
                    throw new ContractValidateException("No asset !");
                }

                Dictionary <string, long> asset = this.db_manager.DynamicProperties.GetAllowSameTokenName() == 0 ? owner_account.Asset : owner_account.AssetV2;
                if (asset == null || asset.Count == 0)
                {
                    throw new ContractValidateException("Owner no asset!");
                }

                asset.TryGetValue(Encoding.UTF8.GetString(asset_name), out long asset_balance);
                if (asset_balance <= 0)
                {
                    throw new ContractValidateException("assetBalance must greater than 0.");
                }

                if (amount > asset_balance)
                {
                    throw new ContractValidateException("assetBalance is not sufficient.");
                }

                AccountCapsule to_account = this.db_manager.Account.Get(to_address);
                if (to_account != null)
                {
                    bool success = false;
                    if (this.db_manager.DynamicProperties.GetAllowSameTokenName() == 0)
                    {
                        success = to_account.Asset.TryGetValue(Encoding.UTF8.GetString(asset_name), out asset_balance);
                    }
                    else
                    {
                        success = to_account.AssetV2.TryGetValue(Encoding.UTF8.GetString(asset_name), out asset_balance);
                    }

                    if (success)
                    {
                        try
                        {
                            asset_balance = asset_balance + amount;
                        }
                        catch (System.Exception e)
                        {
                            Logger.Debug(e.Message);
                            throw new ContractValidateException(e.Message);
                        }
                    }
                }
                else
                {
                    fee = fee + this.db_manager.DynamicProperties.GetCreateNewAccountFeeInSystemContract();
                    if (owner_account.Balance < fee)
                    {
                        throw new ContractValidateException(
                                  "Validate TransferAssetActuator error, insufficient fee.");
                    }
                }
            }
            else
            {
                throw new ContractValidateException(
                          "contract type error,expected type [TransferAssetContract],real type[" + contract.GetType().Name + "]");
            }

            return(true);
        }
示例#7
0
        public async Task <Transaction> TransferAssetAsync(TransferAssetContract contract, CancellationToken token = default)
        {
            var wallet = GetWallet();

            return(await wallet.TransferAssetAsync(contract, _configuration.GetCallOptions(token)));
        }