Browse Source

Added Base58 format checking for namespace.

cn
Jianping Wu 6 years ago
parent
commit
98234230d2
  1. 13
      src/base58.cpp
  2. 1
      src/base58.h
  3. 6
      src/chainparams.cpp
  4. 1
      src/chainparams.h
  5. 3
      src/keva/main.cpp
  6. 8
      src/script/keva.cpp
  7. 9
      src/script/keva.h
  8. 12
      src/wallet/rpckeva.cpp
  9. 2
      src/wallet/wallet.cpp

13
src/base58.cpp

@ -383,3 +383,16 @@ bool IsValidDestinationString(const std::string& str)
{ {
return IsValidDestinationString(str, Params()); 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;
}

1
src/base58.h

@ -146,5 +146,6 @@ std::string EncodeDestination(const CTxDestination& dest);
CTxDestination DecodeDestination(const std::string& str); CTxDestination DecodeDestination(const std::string& str);
bool IsValidDestinationString(const std::string& str); bool IsValidDestinationString(const std::string& str);
bool IsValidDestinationString(const std::string& str, const CChainParams& params); 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 #endif // BITCOIN_BASE58_H

6
src/chainparams.cpp

@ -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) 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, Apple’s Visionary, Dies at 56"; const char* pszTimestamp = "NY Times 05/Oct/2011 Steve Jobs, Apple’s Visionary, Dies at 56";
const CScript genesisOutputScript = CScript() << ParseHex("049451c9ac3be691a4fa375ea69537a46ef374c1f454dbc7c2c6fe27b280f2b979991aadb29358591a1f72c326b537d7fd03e14d4978a1b57486d9e6d2c3645717") << OP_CHECKSIG; const CScript genesisOutputScript = CScript() << ParseHex("049451c9ac3be691a4fa375ea69537a46ef374c1f454dbc7c2c6fe27b280f2b979991aadb29358591a1f72c326b537d7fd03e14d4978a1b57486d9e6d2c3645717") << OP_CHECKSIG;
return CreateGenesisBlock(pszTimestamp, genesisOutputScript, nTime, nNonce, nBits, nVersion, genesisReward); 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[SECRET_KEY] = std::vector<unsigned char>(1,139); // M
base58Prefixes[EXT_PUBLIC_KEY] = {0x04, 0x88, 0xB2, 0x1E}; base58Prefixes[EXT_PUBLIC_KEY] = {0x04, 0x88, 0xB2, 0x1E};
base58Prefixes[EXT_SECRET_KEY] = {0x04, 0x88, 0xAD, 0xE4}; base58Prefixes[EXT_SECRET_KEY] = {0x04, 0x88, 0xAD, 0xE4};
base58Prefixes[KEVA_NAMESPACE] = std::vector<unsigned char>(1,53); // N
bech32_hrp = "kva"; bech32_hrp = "kva";
@ -285,6 +289,7 @@ public:
base58Prefixes[SECRET_KEY] = std::vector<unsigned char>(1,239); base58Prefixes[SECRET_KEY] = std::vector<unsigned char>(1,239);
base58Prefixes[EXT_PUBLIC_KEY] = {0x04, 0x35, 0x87, 0xCF}; base58Prefixes[EXT_PUBLIC_KEY] = {0x04, 0x35, 0x87, 0xCF};
base58Prefixes[EXT_SECRET_KEY] = {0x04, 0x35, 0x83, 0x94}; base58Prefixes[EXT_SECRET_KEY] = {0x04, 0x35, 0x83, 0x94};
base58Prefixes[KEVA_NAMESPACE] = std::vector<unsigned char>(1,53); // N
bech32_hrp = "tkva"; bech32_hrp = "tkva";
@ -402,6 +407,7 @@ public:
base58Prefixes[SECRET_KEY] = std::vector<unsigned char>(1,239); base58Prefixes[SECRET_KEY] = std::vector<unsigned char>(1,239);
base58Prefixes[EXT_PUBLIC_KEY] = {0x04, 0x35, 0x87, 0xCF}; base58Prefixes[EXT_PUBLIC_KEY] = {0x04, 0x35, 0x87, 0xCF};
base58Prefixes[EXT_SECRET_KEY] = {0x04, 0x35, 0x83, 0x94}; base58Prefixes[EXT_SECRET_KEY] = {0x04, 0x35, 0x83, 0x94};
base58Prefixes[KEVA_NAMESPACE] = std::vector<unsigned char>(1,53); // N
bech32_hrp = "rkva"; bech32_hrp = "rkva";
} }

1
src/chainparams.h

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

3
src/keva/main.cpp

@ -153,7 +153,8 @@ CKevaMemPool::removeConflicts(const CTransaction& tx)
bool CKevaMemPool::validateNamespace(const CTransaction& tx, const valtype& nameSpace) const bool CKevaMemPool::validateNamespace(const CTransaction& tx, const valtype& nameSpace) const
{ {
valtype kevaNamespace = ToByteVector(Hash160(ToByteVector(tx.vin[0].prevout.hash))); 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; return kevaNamespace == nameSpace;
} }

8
src/script/keva.cpp

@ -8,8 +8,6 @@
const std::string CKevaScript::KEVA_DISPLAY_NAME_KEY = "_KEVA_NS_"; 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) CKevaScript::CKevaScript (const CScript& script)
: op(OP_NOP), address(script) : op(OP_NOP), address(script)
{ {
@ -87,7 +85,7 @@ CScript CKevaScript::buildKevaNamespace(const CScript& addr, const valtype& name
return prefix + addr; 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); CKevaScript kevaOp(oldScript);
if (!kevaOp.isNamespaceRegistration()) { if (!kevaOp.isNamespaceRegistration()) {
@ -97,7 +95,9 @@ CScript CKevaScript::replaceKevaNamespace(const CScript& oldScript, const uint25
const valtype& displayName = kevaOp.getOpNamespaceDisplayName(); const valtype& displayName = kevaOp.getOpNamespaceDisplayName();
kaveNamespace = ToByteVector(Hash160(ToByteVector(txId))); 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); return CKevaScript::buildKevaNamespace(kevaOp.getAddress(), kaveNamespace, displayName);
} }

9
src/script/keva.h

@ -6,6 +6,7 @@
#define H_BITCOIN_SCRIPT_KEVA #define H_BITCOIN_SCRIPT_KEVA
#include <uint256.h> #include <uint256.h>
#include <chainparams.h>
#include <script/script.h> #include <script/script.h>
class uint160; class uint160;
@ -45,8 +46,6 @@ public:
*/ */
static const std::string KEVA_DISPLAY_NAME_KEY; 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 * Parse a script and determine whether it is a valid name script. Sets
* the member variables representing the "picked apart" name script. * 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 addr The address script to append.
* @param hash The hash to use. * @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, static CScript buildKevaNamespace(const CScript& addr, const valtype& nameSpace,
const valtype& displayName); const valtype& displayName);
@ -238,7 +237,7 @@ public:
const valtype& key, const valtype& value); 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);
}; };

12
src/wallet/rpckeva.cpp

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

2
src/wallet/wallet.cpp

@ -2951,7 +2951,7 @@ bool CWallet::CreateTransaction(const std::vector<CRecipient>& vecSend,
CScript dummyScript = iter->scriptPubKey; CScript dummyScript = iter->scriptPubKey;
CKevaScript kevaOp(dummyScript); CKevaScript kevaOp(dummyScript);
if (kevaOp.isKevaOp() && kevaOp.isNamespaceRegistration()) { 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; kevaDummyReplaced = true;
break; break;
} }

Loading…
Cancel
Save