Jianping Wu
6 years ago
6 changed files with 359 additions and 77 deletions
@ -0,0 +1,75 @@ |
|||||||
|
// Copyright (c) 2014-2017 Daniel Kraft
|
||||||
|
// Distributed under the MIT software license, see the accompanying
|
||||||
|
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||||
|
|
||||||
|
#include <script/keva.h> |
||||||
|
|
||||||
|
#include <uint256.h> |
||||||
|
|
||||||
|
CKevaScript::CKevaScript (const CScript& script) |
||||||
|
: op(OP_NOP), address(script) |
||||||
|
{ |
||||||
|
opcodetype nameOp; |
||||||
|
CScript::const_iterator pc = script.begin (); |
||||||
|
if (!script.GetOp (pc, nameOp)) |
||||||
|
return; |
||||||
|
|
||||||
|
opcodetype opcode; |
||||||
|
while (true) |
||||||
|
{ |
||||||
|
valtype vch; |
||||||
|
|
||||||
|
if (!script.GetOp (pc, opcode, vch)) |
||||||
|
return; |
||||||
|
if (opcode == OP_DROP || opcode == OP_2DROP || opcode == OP_NOP) |
||||||
|
break; |
||||||
|
if (!(opcode >= 0 && opcode <= OP_PUSHDATA4)) |
||||||
|
return; |
||||||
|
|
||||||
|
args.push_back (vch); |
||||||
|
} |
||||||
|
|
||||||
|
// Move the pc to after any DROP or NOP.
|
||||||
|
while (opcode == OP_DROP || opcode == OP_2DROP || opcode == OP_NOP) |
||||||
|
if (!script.GetOp (pc, opcode)) |
||||||
|
break; |
||||||
|
pc--; |
||||||
|
|
||||||
|
/* Now, we have the args and the operation. Check if we have indeed
|
||||||
|
a valid name operation and valid argument counts. Only now set the |
||||||
|
op and address members, if everything is valid. */ |
||||||
|
switch (nameOp) |
||||||
|
{ |
||||||
|
case OP_KEVA_PUT: |
||||||
|
if (args.size () != 1) |
||||||
|
return; |
||||||
|
break; |
||||||
|
|
||||||
|
default: |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
op = nameOp; |
||||||
|
address = CScript (pc, script.end ()); |
||||||
|
} |
||||||
|
|
||||||
|
CScript |
||||||
|
CKevaScript::buildKevaPut(const CScript& addr, const valtype& nameSpace, |
||||||
|
const valtype& key, const valtype& value) |
||||||
|
{ |
||||||
|
CScript prefix; |
||||||
|
prefix << OP_KEVA_PUT << nameSpace << key << value |
||||||
|
<< OP_2DROP << OP_2DROP; |
||||||
|
|
||||||
|
return prefix + addr; |
||||||
|
} |
||||||
|
|
||||||
|
CScript CKevaScript::buildKevaNamespace(const CScript& addr, const valtype& nameSpace, |
||||||
|
const valtype& displayName) { |
||||||
|
CScript prefix; |
||||||
|
prefix << OP_KEVA_NAMESPACE << nameSpace << displayName |
||||||
|
<< OP_2DROP << OP_2DROP; |
||||||
|
|
||||||
|
return prefix + addr; |
||||||
|
} |
||||||
|
|
@ -0,0 +1,207 @@ |
|||||||
|
// Copyright (c) 2018 Jianping Wu
|
||||||
|
// Distributed under the MIT software license, see the accompanying
|
||||||
|
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||||
|
|
||||||
|
#ifndef H_BITCOIN_SCRIPT_KEVA |
||||||
|
#define H_BITCOIN_SCRIPT_KEVA |
||||||
|
|
||||||
|
#include <script/script.h> |
||||||
|
|
||||||
|
class uint160; |
||||||
|
|
||||||
|
/**
|
||||||
|
* A script parsed for keva operations. This can be initialised |
||||||
|
* from a "standard" script, and will then determine if this is |
||||||
|
* a name operation and which parts it consists of. |
||||||
|
*/ |
||||||
|
class CKevaScript |
||||||
|
{ |
||||||
|
|
||||||
|
private: |
||||||
|
|
||||||
|
/** The type of operation. OP_NOP if no (valid) name op. */ |
||||||
|
opcodetype op; |
||||||
|
|
||||||
|
/** The non-name part, i. e., the address. */ |
||||||
|
CScript address; |
||||||
|
|
||||||
|
/** The operation arguments. */ |
||||||
|
std::vector<valtype> args; |
||||||
|
|
||||||
|
public: |
||||||
|
|
||||||
|
/**
|
||||||
|
* Default constructor. This enables us to declare a variable |
||||||
|
* and initialise it later via assignment. |
||||||
|
*/ |
||||||
|
inline CKevaScript () |
||||||
|
: op(OP_NOP) |
||||||
|
{} |
||||||
|
|
||||||
|
/**
|
||||||
|
* Parse a script and determine whether it is a valid name script. Sets |
||||||
|
* the member variables representing the "picked apart" name script. |
||||||
|
* @param script The ordinary script to parse. |
||||||
|
*/ |
||||||
|
explicit CKevaScript (const CScript& script); |
||||||
|
|
||||||
|
/**
|
||||||
|
* Return whether this is a (valid) name script. |
||||||
|
* @return True iff this is a name operation. |
||||||
|
*/ |
||||||
|
inline bool |
||||||
|
isNameOp () const |
||||||
|
{ |
||||||
|
switch (op) |
||||||
|
{ |
||||||
|
case OP_KEVA_PUT: |
||||||
|
return true; |
||||||
|
|
||||||
|
case OP_NOP: |
||||||
|
return false; |
||||||
|
|
||||||
|
default: |
||||||
|
assert (false); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the non-name script. |
||||||
|
* @return The address part. |
||||||
|
*/ |
||||||
|
inline const CScript& |
||||||
|
getAddress () const |
||||||
|
{ |
||||||
|
return address; |
||||||
|
} |
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the name operation. This returns OP_NAME_NEW, OP_NAME_FIRSTUPDATE |
||||||
|
* or OP_NAME_UPDATE. Do not call if this is not a name script. |
||||||
|
* @return The name operation opcode. |
||||||
|
*/ |
||||||
|
inline opcodetype |
||||||
|
getNameOp () const |
||||||
|
{ |
||||||
|
switch (op) |
||||||
|
{ |
||||||
|
case OP_KEVA_PUT: |
||||||
|
return op; |
||||||
|
|
||||||
|
default: |
||||||
|
assert (false); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/**
|
||||||
|
* Return whether this is a name update (including first updates). I. e., |
||||||
|
* whether this creates a name index update/entry. |
||||||
|
* @return True iff this is NAME_FIRSTUPDATE or NAME_UPDATE. |
||||||
|
*/ |
||||||
|
inline bool |
||||||
|
isAnyUpdate () const |
||||||
|
{ |
||||||
|
switch (op) |
||||||
|
{ |
||||||
|
case OP_KEVA_PUT: |
||||||
|
return true; |
||||||
|
|
||||||
|
default: |
||||||
|
assert (false); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the name operation name. This call is only valid for |
||||||
|
* OP_NAME_FIRSTUPDATE or OP_NAME_UPDATE. |
||||||
|
* @return The name operation's name. |
||||||
|
*/ |
||||||
|
inline const valtype& |
||||||
|
getOpName () const |
||||||
|
{ |
||||||
|
switch (op) |
||||||
|
{ |
||||||
|
case OP_KEVA_PUT: |
||||||
|
return args[0]; |
||||||
|
|
||||||
|
default: |
||||||
|
assert (false); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the name operation value. This call is only valid for |
||||||
|
* OP_NAME_FIRSTUPDATE or OP_NAME_UPDATE. |
||||||
|
* @return The name operation's value. |
||||||
|
*/ |
||||||
|
inline const valtype& |
||||||
|
getOpValue () const |
||||||
|
{ |
||||||
|
switch (op) |
||||||
|
{ |
||||||
|
case OP_KEVA_PUT: |
||||||
|
// args[1] is namespace
|
||||||
|
return args[2]; |
||||||
|
|
||||||
|
default: |
||||||
|
assert (false); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the name operation's rand value. This is only valid |
||||||
|
* for OP_NAME_FIRSTUPDATE. |
||||||
|
* @return The name operation's rand. |
||||||
|
*/ |
||||||
|
inline const valtype& |
||||||
|
getOpRand () const |
||||||
|
{ |
||||||
|
assert (op == OP_NAME_FIRSTUPDATE); |
||||||
|
return args[1]; |
||||||
|
} |
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the name operation's hash value. This is only valid |
||||||
|
* for OP_NAME_NEW. |
||||||
|
* @return The name operation's hash. |
||||||
|
*/ |
||||||
|
inline const valtype& |
||||||
|
getOpHash () const |
||||||
|
{ |
||||||
|
assert (op == OP_NAME_NEW); |
||||||
|
return args[0]; |
||||||
|
} |
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if the given script is a name script. This is a utility method. |
||||||
|
* @param script The script to parse. |
||||||
|
* @return True iff it is a name script. |
||||||
|
*/ |
||||||
|
static inline bool |
||||||
|
isNameScript (const CScript& script) |
||||||
|
{ |
||||||
|
const CKevaScript op(script); |
||||||
|
return op.isNameOp (); |
||||||
|
} |
||||||
|
|
||||||
|
/**
|
||||||
|
* Build a KEVA_NAMESPACE transaction. |
||||||
|
* @param addr The address script to append. |
||||||
|
* @param hash The hash to use. |
||||||
|
* @return The full KEVA_NAMESPACE script. |
||||||
|
*/ |
||||||
|
static CScript buildKevaNamespace(const CScript& addr, const valtype& nameSpace, |
||||||
|
const valtype& displayName); |
||||||
|
|
||||||
|
/**
|
||||||
|
* Build a KEVA_PUT transaction. |
||||||
|
* @param addr The address script to append. |
||||||
|
* @param hash The hash to use. |
||||||
|
* @return The full KEVA_PUT script. |
||||||
|
*/ |
||||||
|
static CScript buildKevaPut(const CScript& addr, const valtype& nameSpace, |
||||||
|
const valtype& key, const valtype& value); |
||||||
|
|
||||||
|
}; |
||||||
|
|
||||||
|
#endif // H_BITCOIN_SCRIPT_KEVA
|
Loading…
Reference in new issue