mirror of
https://github.com/transatoshi-mw/grin-web-wallet.git
synced 2025-10-07 00:02:47 +00:00
contents of zip
This commit is contained in:
586
scripts/slate_output.js
Executable file
586
scripts/slate_output.js
Executable file
@@ -0,0 +1,586 @@
|
||||
// Use strict
|
||||
"use strict";
|
||||
|
||||
|
||||
// Classes
|
||||
|
||||
// Slate output class
|
||||
class SlateOutput {
|
||||
|
||||
// Public
|
||||
|
||||
// Constructor
|
||||
constructor(serializedSlateOutputOrFeatures, slateOrCommit, proof) {
|
||||
|
||||
// Reset
|
||||
this.reset();
|
||||
|
||||
// Check if a binary serialized slate output is provided
|
||||
if(serializedSlateOutputOrFeatures instanceof BitReader === true) {
|
||||
|
||||
// Get serialized slate output
|
||||
var serializedSlateOutput = serializedSlateOutputOrFeatures;
|
||||
|
||||
// Get slate
|
||||
var slate = slateOrCommit;
|
||||
|
||||
// Unserialize the serialized slate output
|
||||
this.unserialize(serializedSlateOutput, slate);
|
||||
}
|
||||
|
||||
// Otherwise check if a serialized slate output is provided
|
||||
else if(Object.isObject(serializedSlateOutputOrFeatures) === true) {
|
||||
|
||||
// Get serialized slate output
|
||||
var serializedSlateOutput = serializedSlateOutputOrFeatures;
|
||||
|
||||
// Get slate
|
||||
var slate = slateOrCommit;
|
||||
|
||||
// Unserialize the serialized slate output
|
||||
this.unserialize(serializedSlateOutput, slate);
|
||||
}
|
||||
|
||||
// Otherwise check if arguments are provided
|
||||
else if(typeof serializedSlateOutputOrFeatures === "number") {
|
||||
|
||||
// Get features
|
||||
var features = serializedSlateOutputOrFeatures;
|
||||
|
||||
// Get Commit
|
||||
var commit = slateOrCommit;
|
||||
|
||||
// Set features to provided features
|
||||
this.features = features;
|
||||
|
||||
// Set commit to provided commit
|
||||
this.commit = commit;
|
||||
|
||||
// Set proof to provided proof
|
||||
this.proof = proof;
|
||||
|
||||
// Check if proof failed to be verified
|
||||
if(this.verifyProof() === false) {
|
||||
|
||||
// Throw error
|
||||
throw "Unsupported output.";
|
||||
}
|
||||
}
|
||||
|
||||
// Otherwise
|
||||
else {
|
||||
|
||||
// Throw error
|
||||
throw "Unsupported output.";
|
||||
}
|
||||
}
|
||||
|
||||
// Serialize
|
||||
serialize(slateOrVersion, bitWriter) {
|
||||
|
||||
// Get slate version
|
||||
var slateVersion = (slateOrVersion instanceof Slate === true) ? slateOrVersion.getVersion() : slateOrVersion;
|
||||
|
||||
// Check slate's version
|
||||
switch((slateVersion instanceof BigNumber === true) ? slateVersion.toFixed() : slateVersion) {
|
||||
|
||||
// Version two and three
|
||||
case Slate.VERSION_TWO.toFixed():
|
||||
case Slate.VERSION_THREE.toFixed():
|
||||
|
||||
// Return serialized slate output
|
||||
return {
|
||||
|
||||
// Features
|
||||
"features": SlateOutput.featuresToText(this.getFeatures()),
|
||||
|
||||
// Commit
|
||||
"commit": Common.toHexString(this.getCommit()),
|
||||
|
||||
// Proof
|
||||
"proof": Common.toHexString(this.getProof())
|
||||
};
|
||||
|
||||
// Version Slatepack
|
||||
case Slate.VERSION_SLATEPACK:
|
||||
|
||||
// Try
|
||||
try {
|
||||
|
||||
// Write commit
|
||||
bitWriter.setBytes(this.getCommit());
|
||||
|
||||
// Check if proof is too long
|
||||
if(this.getProof()["length"] >= Math.pow(2, SlateOutput.COMPACT_PROOF_LENGTH_LENGTH)) {
|
||||
|
||||
// Throw error
|
||||
throw "Proof is too long.";
|
||||
}
|
||||
|
||||
// Write proof length
|
||||
bitWriter.setBits(this.getProof()["length"], SlateOutput.COMPACT_PROOF_LENGTH_LENGTH);
|
||||
|
||||
// Write proof
|
||||
bitWriter.setBytes(this.getProof());
|
||||
}
|
||||
|
||||
// Catch errors
|
||||
catch(error) {
|
||||
|
||||
// Throw error
|
||||
throw "Unsupported output.";
|
||||
}
|
||||
|
||||
// Break
|
||||
break;
|
||||
|
||||
// Version four
|
||||
case Slate.VERSION_FOUR.toFixed():
|
||||
|
||||
// Check if serializing slate output as binary
|
||||
if(typeof bitWriter !== "undefined") {
|
||||
|
||||
// Try
|
||||
try {
|
||||
|
||||
// Write features
|
||||
bitWriter.setBytes([this.getFeatures()]);
|
||||
|
||||
// Write commit
|
||||
bitWriter.setBytes(this.getCommit());
|
||||
|
||||
// Write proof length
|
||||
bitWriter.setBytes((new BigNumber(this.getProof()["length"])).toBytes(BigNumber.BIG_ENDIAN, Common.BYTES_IN_A_UINT64));
|
||||
|
||||
// Write proof
|
||||
bitWriter.setBytes(this.getProof());
|
||||
}
|
||||
|
||||
// Catch errors
|
||||
catch(error) {
|
||||
|
||||
// Throw error
|
||||
throw "Unsupported output.";
|
||||
}
|
||||
}
|
||||
|
||||
// Otherwise
|
||||
else {
|
||||
|
||||
// Create serialized slate output
|
||||
var serializedSlateOutput = {
|
||||
|
||||
// Commit
|
||||
"c": Common.toHexString(this.getCommit()),
|
||||
|
||||
// Proof
|
||||
"p": Common.toHexString(this.getProof())
|
||||
};
|
||||
|
||||
// Check if not plain
|
||||
if(this.isPlain() === false) {
|
||||
|
||||
// Set serialized slate output's features
|
||||
serializedSlateOutput["f"] = this.getFeatures();
|
||||
}
|
||||
|
||||
// Return serialized slate output
|
||||
return serializedSlateOutput;
|
||||
}
|
||||
|
||||
// Break
|
||||
break;
|
||||
|
||||
// Default
|
||||
default:
|
||||
|
||||
// Throw error
|
||||
throw "Unsupported slate version.";
|
||||
}
|
||||
}
|
||||
|
||||
// Get transaction
|
||||
getTransaction() {
|
||||
|
||||
// Return transaction
|
||||
return {
|
||||
|
||||
// Features
|
||||
"features": SlateOutput.featuresToText(this.getFeatures()),
|
||||
|
||||
// Commit
|
||||
"commit": Common.toHexString(this.getCommit()),
|
||||
|
||||
// Proof
|
||||
"proof": Common.toHexString(this.getProof())
|
||||
};
|
||||
}
|
||||
|
||||
// Get features
|
||||
getFeatures() {
|
||||
|
||||
// Return features
|
||||
return this.features;
|
||||
}
|
||||
|
||||
// Get commit
|
||||
getCommit() {
|
||||
|
||||
// Return commit
|
||||
return this.commit;
|
||||
}
|
||||
|
||||
// Get proof
|
||||
getProof() {
|
||||
|
||||
// Return proof
|
||||
return this.proof;
|
||||
}
|
||||
|
||||
// Is plain
|
||||
isPlain() {
|
||||
|
||||
// Return if features is plain
|
||||
return this.getFeatures() === SlateOutput.PLAIN_FEATURES;
|
||||
}
|
||||
|
||||
// Is coinbase
|
||||
isCoinbase() {
|
||||
|
||||
// Return if features is coinbase
|
||||
return this.getFeatures() === SlateOutput.COINBASE_FEATURES;
|
||||
}
|
||||
|
||||
// Get hash
|
||||
getHash() {
|
||||
|
||||
// Return hash
|
||||
return new Hash([
|
||||
|
||||
// Features
|
||||
new Uint8Array([this.getFeatures()]),
|
||||
|
||||
// Commit
|
||||
this.getCommit()
|
||||
]);
|
||||
}
|
||||
|
||||
// Is equal to
|
||||
isEqualTo(slateOutput) {
|
||||
|
||||
// Check if features aren't equal
|
||||
if(this.getFeatures() !== slateOutput.getFeatures())
|
||||
|
||||
// Return false
|
||||
return false;
|
||||
|
||||
// Check if commits aren't equal
|
||||
if(Common.arraysAreEqual(this.getCommit(), slateOutput.getCommit()) === false)
|
||||
|
||||
// Return false
|
||||
return false;
|
||||
|
||||
// Check if proofs aren't equal
|
||||
if(Common.arraysAreEqual(this.getProof(), slateOutput.getProof()) === false)
|
||||
|
||||
// Return false
|
||||
return false;
|
||||
|
||||
// Return true
|
||||
return true;
|
||||
}
|
||||
|
||||
// Private
|
||||
|
||||
// Reset
|
||||
reset() {
|
||||
|
||||
// Set features to plain features
|
||||
this.features = SlateOutput.PLAIN_FEATURES;
|
||||
}
|
||||
|
||||
// Unserialize
|
||||
unserialize(serializedSlateOutput, slate) {
|
||||
|
||||
// Check slate's version
|
||||
switch((slate.getVersion() instanceof BigNumber === true) ? slate.getVersion().toFixed() : slate.getVersion()) {
|
||||
|
||||
// Version two and three
|
||||
case Slate.VERSION_TWO.toFixed():
|
||||
case Slate.VERSION_THREE.toFixed():
|
||||
|
||||
// Check if serialized slate output's features isn't supported
|
||||
if("features" in serializedSlateOutput === false || SlateOutput.textToFeatures(serializedSlateOutput["features"]) === SlateOutput.UNSUPPORTED_FEATURES || SlateOutput.textToFeatures(serializedSlateOutput["features"]) === SlateOutput.COINBASE_FEATURES) {
|
||||
|
||||
// Throw error
|
||||
throw "Unsupported output.";
|
||||
}
|
||||
|
||||
// Set features to serialized slate output's features
|
||||
this.features = SlateOutput.textToFeatures(serializedSlateOutput["features"]);
|
||||
|
||||
// Check if serialized slate output's commit isn't supported
|
||||
if("commit" in serializedSlateOutput === false || Common.isHexString(serializedSlateOutput["commit"]) === false || Common.hexStringLength(serializedSlateOutput["commit"]) !== Crypto.COMMIT_LENGTH || Secp256k1Zkp.isValidCommit(Common.fromHexString(serializedSlateOutput["commit"])) !== true) {
|
||||
|
||||
// Throw error
|
||||
throw "Unsupported output.";
|
||||
}
|
||||
|
||||
// Set commit to serialized slate output's commit
|
||||
this.commit = Common.fromHexString(serializedSlateOutput["commit"]);
|
||||
|
||||
// Check if serialized slate output's proof isn't supported
|
||||
if("proof" in serializedSlateOutput === false || Common.isHexString(serializedSlateOutput["proof"]) === false || Common.hexStringLength(serializedSlateOutput["proof"]) !== Crypto.PROOF_LENGTH) {
|
||||
|
||||
// Throw error
|
||||
throw "Unsupported output.";
|
||||
}
|
||||
|
||||
// Set proof to serialized slate output's proof
|
||||
this.proof = Common.fromHexString(serializedSlateOutput["proof"]);
|
||||
|
||||
// Break
|
||||
break;
|
||||
|
||||
// Version Slatepack
|
||||
case Slate.VERSION_SLATEPACK:
|
||||
|
||||
// Get bit reader
|
||||
var bitReader = serializedSlateOutput;
|
||||
|
||||
// Try
|
||||
try {
|
||||
|
||||
// Set commit to serialized slate output's commit
|
||||
this.commit = bitReader.getBytes(Crypto.COMMIT_LENGTH);
|
||||
|
||||
// Check if commit is invalid
|
||||
if(Secp256k1Zkp.isValidCommit(this.getCommit()) !== true) {
|
||||
|
||||
// Throw error
|
||||
throw "Unsupported output.";
|
||||
}
|
||||
|
||||
// Get serialized slate output's proof length
|
||||
var proofLength = bitReader.getBits(SlateOutput.COMPACT_PROOF_LENGTH_LENGTH);
|
||||
|
||||
// Check if serialized slate output's proof length isn't supported
|
||||
if(proofLength !== Crypto.PROOF_LENGTH) {
|
||||
|
||||
// Throw error
|
||||
throw "Unsupported output.";
|
||||
}
|
||||
|
||||
// Set proof to serialized slate output's proof
|
||||
this.proof = bitReader.getBytes(proofLength);
|
||||
}
|
||||
|
||||
// Catch errors
|
||||
catch(error) {
|
||||
|
||||
// Throw error
|
||||
throw "Unsupported output.";
|
||||
}
|
||||
|
||||
// Break
|
||||
break;
|
||||
|
||||
// Version four
|
||||
case Slate.VERSION_FOUR.toFixed():
|
||||
|
||||
// Check if serialized slate output is binary
|
||||
if(serializedSlateOutput instanceof BitReader === true) {
|
||||
|
||||
// Get bit reader
|
||||
var bitReader = serializedSlateOutput;
|
||||
|
||||
// Try
|
||||
try {
|
||||
|
||||
// Set features to serialized slate output's features
|
||||
this.features = bitReader.getBytes(1)[0];
|
||||
|
||||
// Check if serialized slate output's features isn't supported
|
||||
if(this.getFeatures() !== SlateOutput.PLAIN_FEATURES) {
|
||||
|
||||
// Throw error
|
||||
throw "Unsupported output.";
|
||||
}
|
||||
|
||||
// Set commit to serialized slate output's commit
|
||||
this.commit = bitReader.getBytes(Crypto.COMMIT_LENGTH);
|
||||
|
||||
// Check if serialized slate output's commit isn't supported
|
||||
if(Secp256k1Zkp.isValidCommit(this.getCommit()) !== true) {
|
||||
|
||||
// Throw error
|
||||
throw "Unsupported output.";
|
||||
}
|
||||
|
||||
// Get serialized slate output's proof length
|
||||
var proofLength = new BigNumber(Common.HEX_PREFIX + Common.toHexString(bitReader.getBytes(Common.BYTES_IN_A_UINT64)));
|
||||
|
||||
// Check if serialized slate output's proof length is invalid
|
||||
if(proofLength.isEqualTo(Crypto.PROOF_LENGTH) === false) {
|
||||
|
||||
// Throw error
|
||||
throw "Unsupported output.";
|
||||
}
|
||||
|
||||
// Set proof to serialized slate output's proof
|
||||
this.proof = bitReader.getBytes(proofLength.toNumber());
|
||||
}
|
||||
|
||||
// Catch errors
|
||||
catch(error) {
|
||||
|
||||
// Throw error
|
||||
throw "Unsupported output.";
|
||||
}
|
||||
}
|
||||
|
||||
// Otherwise
|
||||
else {
|
||||
|
||||
// Check if serialized slate output's features isn't supported
|
||||
if("f" in serializedSlateOutput === true && ((Common.isNumberString(serializedSlateOutput["f"]) === false && serializedSlateOutput["f"] instanceof BigNumber === false) || (new BigNumber(serializedSlateOutput["f"])).isEqualTo(SlateOutput.PLAIN_FEATURES) === false)) {
|
||||
|
||||
// Throw error
|
||||
throw "Unsupported output.";
|
||||
}
|
||||
|
||||
// Set features to serialized slate output's features
|
||||
this.features = ("f" in serializedSlateOutput === true) ? (new BigNumber(serializedSlateOutput["f"])).toNumber() : SlateOutput.PLAIN_FEATURES;
|
||||
|
||||
// Check if serialized slate output's commit isn't supported
|
||||
if("c" in serializedSlateOutput === false || Common.isHexString(serializedSlateOutput["c"]) === false || Common.hexStringLength(serializedSlateOutput["c"]) !== Crypto.COMMIT_LENGTH || Secp256k1Zkp.isValidCommit(Common.fromHexString(serializedSlateOutput["c"])) !== true) {
|
||||
|
||||
// Throw error
|
||||
throw "Unsupported output.";
|
||||
}
|
||||
|
||||
// Set commit to serialized slate output's commit
|
||||
this.commit = Common.fromHexString(serializedSlateOutput["c"]);
|
||||
|
||||
// Check if serialized slate output's proof isn't supported
|
||||
if("p" in serializedSlateOutput === false || Common.isHexString(serializedSlateOutput["p"]) === false || Common.hexStringLength(serializedSlateOutput["p"]) !== Crypto.PROOF_LENGTH) {
|
||||
|
||||
// Throw error
|
||||
throw "Unsupported output.";
|
||||
}
|
||||
|
||||
// Set proof to serialized slate output's proof
|
||||
this.proof = Common.fromHexString(serializedSlateOutput["p"]);
|
||||
}
|
||||
|
||||
// Break
|
||||
break;
|
||||
|
||||
// Default
|
||||
default:
|
||||
|
||||
// Throw error
|
||||
throw "Unsupported output.";
|
||||
}
|
||||
|
||||
// Check if proof failed to be verified
|
||||
if(this.verifyProof() === false) {
|
||||
|
||||
// Throw error
|
||||
throw "Unsupported output.";
|
||||
}
|
||||
}
|
||||
|
||||
// Verify proof
|
||||
verifyProof() {
|
||||
|
||||
// Check if proof verifies the commit
|
||||
return Secp256k1Zkp.verifyBulletproof(this.getProof(), this.getCommit(), new Uint8Array([])) === true;
|
||||
}
|
||||
|
||||
// Features to text
|
||||
static featuresToText(features) {
|
||||
|
||||
// Check features
|
||||
switch(features) {
|
||||
|
||||
// Plain features
|
||||
case SlateOutput.PLAIN_FEATURES:
|
||||
|
||||
// Return plain text
|
||||
return "Plain";
|
||||
|
||||
// Coinbase features
|
||||
case SlateOutput.COINBASE_FEATURES:
|
||||
|
||||
// Return coinbase text
|
||||
return "Coinbase";
|
||||
|
||||
// Default
|
||||
default:
|
||||
|
||||
// Return unsupported features
|
||||
return SlateOutput.UNSUPPORTED_FEATURES;
|
||||
}
|
||||
}
|
||||
|
||||
// Text to feature
|
||||
static textToFeatures(text) {
|
||||
|
||||
// Check text
|
||||
switch(text) {
|
||||
|
||||
// Plain text
|
||||
case "Plain":
|
||||
|
||||
// Return plain features
|
||||
return SlateOutput.PLAIN_FEATURES;
|
||||
|
||||
// Coinbase text
|
||||
case "Coinbase":
|
||||
|
||||
// Return coinbase features
|
||||
return SlateOutput.COINBASE_FEATURES;
|
||||
|
||||
// Default
|
||||
default:
|
||||
|
||||
// Return unsupported features
|
||||
return SlateOutput.UNSUPPORTED_FEATURES;
|
||||
}
|
||||
}
|
||||
|
||||
// Plain features
|
||||
static get PLAIN_FEATURES() {
|
||||
|
||||
// Return plain features
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Coinbase features
|
||||
static get COINBASE_FEATURES() {
|
||||
|
||||
// Return coinbase features
|
||||
return SlateOutput.PLAIN_FEATURES + 1;
|
||||
}
|
||||
|
||||
// Unsupported features
|
||||
static get UNSUPPORTED_FEATURES() {
|
||||
|
||||
// Return unsupported features
|
||||
return SlateOutput.COINBASE_FEATURES + 1;
|
||||
}
|
||||
|
||||
// Compact proof length length
|
||||
static get COMPACT_PROOF_LENGTH_LENGTH() {
|
||||
|
||||
// Return compact proof length length
|
||||
return 10;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Main function
|
||||
|
||||
// Set global object's slate output
|
||||
globalThis["SlateOutput"] = SlateOutput;
|
Reference in New Issue
Block a user