Settings

Blockchain
Network
Unit
Language
Theme
Sound New Block

Transaction

abaadcdd437a38025afda08bae3f800cd777326e83bf712f4351f8b713f43ca9
Timestamp (utc)
2020-09-22 15:30:59
Fee Paid
0.00004859 BSV
(
0.00590990 BSV
-
0.00586131 BSV
)
Fee Rate
500.1 sat/KB
Version
1
Confirmations
346,119
Size Stats
9,716 B

3 Outputs

Total Output:
0.00586131 BSV
  • jrunMû${"in":0,"ref":["native://Jig","4cdc49ee0e81a2c677d6bfa6d7c05f15c779484eba79daa38335056ccc42e8d5_o2"],"out":["18425ec9c6a0dd25057526b2de7b6cdc9fb54e0a134518cf30db5df7b4760f1f"],"del":[],"cre":["mzcwZjsbBHgy4rxfULW4mFXVRb6N9pkLV4"],"exec":[{"op":"DEPLOY","data":["class TokenContract extends Jig {\n //\n // with RUN 0.6 preview version \n //\n init(...tokens) {\n this.classname = \"TokenContract: \";\n const function_id = this.classname + \"init(): \"; // The base Token class cannot be created on its own\n\n if (Object.getPrototypeOf(this.constructor) === Jig) {\n throw new Error(function_id + 'must be extended');\n }\n\n if (caller == null) throw function_id + \"cannot be called directly by user\";\n\n if (caller === this.constructor) {\n // call from static function of this class\n if (caller.combine_timestamp) {\n // Case: Combine\n const function_id_combine = function_id + \" combine : \";\n\n try {\n this._checkTimestamp(caller.combine_timestamp); // important to check here\n\n\n if (!Array.isArray(tokens) || tokens.length < 2) {\n throw new Error(function_id_combine + \"Invalid tokens to combine\");\n } // Each token to combine must all be of this type\n\n\n if (tokens.some(token => token.constructor !== this.constructor)) {\n throw new Error(function_id_combine + \"Cannot combine different token classes\");\n } // Check for duplicate tokens in the array\n\n\n const countOf = token => tokens.reduce((count, next) => next === token ? count + 1 : count, 0);\n\n if (tokens.some(token => countOf(token) > 1)) throw new Error(function_id_combine + \"Cannot combine duplicate tokens\"); // Destroy each token, absorbing it into this one\n\n this.amount = 0;\n var oldest_mint_count = null;\n tokens.forEach(token => {\n this.amount += token.amount;\n if (oldest_mint_count == null || token.oldest_mint_count < oldest_mint_count) oldest_mint_count = token.oldest_mint_count;\n token.destroy(); // this ensures only the owner of the tokens can combine because this needs to be signed by the owner of tokens to combine\n });\n this.action = \"combine\";\n this.oldest_mint_count = oldest_mint_count; // Make sure our new amount is within safe range\n\n this._checkAmount(this.amount);\n } catch (e) {\n throw function_id_combine + e;\n }\n\n return;\n } else if (caller.mint_timestamp) {\n // Case: Mint\n const function_id_mint = function_id + \" mint : \";\n\n try {\n this._checkAmount(caller.mintAmount); // important to check here\n\n\n this.amount = caller.mintAmount;\n this.action = \"mint\";\n console.log(function_id_mint + \" \\n caller.mintAmount=\" + caller.mintAmount + \"\\n caller.mint_timestamp=\" + caller.mint_timestamp + \"\\n caller=\", caller, \"\\n \" + caller);\n\n this._checkTimestamp(caller.mint_timestamp); // important to check here\n\n\n this.timestamp = caller.mint_timestamp;\n this.oldest_mint_count = this.constructor.nonce; // TODO see if we should add +1 here ?\n\n console.log(function_id_mint + \" this.oldest_mint_count = \" + this.oldest_mint_count);\n } catch (e) {\n throw function_id_mint + e;\n }\n\n return;\n }\n\n return;\n } // Case: Send\n\n\n if (caller && caller.constructor === this.constructor) {\n // call from a non-static function of this class\n const function_id_send = function_id + \" send : \";\n\n try {\n this._checkAmount(caller.sendAmount);\n\n this.amount = caller.sendAmount;\n this.owner = caller.sendOwner;\n\n this._checkTimestamp(caller.send_timestamp); // very important to check here because we can't do it in: static send()\n\n\n this.timestamp = caller.send_timestamp;\n this.sender = caller.sendSender;\n this.oldest_mint_count = caller.send_oldest_mint_count;\n this.action = \"send\";\n } catch (e) {\n throw function_id_send + e;\n }\n\n return;\n }\n }\n\n static mint(amount, timestamp) {\n const function_id = this.name + (this.tokenName ? \" (\" + this.tokenName + \")\" : \"\") + \": mint(): \";\n this.mintAmount = amount; // we cannot call _checkTimestamp in a static function because it's private but make sure to check in the init()\n\n this.mint_timestamp = timestamp;\n const token = new this();\n delete this.mintAmount;\n this.supply += amount;\n delete this.mint_timestamp;\n return token;\n }\n\n static combine(timestamp, ...tokens) {\n const function_id = this.name + (this.tokenName ? \" (\" + this.tokenName + \")\" : \"\") + \": combine(): \"; // we cannot call _checkTimestamp in a static function because it's private but make sure to check in the init()\n\n this.combine_timestamp = timestamp;\n const token = new this(tokens);\n delete this.combine_timestamp;\n return token;\n }\n\n static _destroy_reduceSupplyIfAdmin(amount) {\n // since this function is private it can only be called from this class, so no need for if(caller instanceof this) {}\n // working if you call it from destroy() with this.constructor.reduceSupply(this.amount)\n const function_id = this.name + (this.tokenName ? \" (\" + this.tokenName + \")\" : \"\") + \": _reduceSupply(): \";\n console.log(function_id + \" caller = \\n \" + caller + \"\\n \", caller);\n this.supply -= amount; // this can only be done by the class' owner so it enforces that only the admin can call this function\n } // redefining the one from extended Jig class\n\n\n destroy() {\n // BEWARE YOU SHOULD RATHER USE BURN TO ATTACH A PRECISE TIMESTAMP TO THIS ACTION\n const function_id = this.classname + \"destroy(): \"; // beware destroy applies to all coins so it doesn't decrease supply because that would require the class's owner access\n // so you should use BURN to burn coins & reduce supply at the same time\n // we could also check in destroy() if the caller is the class owner to reduce supply in that case\n\n console.log(function_id + \" caller : \" + caller + \"\\n\", caller);\n\n if (caller == null && this.owner == this.constructor.owner) {\n // caller is user and is the owner of the token's class\n // user called destroy(). we are not combining or sending tokens\n console.log(function_id + \" destroy from user detected : try to reduce token supply\");\n\n this.constructor._destroy_reduceSupplyIfAdmin(this.amount);\n }\n\n super.destroy();\n this.action = \"burn\";\n this.amount = 0;\n }\n\n send(to, timestamp, amount = this.amount) {\n const function_id = this.classname + \"send(): \";\n\n try {\n this._checkAmount(amount);\n\n if (amount > this.amount) {\n throw new Error(function_id + 'Not enough funds');\n }\n\n this.sendAmount = amount;\n this.sendOwner = to;\n this.sendSender = this.owner;\n\n this._checkTimestamp(timestamp);\n\n if (timestamp <= this.timestamp) throw function_id + \"you cannot send with a timestamp that is before the coin to send's timestamp: \" + timestamp + \" <= \" + this.timestamp;\n this.send_timestamp = timestamp;\n this.send_oldest_mint_count = this.oldest_mint_count;\n const sent = new this.constructor();\n delete this.sendAmount;\n delete this.sendOwner;\n delete this.sendSender;\n delete this.send_timestamp;\n delete this.send_oldest_mint_count;\n\n if (this.amount === amount) {\n this.destroy();\n } else {\n this.amount -= amount;\n this.action = \"change\";\n }\n\n return sent;\n } catch (e) {\n throw function_id + e;\n }\n }\n\n _checkAmount(amount) {\n const function_id = this.classname + \": _checkAmount(): \";\n if (typeof amount !== 'number') throw new Error(function_id + 'amount is not a number : ' + amount); // using throw gives better error trace than expect()\n\n if (!Number.isInteger(amount)) throw new Error(function_id + 'amount must be an integer : ' + amount);\n if (amount <= 0) throw new Error(function_id + 'amount must be positive : ' + amount);\n if (amount > Number.MAX_SAFE_INTEGER) throw new Error(function_id + 'amount too large : ' + amount);\n }\n\n _checkNum(number) {\n // check that number is a positive number (but can be float)\n const function_id = this.classname + \": _checkNum(): \";\n if (typeof number !== 'number') throw function_id + 'number is not a number : ' + number;\n if (!(number > 0)) throw new Error(function_id + 'number must be positive : ' + number);\n if (number > Number.MAX_SAFE_INTEGER) throw new Error(function_id + 'number too large : ' + number);\n }\n\n _checkTimestamp(timestamp) {\n const function_id = this.classname + \": _checkTimestamp(): \";\n\n try {\n this._checkAmount(timestamp); // applies as well to timestamp\n\n } catch (e) {\n throw function_id + e;\n }\n\n if (!(timestamp > 1600729677)) throw function_id + ': timestamp must be older than 1600729677 : ' + timestamp;\n }\n\n}",{"decimals":8,"deps":{"expect":{"$jig":1},"Jig":{"$jig":0}},"icon":{"emoji":null},"sealed":false,"supply":0,"symbol":null}]}]}
    https://whatsonchain.com/tx/abaadcdd437a38025afda08bae3f800cd777326e83bf712f4351f8b713f43ca9