{"id":16314116,"url":"https://github.com/nomeata/capture-the-ic-token","last_synced_at":"2026-03-18T18:56:15.401Z","repository":{"id":66278887,"uuid":"376325601","full_name":"nomeata/capture-the-ic-token","owner":"nomeata","description":"Hack the canister, get the token","archived":false,"fork":false,"pushed_at":"2023-11-19T21:34:29.000Z","size":18,"stargazers_count":19,"open_issues_count":0,"forks_count":1,"subscribers_count":5,"default_branch":"master","last_synced_at":"2025-04-25T15:07:46.340Z","etag":null,"topics":["internet-computer"],"latest_commit_sha":null,"homepage":"https://fj6bh-taaaa-aaaab-qaacq-cai.raw.ic0.app/","language":"Motoko","has_issues":false,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/nomeata.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2021-06-12T15:36:37.000Z","updated_at":"2023-11-19T21:30:47.000Z","dependencies_parsed_at":"2023-11-19T22:37:01.777Z","dependency_job_id":null,"html_url":"https://github.com/nomeata/capture-the-ic-token","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nomeata%2Fcapture-the-ic-token","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nomeata%2Fcapture-the-ic-token/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nomeata%2Fcapture-the-ic-token/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nomeata%2Fcapture-the-ic-token/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/nomeata","download_url":"https://codeload.github.com/nomeata/capture-the-ic-token/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":250840633,"owners_count":21495909,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["internet-computer"],"created_at":"2024-10-10T21:53:14.199Z","updated_at":"2026-01-24T14:04:17.144Z","avatar_url":"https://github.com/nomeata.png","language":"Motoko","funding_links":[],"categories":[],"sub_categories":[],"readme":"Capture The IC Token\n====================\n\nThis little project implements a canister that will hold on to **0.1 ICP** and\nreveal it to anyone who can guess a secret. The secret is obtained from the\nInternet Computer’s random tape (using the `aaaaa-aa.raw_rand()` call), and\nthen kept in main memory. If you find a way to read from the secret tape, or\nfrom the canister’s main memory you unlock 0.1 ICP.\n\nThe canister is live with canister id [`6b4pv-sqaaa-aaaah-qaava-cai`](https://6b4pv-sqaaa-aaaah-qaava-cai.raw.ic0.app/).\n\nThe ICP is sitting in account [**604336f3b4fbd3f45ef058394acdfb8c8e76ea676d90c6147b22888390d06d42**](https://dashboard.internetcomputer.org/account/604336f3b4fbd3f45ef058394acdfb8c8e76ea676d90c6147b22888390d06d42) owned by principal **dn76p-ld3h7-72osu-zv5tz-ot26n-hag5h-jhc5i-3mgv4-wyu4g-hi4j6-vqe**.\n\nFAQ\n===\n\nWhy?\n----\n\nBecause it seemed like a nice programming puzzle. Also, to demonstrate a few\nfeatures of the Internet Computer, namely\n\n * The random tape\n * Certified data\n * [Canister Signatures]\n * Writing canisters in Motoko\n\n[Canister Signatures]: https://sdk.dfinity.org/docs/interface-spec/index.html#canister-signatures\n\nDid someone hack this already?\n------------------------------\n\nYes! You can check [the\naccount](https://dashboard.internetcomputer.org/account/604336f3b4fbd3f45ef058394acdfb8c8e76ea676d90c6147b22888390d06d42)\nto see the transactions on the reward account, and you can go to\n\u003chttps://6b4pv-sqaaa-aaaah-qaava-cai.raw.ic0.app/\u003e and see that there were\n“Successful calls to set_certified_data”.\n\nI heard canisters cannot hold ICPs. How does this work?\n------------------------------------------------------\n\nIndeed, at the time of writing the ledger will not allow accounts owned by\ncanister ids, so Canisters cannot own ICPs via their canister id (which is a\nprincipal).\n\nBut canisters can also create [Canister Signatures], a “signature scheme” based\non certified variables, and mainly used by identity providers such as\n[Internet Identity]. The canister gives full control to its certified variables\nto anyone who has guessed the secret, and thus those can sign withdrawal\nrequests towards the ledger.\n\n[Internet Identity]: https://github.com/dfinity/internet-identity\n\nI know the secret, how do I get the ICP?\n----------------------------------------\n\nYou still have to do a little bit of coding, which is part of the exercise.\nHere is a rough outline:\n\n * Create a request to transfer the token to your account.\n * Create a hash tree that contains a signature to this request in\n   `/sig//\u003cm\u003e` (note that the seed is empty).\n * Pass the root hash of that tree to `set_certified_data`. To authorize, you\n   have to also pass the hash of the concatenation of _your_ principal (in\n   binary form) and the secret hash.\n * Use `get_certificate` to get the certificate\n * Construct a canister signature from the certificate and your hash tree\n * Submit this to the Internet Computer\n * Profit\n\nIf you like the programming challenge even without finding a bug in the\nInternet Computer, and have implemented a tool for this, feel free to link to\nit here.\n\nAre you really running the code you claim to run?\n-------------------------------------------------\n\nYou can check yourself! See the [blog post about verifying the Internet\nIdentity](https://medium.com/dfinity/verifying-the-internet-identity-code-a-walkthrough-c1dd7a53f883)\nfor a rough outline. I used dfx-0.7.0 (moc-0.6.1) on Linux to build this canister.\n\nWho is the controller of this canister?\n---------------------------------------\n\nNo one. You can check with `dfx canister info` or on [ic.rocks](https://ic.rocks/principal/6b4pv-sqaaa-aaaah-qaava-cai).\n\nIf you see `zrl4w-cqaaa-nocon-troll-eraaa-d5qc` shown as a controller, then you\nare using a tool that does not speak the latest IC protocol. This is a\nplaceholder princpal (note that it says “no controller” in the middle).\n\n\nThe canister reports its cycle balance at\n\u003chttps://6b4pv-sqaaa-aaaah-qaava-cai.raw.ic0.app/\u003e. Feel free to donate a few\ncycles.  If this canister runs out of cycles and gets removed by the system,\nthe ICP prize is lost forever.\n\nWhy does this canister control some canisters?\n----------------------------------------------\n\nBecuase I was given this canister by a colleage who was using this as a wallet\ncanister, but does not use it any more. Guess these controlled canisters are\nnow also orphans.\n\nAre Canister Signaures even supported yet?\n------------------------------------------\n\nThe [Interface Spec] specifies them on all subnets, but the replica, at the\ntime of writing, only accepts them from canisters on the root subnet. This\nrestriction is currently implemented in [these\nlines](https://github.com/dfinity/ic/blob/779549eccfcf61ac702dfc2ee6d76ffdc2db1f7f/rs/certified_vars/src/lib.rs#L94-L96),\nand will be removed soon™. If you indeed manage to get the secret before this\nrestriction is removed, well, be proud of it.\n\nHow did you calculate the principal and account number?\n-------------------------------------------------------\n\nThe principal “owning” the token is derived from a Canister Signature public “key”, with the empty blob as the seed. From that we can calculate the ICP ledger address (with subaccount 0).\n\nI used the code in [`dfinity/ic-hs`](https://github.com/dfinity/ic-hs) for these calculations:\n\n```\n~/dfinity/ic-hs $ cabal repl\n\u003e :set -XOverloadedStrings\n\u003e import Codec.Candid\n\u003e let Right (Principal raw_canister) = parsePrincipal \"6b4pv-sqaaa-aaaah-qaava-cai\"\n\u003e let raw_principal = IC.Id.Forms.mkSelfAuthenticatingId (IC.Crypto.DER.encode IC.Crypto.DER.CanisterSig $ IC.Crypto.CanisterSig.genPublicKey (EntityId raw_canister) \"\")\n\u003e prettyPrincipal (Principal raw_principal)\n\"dn76p-ld3h7-72osu-zv5tz-ot26n-hag5h-jhc5i-3mgv4-wyu4g-hi4j6-vqe\"\n\u003e import qualified Data.ByteString.Lazy as BS\n\u003e let subaccount = BS.replicate 32 0\n\u003e let account_hash = IC.Hash.sha224 (\"\\x0a\" \u003c\u003e \"account-id\" \u003c\u003e raw_principal \u003c\u003e subaccount)\n\u003e import Data.Digest.CRC32\n\u003e let CRC32 checksum = digest (BS.toStrict account_hash)\n\u003e import qualified Data.ByteString.Builder as BS\n\u003e let checkbytes = BS.toLazyByteString (BS.word32BE checksum)\n\u003e import qualified Text.Hex as T\n\u003e T.encodeHex (BS.toStrict (checkbytes \u003c\u003e account_hash))\n\"604336f3b4fbd3f45ef058394acdfb8c8e76ea676d90c6147b22888390d06d42\"\n```\n\nWhat happens if I transfer funds to that account?\n-------------------------------------------------\n\nThey will up the stakes for this treasure hunt, so feel free to! But note that\nvery likely, these tokens would simply be lost.\n\nAlso, should the subnet hosting this canister ever get reset, or Canister Signatures not implemented as planned, the tokens would be lost.\n\nWhat is `fj6bh-taaaa-aaaab-qaacq-cai`?\n--------------------------------------\n\nThe canister at [`fj6bh-taaaa-aaaab-qaacq-cai`](https://fj6bh-taaaa-aaaab-qaacq-cai.raw.ic0.app/) is an earlier attempt at setting up this challenge, but it is buggy buggy version of the challenge. See [commit `112933`](https://github.com/nomeata/capture-the-ic-token/commit/112933eb612c8fb97cd8fb0de0cd1688db00e320) for the changes.\n\nThis means that in order to get the ICP token “owned” by that canister, which sits in [**62c01571c33e6b6d118842e2bc25193d6730f6a05580c64d4438411062f13310**](https://dashboard.internetcomputer.org/account/62c01571c33e6b6d118842e2bc25193d6730f6a05580c64d4438411062f13310), can be reaped by anyone who manages to *modify the canister code or state*.\n\nGood luck!\n\nWhat is [**39141f05da8f71024656155dbb7135ff10e3692741dd4dcc65bbe8d867061c1e**](https://dashboard.internetcomputer.org/account/39141f05da8f71024656155dbb7135ff10e3692741dd4dcc65bbe8d867061c1e)?\n-----------------------\n\nThis account holds 1 ICP and was the account I originally claimed to be owned by the present canister. But I made a mistake calculating the account number, so that token is probably lost forever. H't to @mraszyk for noticing when he solved the challenge.\n\nMore questions or comments?\n---------------------------\n\nI have enabled the discussion feature on this repository, feel free to use it.\nElse \u003chttps://forum.dfinity.org/\u003e is a fine venue for questions.\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnomeata%2Fcapture-the-ic-token","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnomeata%2Fcapture-the-ic-token","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnomeata%2Fcapture-the-ic-token/lists"}