//WHITESPACE = _{ "" } // Prohibition of white spaces
nl = _{ "\n" } // Only one way to break a line is accepted
hexa_upper = { ASCII_DIGIT | 'A'..'F' }
base58 = { !("O" | "I" | "l") ~ ASCII_ALPHANUMERIC }
base64 = { ASCII_ALPHANUMERIC | "+" | "/" }
no_zero_u_int = @{ '1'..'9' ~ ASCII_DIGIT* }
u_int = @{ "0" | no_zero_u_int }
hash = @{ hexa_upper{64} }
currency = @{ ASCII_ALPHA ~ (ASCII_ALPHANUMERIC | "-" | "_")* }
pubkey = @{ base58{43,44} }
uid = @{ ASCII_ALPHA ~ (ASCII_ALPHANUMERIC | "-" | "_")* }
block_id = @{ u_int }
blockstamp = ${ block_id ~ "-" ~ hash }
ed25519_sig = @{ base64{88} | (base64{87} ~ "=") | (base64{86} ~ "==") }
v10 = _{ "Version: 10" }
idty_v10 = ${
SOI ~ v10 ~ nl ~
"Type: Identity" ~ nl ~
"Currency: " ~ currency ~ nl ~
"Issuer: " ~ pubkey ~ nl ~
"UniqueID: " ~ uid ~ nl ~
"Timestamp: " ~ blockstamp ~ nl ~
ed25519_sig? ~ nl*
~ EOI
}
idty = ${
(&(SOI ~ v10 ~ nl) ~ idty_v10)
}
membership_in = @{ "IN" }
membership_out = @{ "OUT" }
membership_v10 = ${
SOI ~ v10 ~ nl ~
"Type: Membership" ~ nl ~
"Currency: " ~ currency ~ nl ~
"Issuer: " ~ pubkey ~ nl ~
"Block: " ~ blockstamp ~ nl ~
"Membership: " ~ (membership_in | membership_out) ~ nl ~
"UserID: " ~ uid ~ nl ~
"CertTS: " ~ blockstamp ~ nl ~
ed25519_sig? ~ nl*
~ EOI
}
membership = ${
(&(SOI ~ v10 ~ nl) ~ membership_v10)
}
cert_v10 = ${
v10 ~ nl ~
"Type: Certification" ~ nl ~
"Currency: " ~ currency ~ nl ~
"Issuer: " ~ pubkey ~ nl ~
"IdtyIssuer: " ~ pubkey ~ nl ~
"IdtyUniqueID: " ~ uid ~ nl ~
"IdtyTimestamp: " ~ blockstamp ~ nl ~
"IdtySignature: " ~ ed25519_sig ~ nl ~
"CertTimestamp: " ~ blockstamp ~ nl ~
ed25519_sig? ~ nl*
~ EOI
}
cert = ${
(&(SOI ~ v10 ~ nl) ~ cert_v10)
}
revoc_v10 = ${
SOI ~ v10 ~ nl ~
"Type: Revocation" ~ nl ~
"Currency: " ~ currency ~ nl ~
"Issuer: " ~ pubkey ~ nl ~
"IdtyUniqueID: " ~ uid ~ nl ~
"IdtyTimestamp: " ~ blockstamp ~ nl ~
"IdtySignature: " ~ ed25519_sig ~ nl ~
ed25519_sig? ~ nl*
~ EOI
}
revoc = ${
(&(SOI ~ v10 ~ nl) ~ revoc_v10)
}
tx_locktime = @{ u_int }
tx_amount = @{ u_int }
tx_amount_base = @{ u_int }
du_block_id = @{ u_int }
tx_index = @{ u_int }
input_index = @{ u_int }
issuer_index = @{ u_int }
xhx_secret = @ { ASCII_ALPHANUMERIC+ }
csv_duration = @{ u_int }
cltv_timestamp = @{ u_int }
tx_input = ${ tx_input_du | tx_input_tx }
tx_input_du = ${ tx_amount ~ ":" ~ tx_amount_base ~ ":D:" ~ pubkey ~ ":" ~ du_block_id }
tx_input_tx = ${ tx_amount ~ ":" ~ tx_amount_base ~ ":T:" ~ hash ~ ":" ~ tx_index }
tx_unlock = ${ input_index ~ ":" ~ unlock_cond ~ (" " ~ unlock_cond)* }
unlock_cond = _{ unlock_sig | unlock_xhx }
unlock_sig = ${ "SIG(" ~ issuer_index ~ ")" }
unlock_xhx = ${ "XHX(" ~ xhx_secret ~ ")" }
output_single_cond = { output_cond_sig | output_cond_xhx | output_cond_csv | output_cond_cltv }
output_cond_sig = ${ "SIG(" ~ pubkey ~ ")"? }
output_cond_xhx = ${ "XHX(" ~ hash ~ ")"? }
output_cond_csv = ${ "CSV(" ~ csv_duration ~ ")"? }
output_cond_cltv = ${ "CLTV(" ~ cltv_timestamp ~ ")"? }
operation = _{ output_cond_op_and | output_cond_op_or }
output_cond_op_and = { " && " }
output_cond_op_or = { " || " }
output_conds = { output_conds_expr }
output_conds_expr = _{ term ~ (operation ~ term)* }
output_conds_brackets_expr = ${ "(" ~ output_conds_expr ~ ")" }
term = _{ output_single_cond | output_conds_brackets_expr }
tx_output = ${ tx_amount ~ ":" ~ tx_amount_base ~ ":" ~ output_conds }
tx_comment_char = {
ASCII_ALPHANUMERIC | "." | " " | "-" | "_" | "\\" | ":" | "/" | ";" | "*" | "[" | "]" | "(" | ")" | "?" | "!" | "^"
| "+" | "=" | "@" | "&" | "~" | "#" | "{" | "}" | "|" | "<" | ">" | "%"
}
tx_comment = @{ tx_comment_char{0,255} }
tx_v10 = ${
SOI ~ v10 ~ nl ~
"Type: Transaction" ~ nl ~
"Currency: " ~ currency ~ nl ~
"Blockstamp: " ~ blockstamp ~ nl ~
"Locktime: " ~ tx_locktime ~ nl ~
"Issuers:" ~ nl ~ (pubkey ~ nl)+ ~
"Inputs:" ~ nl ~ (tx_input ~ nl)+ ~
"Unlocks:" ~ nl ~ (tx_unlock ~ nl)+ ~
"Outputs:" ~ nl ~ (tx_output ~ nl)+ ~
"Comment: " ~ tx_comment ~ nl ~
(ed25519_sig ~ nl)* ~ // intermediate signatures (zero if the transaction has only one signature)
ed25519_sig? ~ nl* // last signature
~ EOI
}
tx = ${
(&(SOI ~ v10 ~ nl) ~ tx_v10)
}
document_v10 = ${
&(SOI ~ v10 ~ nl) ~
idty_v10 |
membership_v10 |
cert_v10 |
revoc_v10 |
tx_v10
}
document = ${
&SOI ~
(&(v10 ~ nl) ~ document_v10)
}