Example #1
0
Value sendtoaddresswithfee(const Array& params, bool fHelp)
 {
	int size = params.size();
	if (fHelp || (!(size == 3 || size == 4)))
		throw runtime_error(
						"sendtoaddresswithfee (\"sendaddress\") \"recvaddress\" \"amount\" (fee)\n"
						"\nSend an amount to a given address with fee. The amount is a real and is rounded to the nearest 0.00000001\n"
						"\nArguments:\n"
						"1. \"sendaddress\"  (string, optional) The Honghuo address to send to.\n"
						"2. \"recvaddress\" (string, required) The Honghuo address to receive.\n"
						"3.\"amount\"   (string,required) \n"
						"4.\"fee\"      (string,required) \n"
						"\nResult:\n"
						"\"transactionid\"  (string) The transaction id.\n"
						"\nExamples:\n"
						+ HelpExampleCli("sendtoaddresswithfee", "\"1M72Sfpbz1BPpXFHz9m3CdqATR44Jvaydd\" 10000000 1000")
						+ HelpExampleCli("sendtoaddresswithfee",
						"\"1M72Sfpbz1BPpXFHz9m3CdqATR44Jvaydd\" 0.1 \"donation\" \"seans outpost\"")
						+ HelpExampleRpc("sendtoaddresswithfee",
						"\"1M72Sfpbz1BPpXFHz9m3CdqATR44Jvaydd\", 0.1, \"donation\", \"seans outpost\""
						+ HelpExampleCli("sendtoaddresswithfee", "\"0-6\" 10 ")
						+ HelpExampleCli("sendtoaddresswithfee", "\"00000000000000000005\" 10 ")
						+ HelpExampleCli("sendtoaddresswithfee", "\"0-6\" \"0-5\" 10 ")
						+ HelpExampleCli("sendtoaddresswithfee", "\"00000000000000000005\" \"0-6\"10 ")));

	EnsureWalletIsUnlocked();
	CKeyID sendKeyId;
	CKeyID RevKeyId;

	auto GetKeyId = [](string const &addr,CKeyID &KeyId) {
		if (!CRegID::GetKeyID(addr, KeyId)) {
			KeyId=CKeyID(addr);
			if (KeyId.IsEmpty())
			return false;
		}
		return true;
	};

	// Amount
	int64_t nAmount = 0;
	int64_t nFee = 0;
	//// from address to addreww
	if (size == 4) {

		if (!GetKeyId(params[0].get_str(), sendKeyId)) {
			throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "FROM Invalid  address");
		}
		if (!GetKeyId(params[1].get_str(), RevKeyId)) {
			throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "to Invalid  address");
		}

		nAmount = AmountToRawValue(params[2]);
		if (pAccountViewTip->GetRawBalance(sendKeyId) <= nAmount + SysCfg().GetTxFee()) {
			throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "FROM address not enough coins");
		}
		nFee = AmountToRawValue(params[3]);
	} else {
		if (!GetKeyId(params[0].get_str(), RevKeyId)) {
			throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "to address Invalid  ");
		}

		nAmount = AmountToRawValue(params[1]);
		set<CKeyID> sKeyid;
		sKeyid.clear();
		pwalletMain->GetKeys(sKeyid);
		if (sKeyid.empty()) //get addrs
		{
			throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "No Key In wallet \n");
		}
		nFee = AmountToRawValue(params[2]);
		for (auto &te : sKeyid) {
			if (pAccountViewTip->GetRawBalance(te) >= nAmount + SysCfg().GetTxFee()) {
				sendKeyId = te;
				break;
			}
		}

		if (sendKeyId.IsNull()) {
			throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "not find enough moeny account ");
		}
	}

	auto SendMoney = [&](const CRegID &send, const CUserID &rsv, int64_t nValue, int64_t nFee) {
		CTransaction tx;
		tx.srcRegId = send;
		tx.desUserId = rsv;
		tx.llValues = nValue;
		if (0 == nFee) {
			tx.llFees = SysCfg().GetTxFee();
		} else
		tx.llFees = nFee;
		tx.nValidHeight = chainActive.Tip()->nHeight;

		CKeyID keID;
		if(!pAccountViewTip->GetKeyId(send,keID)) {
			return std::make_tuple (false,"key or keID failed");
		}

		if (!pwalletMain->Sign(keID,tx.SignatureHash(), tx.signature)) {
			return std::make_tuple (false,"Sign failed");
		}
		std::tuple<bool,string> ret = pwalletMain->CommitTransaction((CBaseTransaction *) &tx);
		bool falg = std::get<0>(ret);
		string te = std::get<1>(ret);
		if(falg == true)
		te = tx.GetHash().ToString();
		return std::make_tuple (falg,te.c_str());
	};


	CRegID sendreg;
	CRegID revreg;


	if (!pAccountViewTip->GetRegId(CUserID(sendKeyId), sendreg)) {
		throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid  address");
	}

	std::tuple<bool,string> ret;
	if (pAccountViewTip->GetRegId(CUserID(RevKeyId), revreg)) {
		ret = SendMoney(sendreg, revreg, nAmount, nFee);
	} else {


		ret = SendMoney(sendreg, CUserID(RevKeyId), nAmount, nFee);
	}

	Object obj;
	obj.push_back(Pair(std::get<0>(ret) ? "hash" : "error code", std::get<1>(ret)));
	return obj;
}