Added primitive zcrawkeygen/zcrawpour implementations
This commit is contained in:
parent
4f1c37980e
commit
730790f7a4
|
@ -27,6 +27,7 @@ testScripts=(
|
|||
'merkle_blocks.py'
|
||||
'signrawtransactions.py'
|
||||
'walletbackup.py'
|
||||
'zcpour.py'
|
||||
);
|
||||
testScriptsExt=(
|
||||
'bipdersig-p2p.py'
|
||||
|
|
|
@ -49,7 +49,7 @@ except ImportError:
|
|||
|
||||
USER_AGENT = "AuthServiceProxy/0.1"
|
||||
|
||||
HTTP_TIMEOUT = 30
|
||||
HTTP_TIMEOUT = 600
|
||||
|
||||
log = logging.getLogger("BitcoinRPC")
|
||||
|
||||
|
|
|
@ -0,0 +1,71 @@
|
|||
#!/usr/bin/env python2
|
||||
|
||||
#
|
||||
# Test Pour semantics
|
||||
#
|
||||
|
||||
from test_framework.test_framework import BitcoinTestFramework
|
||||
from test_framework.util import *
|
||||
from decimal import Decimal
|
||||
import os
|
||||
import shutil
|
||||
import sys
|
||||
|
||||
class PourTxTest(BitcoinTestFramework):
|
||||
def setup_network(self):
|
||||
# Start with split network:
|
||||
return super(PourTxTest, self).setup_network(True)
|
||||
|
||||
def run_test(self):
|
||||
# All nodes should start with 1,250 BTC:
|
||||
starting_balance = 1250
|
||||
for i in range(4):
|
||||
assert_equal(self.nodes[i].getbalance(), starting_balance)
|
||||
self.nodes[i].getnewaddress("") # bug workaround, coins generated assigned to first getnewaddress!
|
||||
|
||||
# Generate zcaddress keypairs
|
||||
zckeypair1 = self.nodes[0].zcrawkeygen()
|
||||
zcsecretkey1 = zckeypair1["zcsecretkey"]
|
||||
zcaddress1 = zckeypair1["zcaddress"]
|
||||
|
||||
zckeypair2 = self.nodes[0].zcrawkeygen()
|
||||
zcsecretkey2 = zckeypair2["zcsecretkey"]
|
||||
zcaddress2 = zckeypair2["zcaddress"]
|
||||
|
||||
self.nodes[0].move("", "foo", 1220)
|
||||
self.nodes[0].move("", "bar", 30)
|
||||
assert_equal(self.nodes[0].getbalance(""), 0)
|
||||
|
||||
change_address = self.nodes[0].getnewaddress("foo")
|
||||
|
||||
# Pour some of our money into this address
|
||||
(total_in, inputs) = gather_inputs(self.nodes[0], 1210)
|
||||
outputs = {}
|
||||
outputs[change_address] = 78
|
||||
rawtx = self.nodes[0].createrawtransaction(inputs, outputs)
|
||||
|
||||
pour_inputs = {}
|
||||
pour_outputs = {}
|
||||
pour_outputs[zcaddress1] = 100
|
||||
pour_outputs[zcaddress2] = 800
|
||||
exception_triggered = False
|
||||
try:
|
||||
pour_result = self.nodes[0].zcrawpour(rawtx, pour_inputs, pour_outputs, 0, 0)
|
||||
except JSONRPCException:
|
||||
exception_triggered = True
|
||||
|
||||
# We expect it to fail; the pour's balance equation isn't adding up.
|
||||
assert_equal(exception_triggered, True)
|
||||
|
||||
pour_outputs[zcaddress1] = 370
|
||||
pour_result = self.nodes[0].zcrawpour(rawtx, pour_inputs, pour_outputs, 1200, 30)
|
||||
# This should succeed to construct a pour: the math adds up!
|
||||
|
||||
signed_tx_pour = self.nodes[0].signrawtransaction(pour_result["rawtxn"])
|
||||
|
||||
print signed_tx_pour
|
||||
|
||||
self.nodes[0].sendrawtransaction(signed_tx_pour["hex"])
|
||||
|
||||
if __name__ == '__main__':
|
||||
PourTxTest().main()
|
|
@ -91,6 +91,10 @@ static const CRPCConvertParam vRPCConvertParams[] =
|
|||
{ "estimatepriority", 0 },
|
||||
{ "prioritisetransaction", 1 },
|
||||
{ "prioritisetransaction", 2 },
|
||||
{ "zcrawpour", 1 },
|
||||
{ "zcrawpour", 2 },
|
||||
{ "zcrawpour", 3 },
|
||||
{ "zcrawpour", 4 }
|
||||
};
|
||||
|
||||
class CRPCConvertTable
|
||||
|
|
|
@ -376,6 +376,8 @@ static const CRPCCommand vRPCCommands[] =
|
|||
{ "wallet", "walletlock", &walletlock, true },
|
||||
{ "wallet", "walletpassphrasechange", &walletpassphrasechange, true },
|
||||
{ "wallet", "walletpassphrase", &walletpassphrase, true },
|
||||
{ "wallet", "zcrawkeygen", &zc_raw_keygen, true },
|
||||
{ "wallet", "zcrawpour", &zc_raw_pour, true },
|
||||
#endif // ENABLE_WALLET
|
||||
};
|
||||
|
||||
|
|
|
@ -208,6 +208,8 @@ extern json_spirit::Value getblockchaininfo(const json_spirit::Array& params, bo
|
|||
extern json_spirit::Value getnetworkinfo(const json_spirit::Array& params, bool fHelp);
|
||||
extern json_spirit::Value setmocktime(const json_spirit::Array& params, bool fHelp);
|
||||
extern json_spirit::Value resendwallettransactions(const json_spirit::Array& params, bool fHelp);
|
||||
extern json_spirit::Value zc_raw_keygen(const json_spirit::Array& params, bool fHelp);
|
||||
extern json_spirit::Value zc_raw_pour(const json_spirit::Array& params, bool fHelp);
|
||||
|
||||
extern json_spirit::Value getrawtransaction(const json_spirit::Array& params, bool fHelp); // in rcprawtransaction.cpp
|
||||
extern json_spirit::Value listunspent(const json_spirit::Array& params, bool fHelp);
|
||||
|
|
|
@ -2343,3 +2343,122 @@ Value listunspent(const Array& params, bool fHelp)
|
|||
|
||||
return results;
|
||||
}
|
||||
|
||||
Value zc_raw_pour(const json_spirit::Array& params, bool fHelp)
|
||||
{
|
||||
/*
|
||||
zcrawpour <rawtx> {<bucket>: <zcsecretkey>, ...} {<zcaddress>: <value>, ...} vpub_old vpub_new
|
||||
*/
|
||||
|
||||
//RPCTypeCheck(params, boost::assign::list_of(str_type)(obj_type)(obj_type)(int_type)(int_type));
|
||||
|
||||
CTransaction tx;
|
||||
if (!DecodeHexTx(tx, params[0].get_str()))
|
||||
throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "TX decode failed");
|
||||
|
||||
Object inputs = params[1].get_obj();
|
||||
Object outputs = params[2].get_obj();
|
||||
|
||||
CAmount vpub_old(0);
|
||||
CAmount vpub_new(0);
|
||||
|
||||
if (params[3].get_real() != 0.0)
|
||||
vpub_old = AmountFromValue(params[3]);
|
||||
|
||||
if (params[4].get_real() != 0.0)
|
||||
vpub_new = AmountFromValue(params[4]);
|
||||
|
||||
std::vector<PourInput> vpourin;
|
||||
std::vector<PourOutput> vpourout;
|
||||
|
||||
/*
|
||||
BOOST_FOREACH(const Pair& s, inputs)
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
*/
|
||||
|
||||
// TODO
|
||||
vpourin.push_back(PourInput(INCREMENTAL_MERKLE_TREE_DEPTH));
|
||||
vpourin.push_back(PourInput(INCREMENTAL_MERKLE_TREE_DEPTH));
|
||||
|
||||
BOOST_FOREACH(const Pair& s, outputs)
|
||||
{
|
||||
libzerocash::PublicAddress addrTo;
|
||||
|
||||
{
|
||||
vector<unsigned char> decoded(ParseHex(s.name_));
|
||||
CDataStream ssData(decoded, SER_NETWORK, PROTOCOL_VERSION);
|
||||
|
||||
std::vector<unsigned char> pubAddressSecret;
|
||||
std::string encryptionPublicKey;
|
||||
|
||||
ssData >> pubAddressSecret;
|
||||
ssData >> encryptionPublicKey;
|
||||
|
||||
addrTo = libzerocash::PublicAddress(pubAddressSecret, encryptionPublicKey);
|
||||
}
|
||||
CAmount nAmount = AmountFromValue(s.value_);
|
||||
|
||||
libzerocash::Coin coin(addrTo, nAmount);
|
||||
libzerocash::PourOutput output(coin, addrTo);
|
||||
|
||||
vpourout.push_back(output);
|
||||
}
|
||||
|
||||
while (vpourout.size() < 2) {
|
||||
vpourout.push_back(PourOutput(0));
|
||||
}
|
||||
|
||||
// TODO
|
||||
if (vpourout.size() > 2 || vpourin.size() > 2) {
|
||||
throw runtime_error("unsupported");
|
||||
}
|
||||
|
||||
uint256 anchor; // TODO
|
||||
CScript scriptPubKey;
|
||||
CPourTx pourtx(*pzerocashParams,
|
||||
scriptPubKey,
|
||||
anchor,
|
||||
{vpourin[0], vpourin[1]},
|
||||
{vpourout[0], vpourout[1]},
|
||||
vpub_old,
|
||||
vpub_new);
|
||||
|
||||
CMutableTransaction mtx(tx);
|
||||
mtx.nVersion = 2;
|
||||
mtx.vpour.push_back(pourtx);
|
||||
|
||||
CTransaction rawTx(mtx);
|
||||
|
||||
CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
|
||||
ss << rawTx;
|
||||
|
||||
Object result;
|
||||
result.push_back(Pair("encryptedbucket1", HexStr(pourtx.ciphertexts[0].begin(), pourtx.ciphertexts[0].end())));
|
||||
result.push_back(Pair("encryptedbucket2", HexStr(pourtx.ciphertexts[1].begin(), pourtx.ciphertexts[1].end())));
|
||||
result.push_back(Pair("rawtxn", HexStr(ss.begin(), ss.end())));
|
||||
return result;
|
||||
}
|
||||
|
||||
Value zc_raw_keygen(const json_spirit::Array& params, bool fHelp)
|
||||
{
|
||||
auto zckeypair = libzerocash::Address::CreateNewRandomAddress();
|
||||
|
||||
CDataStream pub(SER_NETWORK, PROTOCOL_VERSION);
|
||||
CDataStream priv(SER_NETWORK, PROTOCOL_VERSION);
|
||||
|
||||
pub << zckeypair.getPublicAddress().getPublicAddressSecret(); // a_pk
|
||||
pub << zckeypair.getPublicAddress().getEncryptionPublicKey(); // pk_enc
|
||||
|
||||
priv << zckeypair.getPrivateAddress().getAddressSecret(); // a_sk
|
||||
priv << zckeypair.getPrivateAddress().getEncryptionSecretKey(); // sk_enc
|
||||
|
||||
std::string pub_hex = HexStr(pub.begin(), pub.end());
|
||||
std::string priv_hex = HexStr(priv.begin(), priv.end());
|
||||
|
||||
Object result;
|
||||
result.push_back(Pair("zcaddress", pub_hex));
|
||||
result.push_back(Pair("zcsecretkey", priv_hex));
|
||||
return result;
|
||||
}
|
Loading…
Reference in New Issue