Maybe someone else is also trying to write some ElasticPL code to execute it in Elastic network so I paste little @EK howto for you:
I have worked 14 hours straight today, and I would like to give you all a short status update and ask for a "feature request".
What I have done basically is create an entirely new programming language for elastic including a JIT compiler and an interpreter. The programming language is basic enough to be able to say that it is safe and that "eastereggs" like for example Soliticy's send bug are not possible. I would like to give you a short overview what is there and ask you all what you would like to have in it before we close that chapter for now.
1. The programming language does not allow the declaration of new variables. All you have is the integer state array m[0]-m[255]. This limits the memory overhead of the user-provided POW algorithms to 256*8 Bits. Dos attacks using "stack/heap exhaustion" or whatever are not possible.
Any other variable declarations are not allowed per the grammar, also m[256 and higher] are forbidden per grammer and result in a syntax error so other implementations (maybe we will have some in Go or so) cannot screw up here at all.
The programmer must make sure to use the state array in a "smart" manner!
2. We support the following operations:
+: Addition
-: Subtraction
*: Multiplication
/: Integer Division
%: Modulo Operation
>>: Right Shift 32bit
<<: Left Shift 32bit
>>>: Right Rotate 32bit
<<<: Left Rotate 32bit
~: Bitwise Complement
!: Logical Negation
^: Bitwise XOR 32 bit
&: Bitwise OR 32 bit
|: BitWise AND 32bit
3. And we support the following relational exressions:
<: smaller
>: larger
<=: smaller than
>=: greater than
==: equal
=!: not equal
4, And the following conditional expressions:
&&: and
||: or
5. Additionally, we have two (ASK FOR MORE NOW, PLEASE!!) built in functions:
SHA256 x y;
MD5 x y;
Which start at the beginning of
m[ x ] and take y byte from there to hash it with the given hash function. In this case, the state array is overwritten beginning at the first byte of
m[ x ] with HASH_LENGTH bytes.
6. We support
- if statements
- while statements
7. The "random integers" provided by the miners are stored in
m[ 0 ]-m[ ... ] (depending on how many the POW author requests).
8. Every source file must start with "input x;" while x is a value between 3 and 12 and describes how many random integers are shuffled by the miners. Those are added to the state beginning at m[0]...
9. Every source file must end with "verify STATEMENT;" which is the bounty submission check. This line is a Statement that evaluated to either true or false and tells us if the result is "a bounty" or not.
EXAMPLE
======This is very theoretical, I know! I will give a practical example tomorrow so everyone can try one. For those who are interested in diving into the technical backgrounds ...
Here is a Bitcoin-Mining-Function that would mine the Genesis Block 0 and that is written in Elastics internal programming language:
SMALL AND COMPACT, ISN'T IT??? It is basically putting the block header into the internal state using Elastic's Programming Language's syntax in "unsigned integer coding" and calls SHA256 Twice, once hashing all 80 bytes of the block header and the second time only the 32 bytes of the resulting hash. The nonce is "shuffled" using the random input fed by the "miners" from m[ 1 ] ;
Tested ;-) Works! ;-)
input 3;
m[3]=16777216;
m[4]=0;
m[5]=0;
m[6]=0;
m[7]=0;
m[8]=0;
m[9]=0;
m[10]=0;
m[11]=0;
m[12]=1000599037;
m[13]=2054886066;
m[14]=2059873342;
m[15]=1735823201;
m[16]=2143820739;
m[17]=2290766130;
m[18]=983546026;
m[19]=1260281418;
m[20]=699096905;
m[21]=4294901789;
m[22]=497822464 | (m[1] & 255);
SHA256 3 80;
SHA256 3 32;
verify m[10]==0;
The Bounty hook function which must be the last instruction in the source code in this case is "checking for 32 leading zerobits which in fact are trailing zero bits due to endianess".
This is simply:
verify m[10]==0;
And this is the grammar of ElasticPL (POW) for now:
SKIP :
{
" "
| "\t"
| "\n"
| "\r"
| "\f"
}
TOKEN :
{
< INTEGER_LITERAL: (<DIGIT>)+ >
}
void CompilationUnit() :
{
String name;
}
{
(
Statement()
)*
FinalBountyCheckExpression()
<EOF>
}
void FinalBountyCheckExpression() :
{}
{
"verify" Expression() ";"
}
void Expression() #void:
{}
{
LOOKAHEAD( PrimaryExpression() "=" )
Assignment()
|
ConditionalOrExpression()
}
void Assignment() #Assignment(2) :
{}
{
PrimaryExpression() "=" Expression()
}
void ConditionalOrExpression() #void :
{}
{
ConditionalAndExpression()
( "||" ConditionalAndExpression() #OrNode(2) )*
}
void ConditionalAndExpression() #void :
{}
{
InclusiveOrExpression()
( "&&" InclusiveOrExpression() #AndNode(2) )*
}
void InclusiveOrExpression() #void :
{}
{
ExclusiveOrExpression()
( "|" ExclusiveOrExpression() #BitwiseOrNode(2) )*
}
void ExclusiveOrExpression() #void :
{}
{
AndExpression()
( "^" AndExpression() #BitwiseXorNode(2) )*
}
void AndExpression() #void :
{}
{
EqualityExpression()
( "&" EqualityExpression() #BitwiseAndNode(2) )*
}
void EqualityExpression() #void :
{}
{
RelationalExpression()
(
"==" RelationalExpression() #EQNode(2)
|
"!=" RelationalExpression() #NENode(2)
)*
}
void RelationalExpression() #void :
{}
{
AdditiveExpression()
(
"<" AdditiveExpression() #LTNode(2)
|
">" AdditiveExpression() #GTNode(2)
|
"<=" AdditiveExpression() #LENode(2)
|
">=" AdditiveExpression() #GENode(2)
)*
}
void AdditiveExpression() #void :
{}
{
MultiplicativeExpression()
(
"+" MultiplicativeExpression() #AddNode(2)
|
"-" MultiplicativeExpression() #SubtractNode(2)
)*
}
void MultiplicativeExpression() #void :
{}
{
UnaryExpression()
(
"*" UnaryExpression() #MulNode(2)
|
"/" UnaryExpression() #DivNode(2)
|
"%" UnaryExpression() #ModNode(2)
|
">>" UnaryExpression() #RShiftNode(2)
|
"<<" UnaryExpression() #LShiftNode(2)
|
">>>" UnaryExpression() #RRotNode(2)
|
"<<<" UnaryExpression() #LRotNode(2)
)*
}
void UnaryExpression() #void :
{}
{
"~" UnaryExpression() #BitwiseComplNode(1)
|
"!" UnaryExpression() #NotNode(1)
|
PrimaryExpression()
}
void PrimaryExpression() #void :
{
String name;
}
{
Literal()
|
Id()
|
"(" Expression() ")"
}
void Id() :
{
Token t;
}
{
t = <IDENTIFIER> { jjtThis.name = t.image; }
}
void Literal() #void :
{
Token t;
}
{
(
t=<INTEGER_LITERAL>
{
jjtThis.val = Integer.parseUnsignedInt(t.image);
}
)#IntConstNode
|
BooleanLiteral()
}
void BooleanLiteral() #void :
{}
{
"true" #TrueNode
|
"false" #FalseNode
}
void Statement() #void :
{}
{
";"
|
LOOKAHEAD(2)
LabeledStatement()
|
Block()
|
StatementExpression()
|
IfStatement()
|
WhileStatement()
|
HashStatement()
}
void HashStatement() #void :
{}
{
SHA256()
|
MD5()
}
void SHA256() :
{ Token t1; Token t2; }
{
"SHA256" t1 = <INTEGER_LITERAL> t2 = <INTEGER_LITERAL>
{ jjtThis.position_to_start = Integer.valueOf(t1.image); jjtThis.byte_length = Integer.valueOf(t2.image); }
}
void MD5() :
{ Token t1; Token t2; }
{
"MD5" t1 = <INTEGER_LITERAL> t2 = <INTEGER_LITERAL>
{ jjtThis.position_to_start = Integer.valueOf(t1.image); jjtThis.byte_length = Integer.valueOf(t2.image); }
}
void LabeledStatement() #void :
{}
{
<IDENTIFIER> ":" Statement()
}
void Block() :
{}
{
"{" ( Statement() )* "}"
}
void StatementExpression() :
{}
{
Assignment() ";"
}
void IfStatement() :
{}
{
"if" "(" Expression() ")" Statement() [ LOOKAHEAD(1) "else" Statement() ]
}
void WhileStatement() :
{}
{
"while" "(" Expression() ")" Statement()
}
TOKEN :
{
< IDENTIFIER: "m[" (<DIGIT>|<NOZERODIGIT><DIGIT>|<ONE><DIGIT><DIGIT>|<TWO><ZEROTOFOUR><DIGIT>|<TWO><FIVE><ZEROTOFIVE>) "]" >
|
< #DIGIT: [ "0"-"9" ] >
|
< #NOZERODIGIT: [ "1"-"9" ] >
|
< #ONE: [ "1" ] >
|
< #TWO: [ "2" ] >
|
< #ZEROTOFOUR: [ "0"-"4" ] >
|
< #FIVE: [ "5" ] >
|
< #ZEROTOFIVE: [ "0"-"5" ] >
}