Settings

Blockchain
Network
Unit
Language
Theme
Sound New Block

Transaction

9fb69456d438cfe1f22d3eb4aa66d5ad8c8a34c0d0aaa6e9d10ea62bc95702f2
Timestamp (utc)
2020-10-14 16:02:34
Fee Paid
0.00002829 BSV
(
0.00057415 BSV
-
0.00054586 BSV
)
Fee Rate
500.1 sat/KB
Version
1
Confirmations
336,994
Size Stats
5,656 B

3 Outputs

Total Output:
0.00054586 BSV
  • jrun b1b605103eM{"in":0,"ref":["native://Jig","780731b97e5f646c5eafd6e8f81eed3f13bac1f84984a2e1055de0e9d2891e48_o2","780731b97e5f646c5eafd6e8f81eed3f13bac1f84984a2e1055de0e9d2891e48_o3"],"out":["ea473b8d600c11fe60a4ee6731af6ee11f7160d77bd20f31eb0aa95d4947af8e"],"del":[],"cre":["muC8yXMk5dV1gSpXWVHUcE4Cp3cCyHGtMT"],"exec":[{"op":"DEPLOY","data":["class Blacklist extends Jig {\r\n \r\n init(timestamp) {\r\n this.classname = \"Blacklist: \"\r\n const function_id = this.classname+\"init(): \"\r\n\r\n if(!timestamp) throw SmartContractError(401, function_id+\"timestamp missing: \"+timestamp)\r\n this._checkTimestamp(timestamp)\r\n\r\n this.list = []\r\n this.timestamps = []\r\n this.list_action_numbers = []\r\n\r\n this.action=\"init\"\r\n }\r\n\r\n linkAdminCounter(admincounter){\r\n /* this should be done right after creation, we need it separate from init() because we first need to link multlist to the tokencontract and then the other way */\r\n if(this.admincounter) throw SmartContractError(402, this.classname+\": already an admincounter linked: \"+this.admincounter.origin)\r\n this.admincounter = admincounter\r\n this.action= \"linkAdminCounter\"\r\n }\r\n\r\n blacklist(address, timestamp) {\r\n const function_id = this.classname+\"blacklist(): \"\r\n\r\n // checks\r\n if(!this.admincounter) throw SmartContractError(403, function_id+\" no admincounter contract found, please link one before blacklisting\")\r\n //\r\n\r\n if(this.admincounter.isRevoked()) throw SmartContractError(404, function_id+\"token contract has been revoked (admincounter)\")\r\n if(this.admincounter.isBackedup()) throw SmartContractError(405, function_id+\"token contract has been backedup (admincounter)\")\r\n if(this.admincounter.isFrozen()) throw SmartContractError(406, function_id+\"token contract has been frozen (admincounter)\") // check frozen as last always!\r\n\r\n if(!timestamp) throw SmartContractError(407, function_id+\": publish: timestamp missing: \"+timestamp)\r\n this._checkTimestamp(timestamp)\r\n\r\n if(this.owner != this.constructor.owner) throw SmartContractError(408, function_id+\" Only \"+this.classname+\" owner may manage blacklist\")\r\n if(typeof address != \"string\") throw SmartContractError(409, function_id+' address to blacklist must be a string: '+address)\r\n if(address == this.owner) throw SmartContractError(410, function_id+\" you cannot blacklist your own administration address\")\r\n if(address.length < 26) throw SmartContractError(411, function_id+\" address is too short: \"+address.length)\r\n if(!address.match(\"^[A-Za-z0-9]+$\")) throw SmartContractError(412, function_id+\" wrong character in address: \"+address)\r\n if(this.list.includes(address)) throw SmartContractError(413, function_id+\" address is already in blacklist\")\r\n\r\n // all parameters checks passed\r\n if(!this.admincounter){\r\n throw SmartContractError(414, function_id+\" no admincounter contract found, please link one before publishing\")\r\n }\r\n else {\r\n this.admincounter.auth() //ensures only the tokencontract owner can publish // for run 0.6\r\n this.action_count = this.admincounter.nonce // for run 0.6\r\n }\r\n this.list_action_numbers.push(this.action_count) // as an array for practicality\r\n\r\n this.list.push(address)\r\n this.timestamps.push(timestamp)\r\n this.action=\"blacklist\"\r\n }\r\n // beware allowing remove introduces a security breach if an hacker can unblacklist his address and send some of his tokens to others to taint them\r\n //remove(address){\r\n // expect(address).toBeString(this.classname+': address to blacklist must be a string')\r\n // if(!this.list.has(address)) throw SmartContractError(ADD NUMBER,this.classname+\": address to remove is not in blacklist\") // replace by SmartContractError\r\n // this.list.delete(address)\r\n //}\r\n isBlacklisted(address){\r\n if(this.list.includes(address)) return true\r\n else return false\r\n }\r\n _checkNum (number) { // check that number is a positive number (but can be float)\r\n const function_id = this.classname+\": _checkNum(): \"\r\n if (typeof number !== 'number') throw SmartContractError(415, function_id+'number is not a number : '+number) // throw gives better error trace than expect()\r\n if (!(number > 0)) throw SmartContractError(416, function_id+'number must be positive : '+number)\r\n if (number > Number.MAX_SAFE_INTEGER) throw SmartContractError(417, function_id+'number too large : '+number)\r\n }\r\n _checkTimestamp (timestamp) {\r\n const function_id = this.classname+\": _checkTimestamp(): \"\r\n try {\r\n this._checkNum(timestamp) // applies as well to timestamp\r\n } catch(e) { throw SmartContractError(418, function_id+e) }\r\n if (!Number.isInteger(timestamp)) throw SmartContractError(419, function_id+'timestamp must be an integer : '+timestamp) //necessary because _checkNum doesn't do it\r\n if( !(timestamp > 1600939295117) ) throw SmartContractError(420, function_id+': timestamp must be older than 1600939295117 : '+timestamp) // make sure the timestamp here is in ms!!\r\n }\r\n}",{"deps":{"Jig":{"$jig":0},"SmartContractError":{"$jig":1},"expect":{"$jig":2}},"sealed":true}]}]}
    https://whatsonchain.com/tx/9fb69456d438cfe1f22d3eb4aa66d5ad8c8a34c0d0aaa6e9d10ea62bc95702f2