///// <summary> ///// 获取指定地址的交易列表 ///// </summary> ///// <param name="_params[0]">地址</param> ///// <param name="_params[1]">起始索引位置,默认1</param> ///// <param name="_params[2]">偏移量,默认20</param> ///// <returns>交易列表</returns> //private JObject GetTransaction(JArray _params, JObject json) //{ // string from = _params[0].AsString(); // string position = _params[1].AsString() != "" ? _params[1].AsString() : "1"; // string offset = _params[2].AsString() != "" ? _params[2].AsString() : "20"; // string jsonRes = RequestRpc("findTxVout", $"address={from}&position={position}&offset={offset}"); // Newtonsoft.Json.Linq.JArray jsons = Newtonsoft.Json.Linq.JArray.Parse(jsonRes); // json["transaction"] = new JArray(jsons.Select(p => // { // JObject peerJson = new JObject(); // peerJson["blockHeight"] = p["blockHeight"].ToString(); // peerJson["txid"] = p["txid"].ToString(); // peerJson["type"] = p["type"].ToString(); // Newtonsoft.Json.Linq.JToken[] jt = p["inAddress"].ToArray(); // JArray j_inaddress = new JArray(); // foreach (Newtonsoft.Json.Linq.JToken i in jt) // { // string s = i.ToString(); // j_inaddress.Add(s); // } // peerJson["inputaddress"] = j_inaddress; // peerJson["asset"] = p["asset"].ToString(); // peerJson["n"] = (int)p["n"]; // peerJson["value"] = (double)p["value"]; // peerJson["outputaddress"] = p["address"].ToString(); // peerJson["time"] = p["time"].ToString(); // peerJson["utctime"] = (int)p["utcTime"]; // peerJson["confirmations"] = p["confirmations"].ToString(); // return peerJson; // })); // return json; //} /// <summary> /// 获取交易的的十六进制字符串(不上链) /// </summary> /// <param name="_params[0]">资产 ID</param> /// <param name="_params[1]">收款地址</param> /// <param name="_params[2]">转账金额</param> /// <param name="_params[3]">手续费,可选参数,默认为 0</param> /// <param name="_params[4]">找零地址,可选参数,默认为钱包中第一个标准地址</param> /// <param name="_params[5]">bhp手续费地址,可选参数。(转账资产为BHP时,此参数无效)</param> /// <returns>交易的的十六进制字符串</returns> private JObject GetTransactionData(JArray _params) { if (wallet == null || walletTimeLock.IsLocked()) { throw new RpcException(-400, "Access denied"); } else { UIntBase assetId = UIntBase.Parse(_params[0].AsString()); AssetDescriptor descriptor = new AssetDescriptor(assetId); UInt160 scriptHash = _params[1].AsString().ToScriptHash(); BigDecimal value = BigDecimal.Parse(_params[2].AsString(), descriptor.Decimals); if (value.Sign <= 0) { throw new RpcException(-32602, "Invalid params"); } Fixed8 fee = _params.Count >= 4 ? Fixed8.Parse(_params[3].AsString()) : Fixed8.Zero; if (fee < Fixed8.Zero) { throw new RpcException(-32602, "Invalid params"); } UInt160 change_address = _params.Count >= 5 ? _params[4].AsString().ToScriptHash() : null; UInt160 fee_address = _params.Count >= 6 ? _params[5].AsString().ToScriptHash() : null; if (assetId.Equals(Blockchain.GoverningToken.Hash)) { fee_address = null; } Transaction tx = wallet.MakeTransaction(null, new[] { new TransferOutput { AssetId = assetId, Value = value, ScriptHash = scriptHash } }, fee_address: fee_address, change_address: change_address, fee: fee); if (tx == null) { throw new RpcException(-300, "Insufficient funds"); } ContractParametersContext context = new ContractParametersContext(tx); wallet.Sign(context); if (context.Completed) { tx.Witnesses = context.GetWitnesses(); if (tx.Size > Transaction.MaxTransactionSize) { throw new RpcException(-301, "The data is too long."); } return(Bhp.IO.Helper.ToArray(tx).ToHexString()); } else { return(context.ToJson()); } } }
/// <summary> /// 发送一个包含订单信息的交易 /// </summary> /// <param name="_params[0]">订单信息</param> /// <param name="_params[1]">资产 ID</param> /// <param name="_params[2]">收款地址</param> /// <param name="_params[3]">转账金额</param> /// <param name="_params[4]">手续费,可选参数,默认为 0</param> /// <param name="_params[5]">找零地址,可选参数,默认为钱包中第一个标准地址</param> /// <param name="_params[6]">bhp手续费地址,可选参数。(转账资产包含BHP时,此参数无效)</param> /// <returns>交易</returns> private JObject SendToAddressOrder(JArray _params) { if (wallet == null || walletTimeLock.IsLocked()) { throw new RpcException(-400, "Access denied"); } else { string remarks = _params[0].AsString(); List <TransactionAttribute> attributes = new List <TransactionAttribute>(); using (ScriptBuilder sb = new ScriptBuilder()) { sb.EmitPush(remarks); attributes.Add(new TransactionAttribute { Usage = TransactionAttributeUsage.Description, Data = sb.ToArray() }); } UIntBase assetId = UIntBase.Parse(_params[1].AsString()); AssetDescriptor descriptor = new AssetDescriptor(assetId); UInt160 scriptHash = _params[2].AsString().ToScriptHash(); BigDecimal value = BigDecimal.Parse(_params[3].AsString(), descriptor.Decimals); if (value.Sign <= 0) { throw new RpcException(-32602, "Invalid params"); } Fixed8 fee = _params.Count >= 5 ? Fixed8.Parse(_params[4].AsString()) : Fixed8.Zero; if (fee < Fixed8.Zero) { throw new RpcException(-32602, "Invalid params"); } UInt160 change_address = _params.Count >= 6 ? _params[5].AsString().ToScriptHash() : null; UInt160 fee_address = _params.Count >= 7 ? _params[6].AsString().ToScriptHash() : null; if (assetId.Equals(Blockchain.GoverningToken.Hash)) { fee_address = null; } Transaction tx = wallet.MakeTransaction(attributes, new[] { new TransferOutput { AssetId = assetId, Value = value, ScriptHash = scriptHash } }, fee_address: fee_address, change_address: change_address, fee: fee); if (tx == null) { throw new RpcException(-300, "Insufficient funds"); } ContractParametersContext context = new ContractParametersContext(tx); wallet.Sign(context); if (context.Completed) { tx.Witnesses = context.GetWitnesses(); if (tx.Size > Transaction.MaxTransactionSize) { throw new RpcException(-301, "The size of the free transaction must be less than 102400 bytes"); } wallet.ApplyTransaction(tx); system.LocalNode.Tell(new LocalNode.Relay { Inventory = tx }); return(tx.ToJson()); } else { return(context.ToJson()); } } }