Skip to content

Instantly share code, notes, and snippets.

@JeremyRubin
Created May 22, 2019 04:50
Show Gist options
  • Save JeremyRubin/6de3accb13dc891a48346173bacaf221 to your computer and use it in GitHub Desktop.
Save JeremyRubin/6de3accb13dc891a48346173bacaf221 to your computer and use it in GitHub Desktop.
#include <cstddef>
static const size_t MAX_DEPTH = 32;
static const size_t NODE_WIDTH = 32;
static const size_t PROOF_SIZE_WIDTH = 33 + 32*32;
static const size_t MAX_STACK_SIZE = 1000;
static const size_t MAX_STACK_ELT_SIZE = 520;
static const size_t MAX_STACK_SIZE_BYTES = MAX_STACK_SIZE*MAX_STACK_ELT_SIZE;
static const size_t NBITS_STACK_WIDTH = 19;
static const size_t MAX_SCRIPT_SIZE_BYTES = 10000;
static const size_t NBITS_SCRIPT_WIDTH = 14;
static const size_t NBITS_PROOF_WIDTH = 5;
static_assert(1<<NBITS_PROOF_WIDTH >= MAX_DEPTH, "Wrong sized NBITS");
static_assert(1<<NBITS_STACK_WIDTH >= MAX_STACK_SIZE_BYTES + MAX_STACK_SIZE * 2, "Wrong sized NBITS");
static_assert(1<<NBITS_SCRIPT_WIDTH >= MAX_SCRIPT_SIZE_BYTES, "Wrong sized NBITS");
enum Version {
AnnexedScriptPath,
AnnexedKeyPath,
PlainScriptPath,
PlainKeyPath,
};
// Pragma pack for serialization, when actually accessing data construct correctly aligned classes
using Annex = unsigned char[32];
template<typename T>
class Annexed {
const bool has_annex : 1;
Annex a;
// unsized, must be last
T path;
Annexed() : has_annex(true){}
};
template<typename T>
class Plain {
const bool has_annex : 1;
T path;
Plain() : has_annex(false){}
};
class Control {
bool epoch : 1;
unsigned char hash_type;
}
class Script
class ScriptPath {
bool is_keypath : 1;
size_t control_width: NBITS_PROOF_WIDTH;
size_t script_length: NBITS_SCRIPT_WIDTH;
size_t stack_length: NBITS_STACK_WIDTH;
//stack@data to data + stack_length
//script@ stack to stack + script_length
//control@ script to script + 33 + NODE_WIDTH *control_width
unsigned char data[];
ScriptPath() : is_keypath(false){}
};
using Signature = unsigned char[65];
class KeyPath {
bool is_keypath : 1;
Signature s;
KeyPath() : is_keypath(true){}
};
class ReadVersion{
bool has_annex : 1;
bool is_keypath: 1;
public:
Version operator()(){
return has_annex ? (is_keypath? AnnexedKeyPath : AnnexedScriptPath) : (is_keypath? PlainKeyPath : PlainScriptPath);
}
};
union Taproot {
ReadVersion version;
Annexed<ScriptPath> as;
Plain<ScriptPath> nas;
Annexed<KeyPath> akp;
Plain<KeyPath> nakp;
};
void dispatch_example(Taproot taproot) {
switch (taproot.version()) {
case PlainScriptPath:
break;
case PlainKeyPath:
break;
case AnnexedScriptPath:
break;
case AnnexedKeyPath:
break;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment