Settings

Blockchain
Network
Unit
Language
Theme
Sound New Block

Transaction

f5620947802fa8f977e0c56dded5e6d3dab575967e0d9b9459b6c8d116eb74cc
Timestamp (utc)
2020-09-21 21:35:42
Fee Paid
0.00005309 BSV
(
0.00670070 BSV
-
0.00664761 BSV
)
Fee Rate
500 sat/KB
Version
1
Confirmations
340,577
Size Stats
10,616 B

4 Outputs

Total Output:
0.00664761 BSV
  • jrunM]({"in":0,"ref":["native://Jig"],"out":["4d5c4daf07af239f80d4a987db016ae1dd371dab379fdc2c137f8e1f2d796f9b","2db315449d20dcc41488a245517866c441ba2d86488331d61d033a1f479a80ea"],"del":[],"cre":["mge9PJwnAno5Z3pehdqqUF7CEekHmFvfYu","mge9PJwnAno5Z3pehdqqUF7CEekHmFvfYu"],"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 } // Case: Mint\n\n\n if (caller === this.constructor) {\n // call from static function of this class\n this._checkAmount(caller.mintAmount);\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); // should already be checked in mint() but better twice for security\n\n\n this.timestamp = caller.mint_timestamp;\n this.oldest_mint_count = this.constructor.nonce;\n console.log(function_id + \" mint(): this.oldest_mint_count = \" + this.oldest_mint_count);\n return;\n } // Case: Send\n\n\n if (caller && caller.constructor === this.constructor) {\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.oldest_mint_count = caller.send_oldest_mint_count;\n this.action = \"send\";\n return;\n } // Case: Combine // when caller==null => called by the user\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 }\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 _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 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\n this._checkTimestamp(timestamp);\n\n if (timestamp <= this.timestamp) throw function_id + \"send(): 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.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 }\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');\n if (!Number.isInteger(amount)) throw new Error(function_id + 'amount must be an integer');\n if (amount <= 0) throw new Error(function_id + 'amount must be positive');\n if (amount > Number.MAX_SAFE_INTEGER) throw new Error(function_id + 'amount too large');\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 expect(number).toBeNumber(function_id + \"not a number : \" + number);\n expect(number).toBeGreaterThan(0, function_id + \"number must be positive : \" + number);\n expect(number).toBeLessThanOrEqualTo(Number.MAX_SAFE_INTEGER, function_id + \"number too large : \" + number);\n }\n\n _checkTimestamp(timestamp) {\n const function_id = this.classname + \": _checkTimestamp: \";\n\n this._checkNum(timestamp); // applies as well to timestamp\n\n\n expect(timestamp).toBeInteger(function_id + ': timestamp must be an integer : ' + timestamp);\n expect(timestamp).toBeGreaterThan(1593026831, function_id + ': timestamp must be older than 1593026831 : ' + timestamp);\n }\n\n}",{"decimals":8,"deps":{"expect":{"$jig":2},"Jig":{"$jig":0}},"icon":{"emoji":null},"sealed":false,"supply":0,"symbol":null},"function expect(t){let e=!1;const n=t=>{if(\"object\"!=typeof t||!t)return t;try{return JSON.stringify(t)}catch(e){return t.toString()}};function r(r,o,i){if(e?r:!r)throw new Error(i||`expected value${e?\" not\":\"\"} to be ${o} but was ${n(t)}`)}function o(t,e){if(t===e)return!0;if(typeof t!=typeof e)return!1;if(\"object\"!=typeof t)return!1;if(null===t||null===e)return!1;if(Object.getPrototypeOf(t)!==Object.getPrototypeOf(e))return!1;if(Object.keys(t).length!==Object.keys(e).length)return!1;if(!Object.keys(t).every(n=>o(t[n],e[n])))return!1;if(t instanceof Set){if(t.size!==e.size)return!1;if(!o(Array.from(t.entries()),Array.from(e.entries())))return!1}if(t instanceof Map){if(t.size!==e.size)return!1;if(!o(Array.from(t.entries()),Array.from(e.entries())))return!1}return!0}function i(t,e){if(\"function\"!=typeof t)return!1;if(\"function\"!=typeof e)return!1;for(;t;)if((t=Object.getPrototypeOf(t))===e)return!0;return!1}return{get not(){return e=!e,this},toBe:(e,o)=>r(t===e,\"\"+n(e),o),toEqual:(e,i)=>r(o(t,e),\"equal to \"+n(e),i),toBeInstanceOf:(e,n)=>r(t&&t instanceof e,\"an instance of \"+(e&&e.name),n),toBeDefined:e=>r(void 0!==t,\"defined\",e),toBeNull:e=>r(null===t,\"null\",e),toBeNumber:e=>r(\"number\"==typeof t,\"a number\",e),toBeInteger:e=>r(Number.isInteger(t),\"an integer\",e),toBeLessThan:(e,n)=>r(t<e&&\"number\"==typeof t&&\"number\"==typeof e,\"less than \"+e,n),toBeLessThanOrEqualTo:(e,n)=>r(t<=e&&\"number\"==typeof t&&\"number\"==typeof e,\"less than or equal to \"+e,n),toBeGreaterThan:(e,n)=>r(t>e&&\"number\"==typeof t&&\"number\"==typeof e,\"greater than \"+e,n),toBeGreaterThanOrEqualTo:(e,n)=>r(t>=e&&\"number\"==typeof t&&\"number\"==typeof e,\"greater than or equal to \"+e,n),toBeBoolean:e=>r(\"boolean\"==typeof t,\"a boolean\",e),toBeString:e=>r(\"string\"==typeof t,\"a string\",e),toBeObject:e=>r(t&&\"object\"==typeof t,\"an object\",e),toBeArray:e=>r(Array.isArray(t),\"an array\",e),toBeSet:e=>r(t instanceof Set,\"a set\",e),toBeMap:e=>r(t instanceof Map,\"a map\",e),toBeUint8Array:e=>r(t instanceof Uint8Array,\"a uint8array\",e),toBeClass:e=>r(\"function\"==typeof t&&t.toString().startsWith(\"class\"),\"a class\",e),toBeFunction:e=>r(\"function\"==typeof t&&!t.toString().startsWith(\"class\"),\"a function\",e),toBeJigClass:e=>r(\"function\"==typeof t&&t.toString().startsWith(\"class\")&&i(t,Jig),\"a jig class\",e),toExtendFrom:(e,n)=>r(i(t,e),\"an extension of \"+(e&&e.name),n)}}",{"deps":{"Jig":{"$dup":["1","deps","Jig"]}}}]}]}
    https://whatsonchain.com/tx/f5620947802fa8f977e0c56dded5e6d3dab575967e0d9b9459b6c8d116eb74cc