Jianping Wu
6 years ago
6 changed files with 359 additions and 77 deletions
@ -0,0 +1,75 @@
@@ -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 @@
@@ -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