From 528e5469a0faf4ab7feda446a86f42a1b71fdcf0 Mon Sep 17 00:00:00 2001 From: Gregory Sanders Date: Tue, 14 Feb 2017 10:40:34 -0500 Subject: [PATCH] new createblindedaddress call to gen CT address --- qa/rpc-tests/confidential_transactions.py | 17 +++++++++ src/rpc/misc.cpp | 43 +++++++++++++++++++++++ 2 files changed, 60 insertions(+) diff --git a/qa/rpc-tests/confidential_transactions.py b/qa/rpc-tests/confidential_transactions.py index fa315a30c6..65bcddc7e2 100755 --- a/qa/rpc-tests/confidential_transactions.py +++ b/qa/rpc-tests/confidential_transactions.py @@ -174,5 +174,22 @@ def run_test(self): assert_equal(self.nodes[1].getbalance(), node1) assert_equal(self.nodes[2].getbalance(), node2) + # Check createblindedaddress functionality + blinded_addr = self.nodes[0].getnewaddress() + validated_addr = self.nodes[0].validateaddress(blinded_addr) + blinding_key = self.nodes[0].dumpblindingkey(blinded_addr) + assert_equal(blinded_addr, self.nodes[1].createblindedaddress(validated_addr["unconfidential"], blinding_key)) + + # If a blinding key is over-ridden by a newly imported one, funds may be unaccounted for + new_addr = self.nodes[0].getnewaddress() + new_validated = self.nodes[0].validateaddress(new_addr) + self.nodes[2].sendtoaddress(new_addr, 1) + diff_blind = self.nodes[1].createblindedaddress(new_validated["unconfidential"], blinding_key) + assert_equal(len(self.nodes[0].listunspent(0, 0, [new_validated["unconfidential"]])), 1) + self.nodes[0].importblindingkey(diff_blind, blinding_key) + # CT values for this wallet transaction have been cached via importblindingkey + # therefore result will be same even though we change blinding keys + assert_equal(len(self.nodes[0].listunspent(0, 0, [new_validated["unconfidential"]])), 1) + if __name__ == '__main__': CTTest ().main () diff --git a/src/rpc/misc.cpp b/src/rpc/misc.cpp index 7f0a4ce2ee..650a1f14e8 100644 --- a/src/rpc/misc.cpp +++ b/src/rpc/misc.cpp @@ -339,6 +339,48 @@ UniValue createmultisig(const UniValue& params, bool fHelp) return result; } +UniValue createblindedaddress(const UniValue& params, bool fHelp) +{ + if (fHelp || params.size() != 2) + { + string msg = "createblindedaddress address blinding_key\n" + "\nCreates a blinded address using the provided blinding key.\n" + "\nArguments:\n" + "1. \"address\" (string, required) The unblinded address to be blinded.\n" + "2. \"key\" (string, required) The blinding private key.\n" + "\nResult:\n" + "\"blinded_address\" (string) The blinded address.\n" + "\nExamples:\n" + "\nCreate a multisig address from 2 addresses\n" + + HelpExampleCli("createblindedaddress", "HEZk3iQi1jC49bxUriTtynnXgWWWdAYx16 ec09811118b6febfa5ebe68642e5091c418fbace07e655da26b4a845a691fc2d") + + "\nAs a json rpc call\n" + + HelpExampleRpc("createblindedaddress", "HEZk3iQi1jC49bxUriTtynnXgWWWdAYx16, ec09811118b6febfa5ebe68642e5091c418fbace07e655da26b4a845a691fc2d") + ; + throw runtime_error(msg); + } + + CBitcoinAddress address(params[0].get_str()); + if (!address.IsValid()) { + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid Bitcoin address or script"); + } + if (address.IsBlinded()) { + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Not an unblinded address"); + } + + if (!IsHex(params[1].get_str())) { + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid hexadecimal for key"); + } + std::vector keydata = ParseHex(params[1].get_str()); + if (keydata.size() != 32) { + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid hexadecimal key length, must be 32 bytes long."); + } + + CKey key; + key.Set(keydata.begin(), keydata.end(), true); + + return address.AddBlindingKey(key.GetPubKey()).ToString(); +} + UniValue verifymessage(const UniValue& params, bool fHelp) { if (fHelp || params.size() != 3) @@ -472,6 +514,7 @@ static const CRPCCommand commands[] = { "control", "getinfo", &getinfo, true }, /* uses wallet if enabled */ { "util", "validateaddress", &validateaddress, true }, /* uses wallet if enabled */ { "util", "createmultisig", &createmultisig, true }, + { "util", "createblindedaddress", &createblindedaddress, true }, { "util", "verifymessage", &verifymessage, true }, { "util", "signmessagewithprivkey", &signmessagewithprivkey, true },