Added Base58 format checking for namespace.

This commit is contained in:
Jianping Wu 2018-11-21 19:57:46 -08:00
parent 080740146f
commit 98234230d2
9 changed files with 38 additions and 17 deletions

View File

@ -383,3 +383,16 @@ bool IsValidDestinationString(const std::string& str)
{
return IsValidDestinationString(str, Params());
}
bool DecodeKevaNamespace(const std::string ns, const CChainParams& params, std::vector<unsigned char>& result)
{
if (!DecodeBase58Check(ns, result)) {
return false;
}
uint160 hash;
const std::vector<unsigned char>& ns_prefix = params.Base58Prefix(CChainParams::KEVA_NAMESPACE);
if (result.size() == hash.size() + ns_prefix.size() && std::equal(ns_prefix.begin(), ns_prefix.end(), result.begin())) {
return true;
}
return false;
}

View File

@ -146,5 +146,6 @@ std::string EncodeDestination(const CTxDestination& dest);
CTxDestination DecodeDestination(const std::string& str);
bool IsValidDestinationString(const std::string& str);
bool IsValidDestinationString(const std::string& str, const CChainParams& params);
bool DecodeKevaNamespace(const std::string ns, const CChainParams& params, std::vector<unsigned char>& result);
#endif // BITCOIN_BASE58_H

View File

@ -50,6 +50,9 @@ static CBlock CreateGenesisBlock(const char* pszTimestamp, const CScript& genesi
*/
static CBlock CreateGenesisBlock(uint32_t nTime, uint32_t nNonce, uint32_t nBits, int32_t nVersion, const CAmount& genesisReward)
{
// JWU TODO:
// 1. Change timestamp
// 2. Fix coinbase script using segwit.
const char* pszTimestamp = "NY Times 05/Oct/2011 Steve Jobs, Apples Visionary, Dies at 56";
const CScript genesisOutputScript = CScript() << ParseHex("049451c9ac3be691a4fa375ea69537a46ef374c1f454dbc7c2c6fe27b280f2b979991aadb29358591a1f72c326b537d7fd03e14d4978a1b57486d9e6d2c3645717") << OP_CHECKSIG;
return CreateGenesisBlock(pszTimestamp, genesisOutputScript, nTime, nNonce, nBits, nVersion, genesisReward);
@ -159,6 +162,7 @@ public:
base58Prefixes[SECRET_KEY] = std::vector<unsigned char>(1,139); // M
base58Prefixes[EXT_PUBLIC_KEY] = {0x04, 0x88, 0xB2, 0x1E};
base58Prefixes[EXT_SECRET_KEY] = {0x04, 0x88, 0xAD, 0xE4};
base58Prefixes[KEVA_NAMESPACE] = std::vector<unsigned char>(1,53); // N
bech32_hrp = "kva";
@ -285,6 +289,7 @@ public:
base58Prefixes[SECRET_KEY] = std::vector<unsigned char>(1,239);
base58Prefixes[EXT_PUBLIC_KEY] = {0x04, 0x35, 0x87, 0xCF};
base58Prefixes[EXT_SECRET_KEY] = {0x04, 0x35, 0x83, 0x94};
base58Prefixes[KEVA_NAMESPACE] = std::vector<unsigned char>(1,53); // N
bech32_hrp = "tkva";
@ -402,6 +407,7 @@ public:
base58Prefixes[SECRET_KEY] = std::vector<unsigned char>(1,239);
base58Prefixes[EXT_PUBLIC_KEY] = {0x04, 0x35, 0x87, 0xCF};
base58Prefixes[EXT_SECRET_KEY] = {0x04, 0x35, 0x83, 0x94};
base58Prefixes[KEVA_NAMESPACE] = std::vector<unsigned char>(1,53); // N
bech32_hrp = "rkva";
}

View File

@ -48,6 +48,7 @@ public:
SECRET_KEY,
EXT_PUBLIC_KEY,
EXT_SECRET_KEY,
KEVA_NAMESPACE,
MAX_BASE58_TYPES
};

View File

@ -153,7 +153,8 @@ CKevaMemPool::removeConflicts(const CTransaction& tx)
bool CKevaMemPool::validateNamespace(const CTransaction& tx, const valtype& nameSpace) const
{
valtype kevaNamespace = ToByteVector(Hash160(ToByteVector(tx.vin[0].prevout.hash)));
kevaNamespace.insert(kevaNamespace.begin(), CKevaScript::NAMESPACE_PREFIX);
const std::vector<unsigned char>& ns_prefix = Params().Base58Prefix(CChainParams::KEVA_NAMESPACE);
kevaNamespace.insert(kevaNamespace.begin(), ns_prefix.begin(), ns_prefix.end());
return kevaNamespace == nameSpace;
}

View File

@ -8,8 +8,6 @@
const std::string CKevaScript::KEVA_DISPLAY_NAME_KEY = "_KEVA_NS_";
const unsigned char CKevaScript::NAMESPACE_PREFIX = 53; // N in Base58Check
CKevaScript::CKevaScript (const CScript& script)
: op(OP_NOP), address(script)
{
@ -87,7 +85,7 @@ CScript CKevaScript::buildKevaNamespace(const CScript& addr, const valtype& name
return prefix + addr;
}
CScript CKevaScript::replaceKevaNamespace(const CScript& oldScript, const uint256& txId, valtype& kaveNamespace)
CScript CKevaScript::replaceKevaNamespace(const CScript& oldScript, const uint256& txId, valtype& kaveNamespace, const CChainParams& params)
{
CKevaScript kevaOp(oldScript);
if (!kevaOp.isNamespaceRegistration()) {
@ -97,7 +95,9 @@ CScript CKevaScript::replaceKevaNamespace(const CScript& oldScript, const uint25
const valtype& displayName = kevaOp.getOpNamespaceDisplayName();
kaveNamespace = ToByteVector(Hash160(ToByteVector(txId)));
kaveNamespace.insert(kaveNamespace.begin(), NAMESPACE_PREFIX);
const std::vector<unsigned char>& ns_prefix = params.Base58Prefix(CChainParams::KEVA_NAMESPACE);
kaveNamespace.insert(kaveNamespace.begin(), ns_prefix.begin(), ns_prefix.end());
return CKevaScript::buildKevaNamespace(kevaOp.getAddress(), kaveNamespace, displayName);
}

View File

@ -6,6 +6,7 @@
#define H_BITCOIN_SCRIPT_KEVA
#include <uint256.h>
#include <chainparams.h>
#include <script/script.h>
class uint160;
@ -45,8 +46,6 @@ public:
*/
static const std::string KEVA_DISPLAY_NAME_KEY;
static const unsigned char NAMESPACE_PREFIX;
/**
* Parse a script and determine whether it is a valid name script. Sets
* the member variables representing the "picked apart" name script.
@ -220,10 +219,10 @@ public:
}
/**
* Build a KEVA_NAMESPACE transaction.
* Build a keva namespace transaction.
* @param addr The address script to append.
* @param hash The hash to use.
* @return The full KEVA_NAMESPACE script.
* @return The full keva namespace script.
*/
static CScript buildKevaNamespace(const CScript& addr, const valtype& nameSpace,
const valtype& displayName);
@ -238,7 +237,7 @@ public:
const valtype& key, const valtype& value);
static CScript replaceKevaNamespace(const CScript& oldScript, const uint256& txId, valtype& kaveNamespace);
static CScript replaceKevaNamespace(const CScript& oldScript, const uint256& txId, valtype& kaveNamespace, const CChainParams& params);
};

View File

@ -230,8 +230,8 @@ UniValue keva_put(const JSONRPCRequest& request)
const std::string namespaceStr = request.params[0].get_str();
valtype nameSpace;
if (!DecodeBase58Check(namespaceStr, nameSpace)) {
throw JSONRPCError (RPC_INVALID_PARAMETER, "failed to decode namespace");
if (!DecodeKevaNamespace(namespaceStr, Params(), nameSpace)) {
throw JSONRPCError (RPC_INVALID_PARAMETER, "invalid namespace id");
}
if (nameSpace.size () > MAX_NAMESPACE_LENGTH)
throw JSONRPCError (RPC_INVALID_PARAMETER, "the namespace is too long");
@ -311,8 +311,8 @@ UniValue keva_get(const JSONRPCRequest& request)
const std::string namespaceStr = request.params[0].get_str ();
valtype nameSpace;
if (!DecodeBase58Check(namespaceStr, nameSpace)) {
throw JSONRPCError (RPC_INVALID_PARAMETER, "failed to decode namespace");
if (!DecodeKevaNamespace(namespaceStr, Params(), nameSpace)) {
throw JSONRPCError (RPC_INVALID_PARAMETER, "invalid namespace id");
}
if (nameSpace.size () > MAX_NAMESPACE_LENGTH)
throw JSONRPCError (RPC_INVALID_PARAMETER, "the namespace is too long");
@ -376,8 +376,8 @@ UniValue keva_pending(const JSONRPCRequest& request)
if (request.params.size() == 1) {
RPCTypeCheckArgument(request.params[0], UniValue::VSTR);
namespaceStr = request.params[0].get_str();
if (!DecodeBase58Check(namespaceStr, nameSpace)) {
throw JSONRPCError (RPC_INVALID_PARAMETER, "failed to decode namespace");
if (!DecodeKevaNamespace(namespaceStr, Params(), nameSpace)) {
throw JSONRPCError (RPC_INVALID_PARAMETER, "invalid namespace id");
}
}

View File

@ -2951,7 +2951,7 @@ bool CWallet::CreateTransaction(const std::vector<CRecipient>& vecSend,
CScript dummyScript = iter->scriptPubKey;
CKevaScript kevaOp(dummyScript);
if (kevaOp.isKevaOp() && kevaOp.isNamespaceRegistration()) {
iter->scriptPubKey = CKevaScript::replaceKevaNamespace(dummyScript, coin.outpoint.hash, kaveNamespace);
iter->scriptPubKey = CKevaScript::replaceKevaNamespace(dummyScript, coin.outpoint.hash, kaveNamespace, Params());
kevaDummyReplaced = true;
break;
}