public async Task <TransactionExtention> CreateTransactionAsync(string from, string to, long amount) { var wallet = _walletClient.GetProtocol(); var fromAddress = _walletClient.ParseAddress(from); var toAddress = _walletClient.ParseAddress(to); var transferContract = new TransferContract { OwnerAddress = fromAddress, ToAddress = toAddress, Amount = amount }; var transaction = new Transaction(); var contract = new Transaction.Types.Contract(); try { contract.Parameter = Google.Protobuf.WellKnownTypes.Any.Pack(transferContract); } catch (Exception) { return(new TransactionExtention { Result = new Return { Result = false, Code = Return.Types.response_code.OtherError }, }); } var newestBlock = await wallet.GetNowBlock2Async(new EmptyMessage(), headers : _options.Value.GetgRPCHeaders()); contract.Type = Transaction.Types.Contract.Types.ContractType.TransferContract; transaction.RawData = new Transaction.Types.raw(); transaction.RawData.Contract.Add(contract); transaction.RawData.Timestamp = DateTime.Now.Ticks; transaction.RawData.Expiration = newestBlock.BlockHeader.RawData.Timestamp + 10 * 60 * 60 * 1000; var blockHeight = newestBlock.BlockHeader.RawData.Number; var blockHash = Sha256Sm3Hash.Of(newestBlock.BlockHeader.RawData.ToByteArray()).GetBytes(); var bb = ByteBuffer.Allocate(8); bb.PutLong(blockHeight); var refBlockNum = bb.ToArray(); transaction.RawData.RefBlockHash = ByteString.CopyFrom(blockHash.SubArray(8, 8)); transaction.RawData.RefBlockBytes = ByteString.CopyFrom(refBlockNum.SubArray(6, 2)); var transactionExtension = new TransactionExtention { Transaction = transaction, Txid = ByteString.CopyFromUtf8(transaction.GetTxid()), Result = new Return { Result = true, Code = Return.Types.response_code.Success }, }; return(transactionExtension); }
public async Task <string> TransferAsync(string contractAddress, ITronAccount ownerAccount, string toAddress, decimal amount, string memo, long feeLimit) { var contractAddressBytes = Base58Encoder.DecodeFromBase58Check(contractAddress); var callerAddressBytes = Base58Encoder.DecodeFromBase58Check(toAddress); var ownerAddressBytes = Base58Encoder.DecodeFromBase58Check(ownerAccount.Address); var wallet = _walletClient.GetProtocol(); var functionABI = ABITypedRegistry.GetFunctionABI <TransferFunction>(); try { var contract = await wallet.GetContractAsync(new BytesMessage { Value = ByteString.CopyFrom(contractAddressBytes), }, headers : _walletClient.GetHeaders()); var toAddressBytes = new byte[20]; Array.Copy(callerAddressBytes, 1, toAddressBytes, 0, toAddressBytes.Length); var toAddressHex = "0x" + toAddressBytes.ToHex(); var decimals = GetDecimals(wallet, contractAddressBytes); var tokenAmount = amount; if (decimals > 0) { tokenAmount = amount * Convert.ToDecimal(Math.Pow(10, decimals)); } var trc20Transfer = new TransferFunction { To = toAddressHex, TokenAmount = Convert.ToInt64(tokenAmount), }; var encodedHex = new FunctionCallEncoder().EncodeRequest(trc20Transfer, functionABI.Sha3Signature); var trigger = new TriggerSmartContract { ContractAddress = ByteString.CopyFrom(contractAddressBytes), OwnerAddress = ByteString.CopyFrom(ownerAddressBytes), Data = ByteString.CopyFrom(encodedHex.HexToByteArray()), }; var transactionExtention = await wallet.TriggerConstantContractAsync(trigger, headers : _walletClient.GetHeaders()); if (!transactionExtention.Result.Result) { _logger.LogWarning($"[transfer]transfer failed, message={transactionExtention.Result.Message.ToStringUtf8()}."); return(null); } var transaction = transactionExtention.Transaction; if (transaction.Ret.Count > 0 && transaction.Ret[0].Ret == Transaction.Types.Result.Types.code.Failed) { return(null); } transaction.RawData.Data = ByteString.CopyFromUtf8(memo); transaction.RawData.FeeLimit = feeLimit; var transSign = _transactionClient.GetTransactionSign(transaction, ownerAccount.PrivateKey); var result = await _transactionClient.BroadcastTransactionAsync(transSign); return(transSign.GetTxid()); } catch (Exception ex) { _logger.LogError(ex, ex.Message); return(null); } }