{"id":13620497,"url":"https://github.com/0age/HomeWork","last_synced_at":"2025-04-14T21:31:19.884Z","repository":{"id":44133722,"uuid":"190376567","full_name":"0age/HomeWork","owner":"0age","description":"HomeWork is an autonomous utility for finding, sharing and reusing home addresses for contracts.","archived":false,"fork":false,"pushed_at":"2023-12-19T19:21:46.000Z","size":869,"stargazers_count":123,"open_issues_count":12,"forks_count":10,"subscribers_count":9,"default_branch":"master","last_synced_at":"2024-11-07T19:52:04.232Z","etag":null,"topics":["account","erc721","ethereum","homework","smart-contracts"],"latest_commit_sha":null,"homepage":null,"language":"Solidity","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/0age.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null}},"created_at":"2019-06-05T10:42:21.000Z","updated_at":"2024-06-28T08:42:43.000Z","dependencies_parsed_at":"2024-01-25T18:06:27.652Z","dependency_job_id":"b0fa19d5-d4e5-48cf-b8a6-70baa63fada8","html_url":"https://github.com/0age/HomeWork","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/0age%2FHomeWork","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/0age%2FHomeWork/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/0age%2FHomeWork/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/0age%2FHomeWork/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/0age","download_url":"https://codeload.github.com/0age/HomeWork/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":223647937,"owners_count":17179348,"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":["account","erc721","ethereum","homework","smart-contracts"],"created_at":"2024-08-01T21:00:56.493Z","updated_at":"2024-11-08T07:30:29.715Z","avatar_url":"https://github.com/0age.png","language":"Solidity","funding_links":[],"categories":["Libraries"],"sub_categories":[],"readme":"![HomeWork 🏠🛠️](https://raw.github.com/0age/HomeWork/master/images/HomeWork.svg?sanitize=true)\n\n# HomeWork\n\n[![GitHub](https://img.shields.io/github/license/0age/HomeWork.svg?colorB=brightgreen)](https://github.com/0age/HomeWork/blob/master/LICENSE.md)\n[![Build Status](https://travis-ci.org/0age/HomeWork.svg?branch=master)](https://travis-ci.org/0age/HomeWork)\n[![Coverage](https://coveralls.io/repos/github/0age/HomeWork/badge.svg?branch=master)](https://coveralls.io/github/0age/HomeWork?branch=master)\n[![standard-readme compliant](https://img.shields.io/badge/standard--readme-OK-brightgreen.svg)](https://github.com/RichardLitt/standard-readme)\n[![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg)](http://makeapullrequest.com)\n\n\u003e HomeWork is an autonomous utility for finding, sharing and reusing home addresses for contracts.\n\nA **home address** is a dedicated account where a specific controller can deploy arbitrary contracts. Unlike a standard contract deployment, where the deployment address is determined by rigid factors like the nonce of the deployer or the contract's creation code, home address contract deployments relax the usual constraints and allow *any* contract to be deployed to a specific address, and for new contracts to be redeployed to the same address if the original contract is removed.\n\nEach home address is uniquely identified by a specific 32-byte **key**. Each key has a dedicated controller, an account with the exclusive right to deploy contracts to the corresponding home address. By default, each key is initially controlled by the account whose address matches the first twenty bytes of said key. Alternately, they can be derived using a full 32-byte salt for any submitting account. Control of keys can easily be transferred, either to other accounts and contracts, or to HomeWork itself by locking the home address and minting an NFT.\n\nHomeWork implements **ERC721**, and will take control of any home address without a deployed contract in exchange for a corresponding NFT. The owner of the NFT can then redeem it in order to gain control over deployment to the designated home address. There's no external issuer or anything, so each token must first be discovered and claimed by a valid submitter.\n\n**DISCLAIMER: this implements highly experimental features / bugs - Be careful! These contracts have not yet been fully tested or audited - proceed with caution and please share any exploits or optimizations you discover.**\n\nYou can find HomeWork V1 at `0x0000000000001b84b1cb32787B0D64758d019317` *(yes, there are six zero bytes at the start)* on [mainnet](https://blockscout.com/eth/mainnet/address/0x0000000000001b84b1cb32787b0d64758d019317/contracts), [ropsten](https://blockscout.com/eth/ropsten/address/0x0000000000001b84b1cb32787b0d64758d019317/contracts), [goerli](https://goerli.etherscan.io/address/0x0000000000001b84b1cb32787b0d64758d019317), [rinkeby](https://rinkeby.etherscan.io/address/0x0000000000001b84b1cb32787b0d64758d019317), and [kovan](https://blockscout.com/eth/kovan/address/0x0000000000001b84b1cb32787b0d64758d019317/contracts).\n\nTo learn more about HomeWork, check out [this article](https://medium.com/@0age/on-efficient-ethereum-transactions-introducing-homework-6ae4f21801ed).\n\n## Table of Contents\n\n- [Install](#install)\n- [Usage](#usage)\n- [API](#api)\n- [How It Works](#how-it-works)\n- [Maintainers](#maintainers)\n- [Contribute](#contribute)\n- [License](#license)\n\n## Install\nIf you want to install HomeWork locally, you'll need Node.js 10+ and Yarn *(or npm)*. To get everything set up:\n```sh\n$ git clone https://github.com/0age/HomeWork.git\n$ cd HomeWork\n$ yarn install\n$ yarn build\n```\n\n## Usage\nTo interact with HomeWork, use the following:\n\nContract address:\n```\n0x0000000000001b84b1cb32787B0D64758d019317\n```\n\nABI (basic):\n```\n[{\"constant\":true,\"inputs\":[{\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"getApproved\",\"outputs\":[{\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"to\",\"type\":\"address\"},{\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"approve\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"totalSupply\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"owner\",\"type\":\"address\"},{\"name\":\"index\",\"type\":\"uint256\"}],\"name\":\"tokenOfOwnerByIndex\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"from\",\"type\":\"address\"},{\"name\":\"to\",\"type\":\"address\"},{\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"safeTransferFrom\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"ownerOf\",\"outputs\":[{\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"balanceOf\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"to\",\"type\":\"address\"},{\"name\":\"approved\",\"type\":\"bool\"}],\"name\":\"setApprovalForAll\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"owner\",\"type\":\"address\"},{\"name\":\"operator\",\"type\":\"address\"}],\"name\":\"isApprovedForAll\",\"outputs\":[{\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"name\":\"homeAddress\",\"type\":\"address\"},{\"indexed\":false,\"name\":\"key\",\"type\":\"bytes32\"},{\"indexed\":false,\"name\":\"runtimeCodeHash\",\"type\":\"bytes32\"}],\"name\":\"NewResident\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"name\":\"runtimeStorageContract\",\"type\":\"address\"},{\"indexed\":false,\"name\":\"runtimeCodeHash\",\"type\":\"bytes32\"}],\"name\":\"NewRuntimeStorageContract\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"name\":\"key\",\"type\":\"bytes32\"},{\"indexed\":false,\"name\":\"newController\",\"type\":\"address\"}],\"name\":\"NewController\",\"type\":\"event\"},{\"constant\":false,\"inputs\":[{\"name\":\"key\",\"type\":\"bytes32\"},{\"name\":\"initializationCode\",\"type\":\"bytes\"}],\"name\":\"deploy\",\"outputs\":[{\"name\":\"homeAddress\",\"type\":\"address\"},{\"name\":\"runtimeCodeHash\",\"type\":\"bytes32\"}],\"payable\":true,\"stateMutability\":\"payable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"key\",\"type\":\"bytes32\"},{\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"lock\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"tokenId\",\"type\":\"uint256\"},{\"name\":\"controller\",\"type\":\"address\"}],\"name\":\"redeem\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"key\",\"type\":\"bytes32\"},{\"name\":\"controller\",\"type\":\"address\"}],\"name\":\"assignController\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"tokenId\",\"type\":\"uint256\"},{\"name\":\"controller\",\"type\":\"address\"},{\"name\":\"initializationCode\",\"type\":\"bytes\"}],\"name\":\"redeemAndDeploy\",\"outputs\":[{\"name\":\"homeAddress\",\"type\":\"address\"},{\"name\":\"runtimeCodeHash\",\"type\":\"bytes32\"}],\"payable\":true,\"stateMutability\":\"payable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"salt\",\"type\":\"bytes32\"}],\"name\":\"deriveKey\",\"outputs\":[{\"name\":\"key\",\"type\":\"bytes32\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"key\",\"type\":\"bytes32\"}],\"name\":\"setReverseLookup\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"key\",\"type\":\"bytes32\"}],\"name\":\"staticCreate2Check\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"key\",\"type\":\"bytes32\"}],\"name\":\"isDeployable\",\"outputs\":[{\"name\":\"deployable\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"key\",\"type\":\"bytes32\"}],\"name\":\"getHomeAddressInformation\",\"outputs\":[{\"name\":\"homeAddress\",\"type\":\"address\"},{\"name\":\"controller\",\"type\":\"address\"},{\"name\":\"deploys\",\"type\":\"uint256\"},{\"name\":\"currentRuntimeCodeHash\",\"type\":\"bytes32\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"key\",\"type\":\"bytes32\"}],\"name\":\"hasNeverBeenDeployed\",\"outputs\":[{\"name\":\"neverBeenDeployed\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"homeAddress\",\"type\":\"address\"}],\"name\":\"reverseLookup\",\"outputs\":[{\"name\":\"key\",\"type\":\"bytes32\"},{\"name\":\"salt\",\"type\":\"bytes32\"},{\"name\":\"submitter\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"tokenURI\",\"outputs\":[{\"name\":\"\",\"type\":\"string\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"name\",\"outputs\":[{\"name\":\"\",\"type\":\"string\"}],\"payable\":false,\"stateMutability\":\"pure\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"salt\",\"type\":\"bytes32\"},{\"name\":\"submitter\",\"type\":\"address\"}],\"name\":\"getDerivedKey\",\"outputs\":[{\"name\":\"key\",\"type\":\"bytes32\"}],\"payable\":false,\"stateMutability\":\"pure\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"key\",\"type\":\"bytes32\"}],\"name\":\"getHomeAddress\",\"outputs\":[{\"name\":\"homeAddress\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"pure\",\"type\":\"function\"}]\n```\n\nABI (full):\n```\n[{\"constant\":true,\"inputs\":[{\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"getApproved\",\"outputs\":[{\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"to\",\"type\":\"address\"},{\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"approve\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"totalSupply\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"from\",\"type\":\"address\"},{\"name\":\"to\",\"type\":\"address\"},{\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"transferFrom\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"owner\",\"type\":\"address\"},{\"name\":\"index\",\"type\":\"uint256\"}],\"name\":\"tokenOfOwnerByIndex\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"from\",\"type\":\"address\"},{\"name\":\"to\",\"type\":\"address\"},{\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"safeTransferFrom\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"index\",\"type\":\"uint256\"}],\"name\":\"tokenByIndex\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"ownerOf\",\"outputs\":[{\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"balanceOf\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"to\",\"type\":\"address\"},{\"name\":\"approved\",\"type\":\"bool\"}],\"name\":\"setApprovalForAll\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"from\",\"type\":\"address\"},{\"name\":\"to\",\"type\":\"address\"},{\"name\":\"tokenId\",\"type\":\"uint256\"},{\"name\":\"_data\",\"type\":\"bytes\"}],\"name\":\"safeTransferFrom\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"owner\",\"type\":\"address\"},{\"name\":\"operator\",\"type\":\"address\"}],\"name\":\"isApprovedForAll\",\"outputs\":[{\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"name\":\"to\",\"type\":\"address\"},{\"indexed\":true,\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"Transfer\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"name\":\"owner\",\"type\":\"address\"},{\"indexed\":true,\"name\":\"approved\",\"type\":\"address\"},{\"indexed\":true,\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"Approval\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"name\":\"owner\",\"type\":\"address\"},{\"indexed\":true,\"name\":\"operator\",\"type\":\"address\"},{\"indexed\":false,\"name\":\"approved\",\"type\":\"bool\"}],\"name\":\"ApprovalForAll\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"name\":\"homeAddress\",\"type\":\"address\"},{\"indexed\":false,\"name\":\"key\",\"type\":\"bytes32\"},{\"indexed\":false,\"name\":\"runtimeCodeHash\",\"type\":\"bytes32\"}],\"name\":\"NewResident\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"name\":\"runtimeStorageContract\",\"type\":\"address\"},{\"indexed\":false,\"name\":\"runtimeCodeHash\",\"type\":\"bytes32\"}],\"name\":\"NewRuntimeStorageContract\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"name\":\"key\",\"type\":\"bytes32\"},{\"indexed\":false,\"name\":\"newController\",\"type\":\"address\"}],\"name\":\"NewController\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"name\":\"key\",\"type\":\"bytes32\"},{\"indexed\":false,\"name\":\"submitter\",\"type\":\"address\"},{\"indexed\":false,\"name\":\"score\",\"type\":\"uint256\"}],\"name\":\"NewHighScore\",\"type\":\"event\"},{\"constant\":false,\"inputs\":[{\"name\":\"key\",\"type\":\"bytes32\"},{\"name\":\"initializationCode\",\"type\":\"bytes\"}],\"name\":\"deploy\",\"outputs\":[{\"name\":\"homeAddress\",\"type\":\"address\"},{\"name\":\"runtimeCodeHash\",\"type\":\"bytes32\"}],\"payable\":true,\"stateMutability\":\"payable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"key\",\"type\":\"bytes32\"},{\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"lock\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"tokenId\",\"type\":\"uint256\"},{\"name\":\"controller\",\"type\":\"address\"}],\"name\":\"redeem\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"key\",\"type\":\"bytes32\"},{\"name\":\"controller\",\"type\":\"address\"}],\"name\":\"assignController\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"key\",\"type\":\"bytes32\"}],\"name\":\"relinquishControl\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"tokenId\",\"type\":\"uint256\"},{\"name\":\"controller\",\"type\":\"address\"},{\"name\":\"initializationCode\",\"type\":\"bytes\"}],\"name\":\"redeemAndDeploy\",\"outputs\":[{\"name\":\"homeAddress\",\"type\":\"address\"},{\"name\":\"runtimeCodeHash\",\"type\":\"bytes32\"}],\"payable\":true,\"stateMutability\":\"payable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"salt\",\"type\":\"bytes32\"}],\"name\":\"deriveKey\",\"outputs\":[{\"name\":\"key\",\"type\":\"bytes32\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"salt\",\"type\":\"bytes32\"},{\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"deriveKeyAndLock\",\"outputs\":[{\"name\":\"key\",\"type\":\"bytes32\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"salt\",\"type\":\"bytes32\"},{\"name\":\"controller\",\"type\":\"address\"}],\"name\":\"deriveKeyAndAssignController\",\"outputs\":[{\"name\":\"key\",\"type\":\"bytes32\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"salt\",\"type\":\"bytes32\"}],\"name\":\"deriveKeyAndRelinquishControl\",\"outputs\":[{\"name\":\"key\",\"type\":\"bytes32\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"key\",\"type\":\"bytes32\"}],\"name\":\"setReverseLookup\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"salt\",\"type\":\"bytes32\"},{\"name\":\"submitter\",\"type\":\"address\"}],\"name\":\"setDerivedReverseLookup\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"codePayload\",\"type\":\"bytes\"}],\"name\":\"deployRuntimeStorageContract\",\"outputs\":[{\"name\":\"runtimeStorageContract\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"key\",\"type\":\"bytes32\"},{\"name\":\"initializationRuntimeStorageContract\",\"type\":\"address\"}],\"name\":\"deployViaExistingRuntimeStorageContract\",\"outputs\":[{\"name\":\"homeAddress\",\"type\":\"address\"},{\"name\":\"runtimeCodeHash\",\"type\":\"bytes32\"}],\"payable\":true,\"stateMutability\":\"payable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"tokenId\",\"type\":\"uint256\"},{\"name\":\"controller\",\"type\":\"address\"},{\"name\":\"initializationRuntimeStorageContract\",\"type\":\"address\"}],\"name\":\"redeemAndDeployViaExistingRuntimeStorageContract\",\"outputs\":[{\"name\":\"homeAddress\",\"type\":\"address\"},{\"name\":\"runtimeCodeHash\",\"type\":\"bytes32\"}],\"payable\":true,\"stateMutability\":\"payable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"salt\",\"type\":\"bytes32\"},{\"name\":\"initializationCode\",\"type\":\"bytes\"}],\"name\":\"deriveKeyAndDeploy\",\"outputs\":[{\"name\":\"homeAddress\",\"type\":\"address\"},{\"name\":\"key\",\"type\":\"bytes32\"},{\"name\":\"runtimeCodeHash\",\"type\":\"bytes32\"}],\"payable\":true,\"stateMutability\":\"payable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"salt\",\"type\":\"bytes32\"},{\"name\":\"initializationRuntimeStorageContract\",\"type\":\"address\"}],\"name\":\"deriveKeyAndDeployViaExistingRuntimeStorageContract\",\"outputs\":[{\"name\":\"homeAddress\",\"type\":\"address\"},{\"name\":\"key\",\"type\":\"bytes32\"},{\"name\":\"runtimeCodeHash\",\"type\":\"bytes32\"}],\"payable\":true,\"stateMutability\":\"payable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"owner\",\"type\":\"address\"},{\"name\":\"keys\",\"type\":\"bytes32[]\"}],\"name\":\"batchLock\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"owner\",\"type\":\"address\"},{\"name\":\"salts\",\"type\":\"bytes32[]\"}],\"name\":\"deriveKeysAndBatchLock\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"from\",\"type\":\"address\"},{\"name\":\"to\",\"type\":\"address\"},{\"name\":\"tokenIds\",\"type\":\"uint256[]\"}],\"name\":\"safeBatchTransferFrom\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"from\",\"type\":\"address\"},{\"name\":\"to\",\"type\":\"address\"},{\"name\":\"tokenIds\",\"type\":\"uint256[]\"},{\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"safeBatchTransferFrom\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[],\"name\":\"batchLock_63efZf\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"key\",\"type\":\"bytes32\"}],\"name\":\"staticCreate2Check\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"key\",\"type\":\"bytes32\"}],\"name\":\"claimHighScore\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"token\",\"type\":\"address\"},{\"name\":\"recipient\",\"type\":\"address\"}],\"name\":\"recover\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"key\",\"type\":\"bytes32\"}],\"name\":\"isDeployable\",\"outputs\":[{\"name\":\"deployable\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"getHighScore\",\"outputs\":[{\"name\":\"holder\",\"type\":\"address\"},{\"name\":\"score\",\"type\":\"uint256\"},{\"name\":\"key\",\"type\":\"bytes32\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"key\",\"type\":\"bytes32\"}],\"name\":\"getHomeAddressInformation\",\"outputs\":[{\"name\":\"homeAddress\",\"type\":\"address\"},{\"name\":\"controller\",\"type\":\"address\"},{\"name\":\"deploys\",\"type\":\"uint256\"},{\"name\":\"currentRuntimeCodeHash\",\"type\":\"bytes32\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"key\",\"type\":\"bytes32\"}],\"name\":\"hasNeverBeenDeployed\",\"outputs\":[{\"name\":\"neverBeenDeployed\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"homeAddress\",\"type\":\"address\"}],\"name\":\"reverseLookup\",\"outputs\":[{\"name\":\"key\",\"type\":\"bytes32\"},{\"name\":\"salt\",\"type\":\"bytes32\"},{\"name\":\"submitter\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"getInitializationCodeFromContractRuntime_6CLUNS\",\"outputs\":[{\"name\":\"initializationRuntimeStorageContract\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"tokenURI\",\"outputs\":[{\"name\":\"\",\"type\":\"string\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"name\",\"outputs\":[{\"name\":\"\",\"type\":\"string\"}],\"payable\":false,\"stateMutability\":\"pure\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"symbol\",\"outputs\":[{\"name\":\"\",\"type\":\"string\"}],\"payable\":false,\"stateMutability\":\"pure\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"salt\",\"type\":\"bytes32\"},{\"name\":\"submitter\",\"type\":\"address\"}],\"name\":\"getDerivedKey\",\"outputs\":[{\"name\":\"key\",\"type\":\"bytes32\"}],\"payable\":false,\"stateMutability\":\"pure\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"key\",\"type\":\"bytes32\"}],\"name\":\"getHomeAddress\",\"outputs\":[{\"name\":\"homeAddress\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"pure\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"getMetamorphicDelegatorInitializationCode\",\"outputs\":[{\"name\":\"metamorphicDelegatorInitializationCode\",\"type\":\"bytes32\"}],\"payable\":false,\"stateMutability\":\"pure\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"getMetamorphicDelegatorInitializationCodeHash\",\"outputs\":[{\"name\":\"metamorphicDelegatorInitializationCodeHash\",\"type\":\"bytes32\"}],\"payable\":false,\"stateMutability\":\"pure\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"getArbitraryRuntimeCodePrelude\",\"outputs\":[{\"name\":\"prelude\",\"type\":\"bytes11\"}],\"payable\":false,\"stateMutability\":\"pure\",\"type\":\"function\"}]\n```\n\nTo try it out, start by deploying a contract by choosing an account to submit from, picking a home key with the first twenty bytes set to that account address, and calling `deploy` with the key and your contract’s creation code (including ABI-encoded constructor arguments, of course). Alternately, you can call `lock` to give control to HomeWork and mint an NFT, and `redeem` or `redeemAndDeploy` to burn it and take control back.\n\nTwo big caveats to be aware of:\n- `msg.sender` will refer to HomeWork, not to the submitter - you can still get at the submitter by calling into HomeWork *(easiest if you set a reverse lookup for the home address first)*, or you can just include it as a constructor arg.\n- you won’t be able to deploy any contract to a home address that already has a contract deployed. If you deploy a contract that can’t be removed via `SELFDESTRUCT`, HomeWork’s job is done and it will not be able to interact with that home address anymore. *(Well, state rent might change that...)*\n\nContract verification for contracts deployed via HomeWork is supported by the [BlockScout](https://blockscout.com/eth/mainnet/) block explorer.\n\nTo run tests locally, start the testRPC, trigger the tests, run the linter, and tear down the testRPC *(you can do all of this at once via* `yarn all` *if you prefer)*:\n```sh\n$ yarn start\n$ yarn test\n$ yarn lint\n$ yarn stop\n```\n\nYou can also run code coverage if you like:\n```sh\n$ yarn coverage\n```\n\n## API\n#### Summary\n```Solidity\ninterface IHomeWork {\n  event NewResident(address indexed homeAddress, bytes32 key, bytes32 runtimeCodeHash);\n  event NewRuntimeStorageContract(address runtimeStorageContract, bytes32 runtimeCodeHash);\n  event NewController(bytes32 indexed key, address newController);\n  event NewHighScore(bytes32 key, address submitter, uint256 score);\n\n  function deploy(bytes32 key, bytes calldata initializationCode) external payable returns (address homeAddress, bytes32 runtimeCodeHash);\n  function lock(bytes32 key, address owner) external;\n  function redeem(uint256 tokenId, address controller) external;\n  function assignController(bytes32 key, address controller) external;\n  function relinquishControl(bytes32 key) external;\n  function redeemAndDeploy(uint256 tokenId, address controller, bytes calldata initializationCode) external payable returns (address homeAddress, bytes32 runtimeCodeHash);\n  function deriveKey(bytes32 salt) external returns (bytes32 key);\n  function deriveKeyAndLock(bytes32 salt, address owner) external returns (bytes32 key);\n  function deriveKeyAndAssignController(bytes32 salt, address controller) external returns (bytes32 key);\n  function deriveKeyAndRelinquishControl(bytes32 salt) external returns (bytes32 key);\n  function setReverseLookup(bytes32 key) external;\n  function setDerivedReverseLookup(bytes32 salt, address submitter) external;\n  function deployRuntimeStorageContract(bytes calldata codePayload) external returns (address runtimeStorageContract);\n  function deployViaExistingRuntimeStorageContract(bytes32 key, address initializationRuntimeStorageContract) external payable returns (address homeAddress, bytes32 runtimeCodeHash);\n  function redeemAndDeployViaExistingRuntimeStorageContract(uint256 tokenId, address controller, address initializationRuntimeStorageContract) external payable returns (address homeAddress, bytes32 runtimeCodeHash);\n  function deriveKeyAndDeploy(bytes32 salt, bytes calldata initializationCode) external payable returns (address homeAddress, bytes32 key, bytes32 runtimeCodeHash);\n  function deriveKeyAndDeployViaExistingRuntimeStorageContract(bytes32 salt, address initializationRuntimeStorageContract) external payable returns (address homeAddress, bytes32 key, bytes32 runtimeCodeHash);\n  function batchLock(address owner, bytes32[] calldata keys) external;\n  function deriveKeysAndBatchLock(address owner, bytes32[] calldata salts) external;\n  function batchLock_63efZf(/* packed owner and key segments */) external;\n  function claimHighScore(bytes32 key) external;\n  function recover(address token, address payable recipient) external;\n  \n  function isDeployable(bytes32 key) external /* view */ returns (bool);\n  function getHighScore() external view returns (address holder, uint256 score, bytes32 key);\n  function getHomeAddressInformation(bytes32 key) external view returns (address homeAddress, address controller, uint256 deploys, bytes32 currentRuntimeCodeHash);\n  function hasNeverBeenDeployed(bytes32 key) external view returns (bool);\n  function reverseLookup(address homeAddress) external view returns (bytes32 key, bytes32 salt, address submitter);\n\n  function getDerivedKey(bytes32 salt, address submitter) external pure returns (bytes32);\n  function getHomeAddress(bytes32 key) external pure returns (address);\n  function getMetamorphicDelegatorInitializationCode() external pure returns (bytes32);\n  function getMetamorphicDelegatorInitializationCodeHash() external pure returns (bytes32);\n  function getArbitraryRuntimeCodePrelude() external pure returns (bytes11);\n}\n\ninterface IERC721 {\n    event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);\n    event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);\n    event ApprovalForAll(address indexed owner, address indexed operator, bool approved);\n\n    function balanceOf(address owner) external view returns (uint256 balance);\n    function ownerOf(uint256 tokenId) external view returns (address owner);\n\n    function approve(address to, uint256 tokenId) external;\n    function getApproved(uint256 tokenId) external view returns (address operator);\n    function setApprovalForAll(address operator, bool _approved) external;\n    function isApprovedForAll(address owner, address operator) external view returns (bool);\n\n    function transferFrom(address from, address to, uint256 tokenId) external;\n    function safeTransferFrom(address from, address to, uint256 tokenId) external;\n    function safeTransferFrom(address from, address to, uint256 tokenId, bytes calldata data) external;\n}\n```\n\n\u003e *Note: ERC721 and related interfaces not included as part of this documentation.*\n\n#### Standard Keys\n* [`deploy`](#deploy)\n* [`assignController`](#assigncontroller)\n* [`relinquishControl`](#relinquishcontrol)\n* [`setReverseLookup`](#setreverselookup)\n\n#### Derived Keys\n* [`deriveKey`](#derivekey)\n* [`deriveKeyAndDeploy`](#derivekeyanddeploy)\n* [`deriveKeyAndAssignController`](#derivekeyandassigncontroller)\n* [`deriveKeyAndRelinquishControl`](#derivekeyandrelinquishcontrol)\n* [`setDerivedReverseLookup`](#setderivedreverselookup)\n\n#### Home Address NFTs\n* [`lock`](#lock)\n* [`redeem`](#redeem)\n* [`redeemAndDeploy`](#redeemanddeploy)\n* [`deriveKeyAndLock`](#derivekeyandlock)\n* [`batchLock`](#batchlock)\n* [`deriveKeysAndBatchLock`](#derivekeysandbatchlock)\n\n#### View Functions\n* [`isDeployable`](#isdeployable)\n* [`getHighScore`](#gethighscore)\n* [`getHomeAddressInformation`](#gethomeaddressinformation)\n* [`hasNeverBeenDeployed`](#hasneverbeendeployed)\n* [`reverseLookup`](#reverselookup)\n\n#### Pure Functions\n* [`getDerivedKey`](#getderivedkey)\n* [`getHomeAddress`](#gethomeaddress)\n* [`getMetamorphicDelegatorInitializationCode`](#getmetamorphicdelegatorinitializationcode)\n* [`getMetamorphicDelegatorInitializationCodeHash`](#getmetamorphicdelegatorinitializationcodehash)\n* [`getArbitraryRuntimeCodePrelude`](#getarbitraryruntimecodeprelude)\n\n#### Events\n* [`event NewResident`](#newresident-event)\n* [`event NewRuntimeStorageContract`](#newruntimestoragecontract-event)\n* [`event NewController`](#newcontroller-event)\n* [`event NewHighScore`](#newhighscore-event)\n\n#### Advanced Usage\n* [`deployRuntimeStorageContract`](#deployruntimestoragecontract)\n* [`deployViaExistingRuntimeStorageContract`](#deployviaexistingruntimestoragecontract)\n* [`deriveKeyAndDeployViaExistingRuntimeStorageContract`](#derivekeyanddeployviaexistingruntimestoragecontract)\n* [`redeemAndDeployViaExistingRuntimeStorageContract`](#redeemanddeployviaexistingruntimestoragecontract)\n* [`batchLock_63efZf`](#batchlock_63efzf)\n* [`claimHighScore`](#claimhighscore)\n* [`recover`](#recover)\n\n### deploy\n---\n```Solidity\nfunction deploy(bytes32 key, bytes calldata initializationCode)\n  external\n  payable\n  returns (address homeAddress, bytes32 runtimeCodeHash);\n```\nDeploy a new contract with the supplied initialization code and `msg.value` to the home address corresponding to a given key. Two conditions must be met:\n* the submitter must be designated as the controller of the home address *(with the initial controller set to the address corresponding to the first twenty bytes of the key)*, and\n* there must not be a contract currently deployed at the home address.\n\nThese conditions can be checked by calling `getHomeAddressInformation` and `isDeployable` with the same key.\n\n##### parameters:\n| | | |\n|-|-|-|\n| *bytes32* | key | The unique value used to derive the home address. |\n| *bytes* | initializationCode | The contract creation code that will be used to deploy the contract to the home address. |\n\n##### returns:\n| | | |\n|-|-|-|\n| *address* | homeAddress | The home address of the deployed contract. |\n| *bytes32* | runtimeCodeHash | The runtime code hash of the deployed contract. |\n\n\u003e In order to deploy the contract to the home address, a new contract will be deployed with runtime code set to the initialization code of the contract that will be deployed to the home address. Then, metamorphic initialization code will retrieve that initialization code and use it to set up and deploy the desired contract to the home address.\n\u003e \n\u003e Bear in mind that the deployed contract will interpret msg.sender as the address of THIS contract, and not the address of the submitter - if the constructor of the deployed contract uses msg.sender to set up ownership or other variables, you must modify it to accept a constructor argument with the appropriate address, or alternately to hard-code the intended address. \n\u003e \n\u003e Also, if your contract DOES have constructor arguments, remember to include them as ABI-encoded arguments at the end of the initialization code, just as you would when performing a standard deploy.\n\u003e \n\u003e You may also want to provide the key to `setReverseLookup` in order to find it again using only the home address to prevent accidentally losing the key.\n\n### lock\n---\n```Solidity\nfunction lock(bytes32 key, address owner) external;\n```\nMint an ERC721 token to the supplied owner that can be redeemed in order to gain control of a home address corresponding to a given key. Two conditions must be met:\n* the submitter must be designated as the controller of the home address *(with the initial controller set to the address corresponding to the first twenty bytes of the key)*, and\n* there must not be a contract currently deployed at the home address.\n\nThese conditions can be checked by calling `getHomeAddressInformation` and `isDeployable` with the same key.\n\n##### parameters:\n| | | |\n|-|-|-|\n| *bytes32* | key | The unique value used to derive the home address. |\n| *address* | owner | The account that will be granted ownership of the ERC721 token. |\n\n\u003e In order to mint an ERC721 token, the assocated home address cannot be in use, or else the token will not be able to deploy to the home address. The controller is set to this contract until the token is redeemed and burned, at which point the redeemer designates a new controller for the home address.\n\u003e \n\u003e The key of the home address and the tokenId of the ERC721 token are the same value, but different types *(bytes32 vs. uint256)*.\n\n### redeem\n---\n```Solidity\nfunction redeem(uint256 tokenId, address controller) external;\n```\nBurn an ERC721 NFT to allow the supplied controller to gain the ability to deploy to the home address corresponding to the key matching the burned token. The submitter must be designated as either the owner of the NFT or as an approved spender.\n\n##### parameters:\n| | | |\n|-|-|-|\n| *uint256* | tokenId | The ID of the ERC721 NFT to redeem. |\n| *address* | controller | The account that will be granted control of the home address corresponding to the given NFT. |\n\n\u003e The controller cannot be designated as the address of this contract, the null address, or the home address *(the restriction on setting the home address as the controller is due to the fact that the home address will not be able to deploy to itself, as it needs to be empty before a contract can be deployed to it)*.\n\n### assignController\n---\n```Solidity\nfunction assignController(bytes32 key, address controller) external;\n```\nTransfer control over deployment to the home address corresponding to a given key. The caller must be designated as the current controller of the home address *(with the initial controller set to the address corresponding to the first 20 bytes of the key)* - This condition can be checked by calling `getHomeAddressInformation` with the same key.\n\n##### parameters:\n| | | |\n|-|-|-|\n| *bytes32* | key | The unique value used to derive the home address. |\n| *address* | controller | The account that will be granted control of the home address corresponding to the given key. |\n\n\u003e The controller cannot be designated as the address of this contract, the null address, or the home address *(the restriction on setting the home address as the controller is due to the fact that the home address will not be able to deploy to itself, as it needs to be empty before a contract can be deployed to it)*.\n\n### relinquishControl\n---\n```Solidity\nfunction relinquishControl(bytes32 key) external;\n```\nTransfer control over deployment to the home address corresponding to a given key to the null address, which will prevent it from being deployed to again in the future. The caller must be designated as the current controller of the corresponding home address *(with the initial controller set to the address corresponding to the first 20 bytes of the key)* - This condition can be checked by calling `getHomeAddressInformation` with the same key.\n\n##### parameters:\n| | | |\n|-|-|-|\n| *bytes32* | key | The unique value used to derive the home address. |\n\n### redeemAndDeploy\n---\n```Solidity\nfunction redeemAndDeploy(\n  uint256 tokenId,\n  address controller,\n  bytes calldata initializationCode\n)\n  external\n  payable\n  returns (address homeAddress, bytes32 runtimeCodeHash);\n```\nBurn an ERC721 token, set a supplied controller, and deploy a new contract with the supplied initialization code and `msg.value` to the corresponding home address for the given token.  Two conditions must be met:\n* The submitter must be designated as either the owner of the token or as an approved spender, and\n* there must not be a contract currently deployed at the home address.\n\nThese conditions can be checked by calling either `ownerOf` or `getApproved` for the `tokenId` *(or* `isApprovedForAll` *for the owner of the token and the caller)*, and `isDeployable` with the `bytes32` representation of the `tokenId`.\n\n##### parameters:\n| | | |\n|-|-|-|\n| *uint256* | tokenId | The ID of the ERC721 NFT to redeem. |\n| *address* | controller | The account that will be granted control of the home address corresponding to the given NFT. |\n| *bytes* | initializationCode | The contract creation code that will be used to deploy the contract to the home address. |\n\n##### returns:\n| | | |\n|-|-|-|\n| *address* | homeAddress | The home address of the deployed contract. |\n| *bytes32* | runtimeCodeHash | The runtime code hash of the deployed contract. |\n\n\u003e In order to deploy the contract to the home address, a new contract will be deployed with runtime code set to the initialization code of the contract that will be deployed to the home address. Then, metamorphic initialization code will retrieve that initialization code and use it to set up and deploy the desired contract to the home address.\n\u003e \n\u003e Bear in mind that the deployed contract will interpret msg.sender as the address of THIS contract, and not the address of the submitter - if the constructor of the deployed contract uses msg.sender to set up ownership or other variables, you must modify it to accept a constructor argument with the appropriate address, or alternately to hard-code the intended address. \n\u003e \n\u003e Also, if your contract DOES have constructor arguments, remember to include them as ABI-encoded arguments at the end of the initialization code, just as you would when performing a standard deploy. You may also want to provide the key to `setReverseLookup` in order to find it again using only the home address to prevent accidentally losing the key.\n\u003e \n\u003e The controller cannot be designated as the address of this contract, the null address, or the home address (the restriction on setting the home address as the controller is due to the fact that the home address will not be able to deploy to itself, as it needs to be empty before a contract can be deployed to it).\n\u003e \n\u003e Also, checks on the contract at the home address being empty or not having the correct controller are unnecessary, as they are performed when minting the token and cannot be altered until the token is redeemed.\n\n### deriveKey\n---\n```Solidity\nfunction deriveKey(bytes32 salt) external returns (bytes32 key);\n```\nDerive a new key by concatenating an arbitrary 32-byte salt value and the address of the caller and performing a keccak256 hash. This allows for the creation of keys with additional entropy where desired while also preventing collisions with standard keys. The caller will be set as the controller of the derived key *(unless the key already exists, in which case no action will be taken)*.\n\n##### parameters:\n| | | |\n|-|-|-|\n| *bytes32* | salt | The desired salt value to use *(along with the address of the caller)* when deriving the resultant key and corresponding home address. |\n\n##### returns:\n| | | |\n|-|-|-|\n| *bytes32* | key | The derived key. |\n\n\u003e Home addresses from derived keys will take longer to \"mine\" or locate, as an additional hash must be performed when computing the corresponding home address for each given salt input. Each caller will derive a different key, even if they are supplying the same salt value.\n\n### deriveKeyAndLock\n---\n```Solidity\nfunction deriveKeyAndLock(bytes32 salt, address owner)\n  external\n  returns (bytes32 key);\n```\nMint an ERC721 token to the supplied owner that can be redeemed in order to gain control of a home address corresponding to a given derived key. Two conditions must be met:\n* the submitter must be designated as the controller of the home address corresponding to the derived key, and\n* there must not be a contract currently deployed at the home address.\n\nThese conditions can be checked by calling `getHomeAddressInformation` and `isDeployable` with the key determined by calling `getDerivedKey`.\n\n##### parameters:\n| | | |\n|-|-|-|\n| *bytes32* | salt | The desired salt value to use *(along with the address of the caller)* when deriving the resultant key and corresponding home address. |\n| *address* | owner | The account that will be granted ownership of the ERC721 token. |\n\n##### returns:\n| | | |\n|-|-|-|\n| *bytes32* | key | The derived key. |\n\n\u003e In order to mint an ERC721 token, the assocated home address cannot be in use, or else the token will not be able to deploy to the home address. The controller is set to this contract until the token is redeemed, at which point the redeemer designates a new controller for the home address.\n\u003e \n\u003e The key of the home address and the tokenId of the ERC721 token are the same value, but different types *(bytes32 vs. uint256)*.\n\n### deriveKeyAndAssignController\n---\n```Solidity\nfunction deriveKeyAndAssignController(bytes32 salt, address controller)\n  external\n  returns (bytes32 key);\n```\nTransfer control over deployment to the home address corresponding to a given derived key. The caller must be designated as the current controller of the home address - This condition can be checked by calling `getHomeAddressInformation` with the key obtained via `getDerivedKey`.\n\n##### parameters:\n| | | |\n|-|-|-|\n| *bytes32* | salt | The desired salt value to use *(along with the address of the caller)* when deriving the resultant key and corresponding home address. |\n| *address* | controller | The account that will be granted control of the home address corresponding to the given derived key.\n\n##### returns:\n| | | |\n|-|-|-|\n| *bytes32* | key | The derived key. |\n\n\u003e The controller cannot be designated as the address of this contract, the null address, or the home address *(the restriction on setting the home address as the controller is due to the fact that the home address will not be able to deploy to itself, as it needs to be empty before a contract can be deployed to it)*.\n\n### deriveKeyAndRelinquishControl\n---\n```Solidity\nfunction deriveKeyAndRelinquishControl(bytes32 salt)\n  external\n  returns (bytes32 key);\n```\nTransfer control over deployment to the home address corresponding to a given derived key to the null address, which will prevent it from being deployed to again in the future. The caller must be designated as the current controller of the home address - This condition can be checked by calling `getHomeAddressInformation` with the key determined by calling `getDerivedKey`.\n\n##### parameters:\n| | | |\n|-|-|-|\n| *bytes32* | salt | The desired salt value to use *(along with the address of the caller)* when deriving the resultant key and corresponding home address. |\n\n##### returns:\n| | | |\n|-|-|-|\n| *bytes32* | key | The derived key. |\n\n### setReverseLookup\n---\n```Solidity\nfunction setReverseLookup(bytes32 key) external;\n```\nRecord a key that corresponds to a given home address by supplying said key and using it to derive the address. This enables reverse lookup of a key using only the home address in question.\n\nThis method may be called by anyone - control of the key is not required.\n\n##### parameters:\n| | | |\n|-|-|-|\n| *bytes32* | key | The unique value used to derive the home address. |\n\n\u003e This does not set the salt or submitter fields, as those apply only to derived keys *(although a derived key may also be set with this method, just without the derived fields)*.\n\n### setDerivedReverseLookup\n---\n```Solidity\nfunction setDerivedReverseLookup(bytes32 salt, address submitter) external;\n```\n@notice Record the derived key that corresponds to a given home address by supplying the salt and submitter that were used to derive the key. This facititates reverse lookup of the derivation method of a key using only the home address in question. \n\nThis method may be called by anyone - control of the derived key is not required.\n\n##### parameters:\n| | | |\n|-|-|-|\n| *bytes32* | salt | The desired salt value to use *(along with the address of the caller)* when deriving the resultant key and corresponding home address. |\n| *address* | submitter | The account that can submit the salt that is used to derive the key. |\n\n### deployRuntimeStorageContract\n---\n```Solidity\nfunction deployRuntimeStorageContract(bytes calldata codePayload)\n  external\n  returns (address runtimeStorageContract);\n```\nDeploy a new storage contract with the supplied code as runtime code without deploying a contract to a home address. This can be used to store the contract creation code for use in future deployments of contracts to home addresses.\n\n##### parameters:\n| | | |\n|-|-|-|\n| *bytes* | codePayload | The code to set as the runtime code of the deployed contract. |\n\n##### returns:\n| | | |\n|-|-|-|\n| *address* | runtimeStorageContract | The address of the deployed runtime storage contract. |\n\n\u003e If you plan on reusing the runtime storage contract, consider placing adequate protections on it to prevent unwanted callers from modifying or destroying it. \n\u003e \n\u003e Also, if you are placing contract contract creation code into the runtime storage contract, remember to include any constructor parameters as ABI-encoded arguments at the end of the contract creation code, similar to how you would perform a standard deployment.\n\n### deployViaExistingRuntimeStorageContract\n---\n```Solidity\nfunction deployViaExistingRuntimeStorageContract(\n  bytes32 key,\n  address initializationRuntimeStorageContract\n)\n  external\n  payable\n  returns (address homeAddress, bytes32 runtimeCodeHash);\n```\nDeploy a new contract, with the supplied `msg.value` and the initialization code stored in the runtime code at the specified initialization runtime storage contract, to the home address corresponding to a given key. Two conditions must be met:\n* the submitter must be designated as the controller of the home address *(with the initial controller set to the address corresponding to the first twenty bytes of the key)*, and\n* there must not be a contract currently deployed at the home address.\n\nThese conditions can be checked by calling `getHomeAddressInformation` and `isDeployable` with the same key.\n\n##### parameters:\n| | | |\n|-|-|-|\n| *bytes32* | key | The unique value used to derive the home address. |\n| *address* | initializationRuntimeStorageContract | The storage contract with runtime code equal to the contract creation code that will be used to deploy the contract to the home address. |\n\n##### returns:\n| | | |\n|-|-|-|\n| *address* | homeAddress | The home address of the deployed contract. |\n| *bytes32* | runtimeCodeHash | The runtime code hash of the deployed contract. |\n\n\u003e When deploying a contract to a home address via this method, the metamorphic initialization code will retrieve whatever initialization code currently resides at the specified address and use it to set up and deploy the desired contract to the home address.\n\u003e \n\u003e Bear in mind that the deployed contract will interpret `msg.sender` as the address of THIS contract, and not the address of the submitter - if the constructor of the deployed contract uses `msg.sender` to set up ownership or other variables, you must modify it to accept a constructor argument with the appropriate address, or alternately to hard-code the intended address. \n\u003e \n\u003e Also, if your contract DOES have constructor arguments, remember to include them as ABI-encoded arguments at the end of the initialization code, just as you would when performing a standard deploy.\n\u003e \n\u003e You may also want to provide the key to `setReverseLookup` in order to find it again using only the home address to prevent accidentally losing the key.\n\n### redeemAndDeployViaExistingRuntimeStorageContract\n---\n```Solidity\nfunction redeemAndDeployViaExistingRuntimeStorageContract(\n  uint256 tokenId,\n  address controller,\n  address initializationRuntimeStorageContract\n)\n  external\n  payable\n  returns (address homeAddress, bytes32 runtimeCodeHash);\n```\nBurn an ERC721 token, set a supplied controller, and deploy a new contract, with the supplied `msg.value` and the initialization code stored in the runtime code at the specified initialization runtime storage contract, to the home address corresponding to a given key. Two conditions must be met:\n* The submitter must be designated as either the owner of the token or as an approved spender, and\n* there must not be a contract currently deployed at the home address.\n\nThese conditions can be checked by calling either `ownerOf` or `getApproved` for the `tokenId` *(or* `isApprovedForAll` *for the owner of the token and the caller)*, and `isDeployable` with the `bytes32` representation of the `tokenId`.\n\n##### parameters:\n| | | |\n|-|-|-|\n| *uint256* | tokenId | The ID of the ERC721 NFT to redeem. |\n| *address* | controller | The account that will be granted control of the home address corresponding to the given NFT. |\n| *address* | initializationRuntimeStorageContract | The storage contract with runtime code equal to the contract creation code that will be used to deploy the contract to the home address. |\n\n##### returns:\n| | | |\n|-|-|-|\n| *address* | homeAddress | The home address of the deployed contract. |\n| *bytes32* | runtimeCodeHash | The runtime code hash of the deployed contract. |\n\n\u003e When deploying a contract to a home address via this method, the metamorphic initialization code will retrieve whatever initialization code currently resides at the specified address and use it to set up and deploy the desired contract to the home address.\n\u003e \n\u003e Bear in mind that the deployed contract will interpret `msg.sender` as the address of THIS contract, and not the address of the submitter - if the constructor of the deployed contract uses `msg.sender` to set up ownership or other variables, you must modify it to accept a constructor argument with the appropriate address, or alternately to hard-code the intended address. \n\u003e \n\u003e Also, if your contract DOES have constructor arguments, remember to include them as ABI-encoded arguments at the end of the initialization code, just as you would when performing a standard deploy.\n\u003e \n\u003e You may also want to provide the key to `setReverseLookup` in order to find it again using only the home address to prevent accidentally losing the key.\n\u003e \n\u003e The controller cannot be designated as the address of this contract, the null address, or the home address (the restriction on setting the home address as the controller is due to the fact that the home address will not be able to deploy to itself, as it needs to be empty before a contract can be deployed to it).\n\u003e \n\u003e Also, checks on the contract at the home address being empty or not having the correct controller are unnecessary, as they are performed when minting the token and cannot be altered until the token is redeemed.\n\n### deriveKeyAndDeploy\n---\n```Solidity\nfunction deriveKeyAndDeploy(bytes32 salt, bytes calldata initializationCode)\n  external\n  payable\n  returns (address homeAddress, bytes32 key, bytes32 runtimeCodeHash);\n```\nDeploy a new contract with the supplied `msg.value` and initialization code to the home address corresponding to a given derived key. Two conditions must be met:\n* the submitter must be designated as the controller of the home address corresponding to the derived key, and\n* there must not be a contract currently deployed at the home address.\n\nThese conditions can be checked by calling `getHomeAddressInformation` and `isDeployable` with the key determined by calling `getDerivedKey`.\n\n##### parameters:\n| | | |\n|-|-|-|\n| *bytes32* | salt | The desired salt value to use *(along with the address of the caller)* when deriving the resultant key and corresponding home address. |\n| *bytes* | initializationCode | The contract creation code that will be used to deploy the contract to the home address. |\n\n##### returns:\n| | | |\n|-|-|-|\n| *address* | homeAddress | The home address of the deployed contract. |\n| *bytes32* | key | The derived key. |\n| *bytes32* | runtimeCodeHash | The runtime code hash of the deployed contract. |\n\n\n\u003e In order to deploy the contract to the home address, a new contract will be deployed with runtime code set to the initialization code of the contract that will be deployed to the home address. Then, metamorphic initialization code will retrieve that initialization code and use it to set up and deploy the desired contract to the home address.\n\u003e \n\u003e Bear in mind that the deployed contract will interpret `msg.sender` as the address of THIS contract, and not the address of the submitter - if the constructor of the deployed contract uses `msg.sender` to set up ownership or other variables, you must modify it to accept a constructor argument with the appropriate address, or alternately to hard-code the intended address. \n\u003e \n\u003e Also, if your contract DOES have constructor arguments, remember to include them as ABI-encoded arguments at the end of the initialization code, just as you would when performing a standard deploy.\n\u003e \n\u003e You may want to provide the salt and submitter to `setDerivedReverseLookup` in order to find the salt, submitter, and derived key using only the home address to prevent accidentally losing them.\n\n### deriveKeyAndDeployViaExistingRuntimeStorageContract\n---\n```Solidity\nfunction deriveKeyAndDeployViaExistingRuntimeStorageContract(\n  bytes32 salt,\n  address initializationRuntimeStorageContract\n)\n  external\n  payable\n  returns (address homeAddress, bytes32 key, bytes32 runtimeCodeHash);\n```\nDeploy a new contract, with the supplied `msg.value` and the initialization code stored in the runtime code at the specified initialization runtime storage contract, to the home address corresponding to a given derived key. Two conditions must be met:\n* the submitter must be designated as the controller of the home address corresponding to the derived key, and\n* there must not be a contract currently deployed at the home address.\n\nThese conditions can be checked by calling `getHomeAddressInformation` and `isDeployable` with the key determined by calling `getDerivedKey`.\n\n##### parameters:\n| | | |\n|-|-|-|\n| *bytes32* | salt | The desired salt value to use *(along with the address of the caller)* when deriving the resultant key and corresponding home address. |\n| *address* | initializationRuntimeStorageContract | The storage contract with runtime code equal to the contract creation code that will be used to deploy the contract to the home address. |\n\n##### returns:\n| | | |\n|-|-|-|\n| *address* | homeAddress | The home address of the deployed contract. |\n| *bytes32* | key | The derived key. |\n| *bytes32* | runtimeCodeHash | The runtime code hash of the deployed contract. |\n\n\n\u003e When deploying a contract to a home address via this method, the metamorphic initialization code will retrieve whatever initialization code currently resides at the specified address and use it to set up and deploy the desired contract to the home address.\n\u003e \n\u003e Bear in mind that the deployed contract will interpret `msg.sender` as the address of THIS contract, and not the address of the submitter - if the constructor of the deployed contract uses `msg.sender` to set up ownership or other variables, you must modify it to accept a constructor argument with the appropriate address, or alternately to hard-code the intended address. \n\u003e \n\u003e Also, if your contract DOES have constructor arguments, remember to include them as ABI-encoded arguments at the end of the initialization code, just as you would when performing a standard deploy.\n\u003e \n\u003e You may want to provide the salt and submitter to `setDerivedReverseLookup` in order to find the salt, submitter, and derived key using only the home address to prevent accidentally losing them.\n\n### batchLock\n---\n```Solidity\nfunction batchLock(address owner, bytes32[] calldata keys) external;\n```\nMint multiple ERC721 tokens, designated by their keys, to the specified owner. Keys that aren't controlled, or that point to home addresses that are currently deployed, will be skipped.\n\n##### parameters:\n| | | |\n|-|-|-|\n| *address* | owner | The account that will be granted ownership of the ERC721 tokens. |\n| *bytes32[]* | keys | An array of unique values used to derive each home address. |\n\n\u003e If you plan to use this method regularly or want to keep gas costs to an absolute minimum, and are willing to go without standard ABI encoding, see `batchLock_63efZf` for a more efficient (and unforgiving) implementation.\n\u003e \n\u003e For batch token minting with *derived* keys, see `deriveKeysAndBatchLock`.\n\n### deriveKeysAndBatchLock\n---\n```Solidity\nfunction deriveKeysAndBatchLock(address owner, bytes32[] calldata salts)\n  external;\n```\nMint multiple ERC721 tokens, designated by salts that are hashed with the caller's address to derive each key, to the specified owner. Derived keys that aren't controlled, or that point to home addresses that are currently deployed, will be skipped.\n\n##### parameters:\n| | | |\n|-|-|-|\n| *address* | owner | The account that will be granted ownership of the ERC721 tokens. |\n| *bytes32[]* | salts | An array of values used to derive each key and corresponding home address. |\n\n\u003e See `batchLock` for batch token minting with standard, non-derived keys.\n\n### batchLock_63efZf\n---\n```Solidity\nfunction batchLock_63efZf(/* packed owner and key segments */) external;\n```\nEfficient version of `batchLock` that uses less gas.\n\nThe first twenty bytes of each key are automatically populated using `msg.sender`, and the remaining key segments are passed in as a packed byte array, using twelve bytes per segment.\n\nA function selector of `0x00000000` followed by a twenty-byte segment for the desired owner of the minted ERC721 tokens, are both placed before the array of key segments.\n\n\u003e Note that an attempt to lock a key that is not controlled, or one with its contract already deployed, will cause the entire batch to revert.\n\u003e \n\u003e Checks on whether the owner is a valid ERC721 receiver are also skipped, similar to using `transferFrom` instead of `safeTransferFrom`.\n\n### claimHighScore\n---\n```Solidity\nfunction claimHighScore(bytes32 key) external;\n```\nSubmit a key to claim the \"high score\" - the lower the `uint160` value of the key's home address, the higher the score.\n\nThe high score holder has the exclusive right to recover lost ether and tokens on this contract.\n\n##### parameters:\n| | | |\n|-|-|-|\n| *bytes32* | key | The unique value used to derive the home address that will determine the resultant score. |\n\n\u003e The high score must be claimed by a direct key *(one that is submitted by setting the first twenty bytes of the key to the address of the submitter)* and not by a derived key, and is non-transferable.\n\u003e \n\u003e If you want to help people recover their lost tokens, you might consider deploying a contract to the high score address *(probably a destructible one so that you can use the home address later)* with your contact information.\n\n### recover\n---\n```Solidity\nfunction recover(IERC20 token, address payable recipient) external;\n```\nTransfer any ether or ERC20 tokens that have somehow ended up at this contract by specifying a token address *(set to the null address for ether)* as well as a recipient address.\n\nOnly the high score holder can recover lost ether and tokens on this contract.\n\n##### parameters:\n| | | |\n|-|-|-|\n| *address* | token | The contract address of the ERC20 token to recover, or the null address for recovering Ether. |\n| *address* | recipient | The account where recovered funds should be transferred. |\n\n\u003e If you are trying to recover funds that were accidentally sent into this contract, see if you can contact the holder of the current high score, found by calling `getHighScore`. Better yet, try to find a new high score yourself!\n\n### isDeployable\n---\n```Solidity\nfunction isDeployable(bytes32 key)\n  external\n  /* view */\n  returns (bool deployable);\n```\n\"View\" function to determine if a contract can currently be deployed to a home address given the corresponding key. A contract is only deployable if no account currently exists at the address - any existing contract must be destroyed via `SELFDESTRUCT` before a new contract can be deployed to a home address.\n\n\n##### parameters:\n| | | |\n|-|-|-|\n| *bytes32* | key | The unique value used to derive the home address. |\n\n##### returns:\n| | | |\n|-|-|-|\n| *bool* | deployable | A boolean signifying if a contract can be deployed to the home address that corresponds to the provided key. |\n\n\n@param key bytes32 The unique value used to derive the home address.\n@return A boolean signifying if a contract can be deployed to the home address that corresponds to the provided key.\n\u003e This method does not modify state but is inaccessible via `STATICCALL` *(well, it actually does modify state, but only temporarily)*.\n\u003e \n\u003e This method will not detect if a contract is not deployable due control having been relinquished on the key.\n\n### getHighScore\n---\n```Solidity\nfunction getHighScore()\n  external\n  view\n  returns (address holder, uint256 score, bytes32 key);\n```\nView function to get the current \"high score\", or the lowest uint160 value of a home address of all keys submitted. The high score holder has the exclusive right to recover lost ether and tokens on this contract.\n\n##### returns:\n| | | |\n|-|-|-|\n| *address* | holder | The account that submitted the current high score. |\n| *uint256* | score | The current high score. |\n| *bytes32* | key | The key that was submitted to obtain the current high score. |\n\n### getHomeAddressInformation\n---\n```Solidity\nfunction getHomeAddressInformation(bytes32 key)\n  external\n  view\n  returns (\n    address homeAddress,\n    address controller,\n    uint256 deploys,\n    bytes32 currentRuntimeCodeHash\n  );\n```\nView function to get information on a home address given the corresponding key.\n\n##### parameters:\n| | | |\n|-|-|-|\n| *bytes32* | key | The unique value used to derive the home address. |\n\n##### returns:\n| | | |\n|-|-|-|\n| *address* | homeAddress | The home address of the supplied key. |\n| *address* | controller | The current controller of deployments to the home address. |\n| *uint256* | deploys | The number of times that a contract has been deployed to the home address. |\n| *bytes32* | currentRuntimeCodeHash | The runtime code hash of the contract code currently at the home address *(if any)*. |\n\n\u003e There is also an `isDeployable` method for determining if a contract can be deployed to the address, but in extreme cases it must actually perform a dry-run to determine if the contract is deployable, which means that it does not support `STATICCALL`s.\n\u003e \n\u003e There is also a convenience method, `hasNeverBeenDeployed`, but the information it conveys can be determined from this method alone as well.\n\n### hasNeverBeenDeployed\n---\n```Solidity\nfunction hasNeverBeenDeployed(bytes32 key)\n  external\n  view\n  returns (bool neverBeenDeployed);\n```\nView function to determine if no contract has ever been deployed to a home address given the corresponding key. This can be used to ensure that a given key or corresponding token is \"new\" or not.\n\n##### parameters:\n| | | |\n|-|-|-|\n| *bytes32* | key | The unique value used to derive the home address. |\n\n##### returns:\n| | | |\n|-|-|-|\n| *bool* | neverBeenDeployed | A boolean signifying if a contract has never been deployed using the supplied key before. |\n\n### reverseLookup\n---\n```Solidity\nfunction reverseLookup(address homeAddress)\n  external\n  view\n  returns (bytes32 key, bytes32 salt, address submitter);\n```\nView function to search for a known key, salt, and/or submitter given a supplied home address. Keys can be controlled directly by an address that matches the first 20 bytes of the key, or they can be derived from a salt and a submitter - if the key is not a derived key, the salt and submitter fields will both have a value of zero.\n\n##### parameters:\n| | | |\n|-|-|-|\n| *address* | homeAddress | The home address to perform a reverse lookup on. |\n\n##### returns:\n| | | |\n|-|-|-|\n| *bytes32* | key | The key corresponding to the supplied home address. |\n| *bytes32* | salt | The salt value that is used to derive the key - always `0x0` for non-derived keys. |\n| *address* | submitter | The submitter of the salt value used to derive the key - always `0x0` for non-derived keys. |\n\n\n\u003e To populate these values, call `setReverseLookup` for cases where keys are used directly or are the only value known, and `setDerivedReverseLookup` for cases where keys are derived from a known salt and submitter.\n\u003e \n\u003e The absence of a submitter does not necessarily mean that the key is not a derived key. All it implies is that the salt and submitter were not provided. However, the *existence* of a submitter does imply that the key is a derived key *(and not a standard key)*.\n\n### getDerivedKey\n---\n```Solidity\nfunction getDerivedKey(bytes32 salt, address submitter)\n  external\n  pure\n  returns (bytes32 key);\n```\nPure function to determine the key that is derived from a given salt and submitting address.\n\n##### parameters:\n| | | |\n|-|-|-|\n| *bytes32* | salt | The salt value that is used to derive the key. |\n| *address* | submitter | The submitter of the salt value used to derive the key. |\n\n##### returns:\n| | | |\n|-|-|-|\n| *bytes32* | key | The derived key. |\n\n### getHomeAddress\n---\n```Solidity\nfunction getHomeAddress(bytes32 key)\n  external\n  pure\n  returns (address homeAddress);\n```\nPure function to determine the home address that corresponds to a given key.\n\n##### parameters:\n| | | |\n|-|-|-|\n| *bytes32* | key | The unique value used to derive the home address. |\n\n##### returns:\n| | | |\n|-|-|-|\n| *address* | homeAddress | The home address of the supplied key. |\n\n### getMetamorphicDelegatorInitializationCode\n---\n```Solidity\nfunction getMetamorphicDelegatorInitializationCode()\n  external\n  pure\n  returns (bytes32 metamorphicDelegatorInitializationCode);\n```\nPure function for retrieving the metamorphic initialization code used to deploy arbitrary contracts to home addresses. Provided for easy verification and for use in other applications.\n\n##### returns:\n| | | |\n|-|-|-|\n| *bytes32* | metamorphicDelegatorInitializationCode | The 32-byte metamorphic initialization code. |\n\n\u003e This metamorphic init code works via the \"metamorphic delegator\" mechanism, which is explained in greater detail in the \"How It Works\" section.\n\n### getMetamorphicDelegatorInitializationCodeHash\n---\n```Solidity\nfunction getMetamorphicDelegatorInitializationCodeHash()\n  external\n  pure\n  returns (bytes32 metamorphicDelegatorInitializationCodeHash);\n```\nPure function for retrieving the keccak256 of the metamorphic initialization code used to deploy arbitrary contracts to home addresses. This is the value that you should use, along with this contract's address and a caller address that you control, to mine for an partucular type of home address *(such as one at a compact or gas-efficient address)*.\n\n##### returns:\n| | | |\n|-|-|-|\n| *bytes32* | metamorphicDelegatorInitializationCodeHash | The keccak256 hash of the metamorphic initialization code. |\n\n### getArbitraryRuntimeCodePrelude\n---\n```Solidity\nfunction getArbitraryRuntimeCodePrelude()\n  external\n  pure\n  returns (bytes11 prelude);\n```\nPure function for retrieving the prelude that will be inserted ahead of the code payload in order to deploy a runtime storage contract.\n\n##### returns:\n| | | |\n|-|-|-|\n| *bytes11* | prelude | The 11-byte \"arbitrary runtime\" prelude. |\n\n### NewResident event\n---\n```Solidity\nevent NewResident(\n  address indexed homeAddress,\n  bytes32 key,\n  bytes32 runtimeCodeHash\n);\n```\nFires when a contract is deployed or redeployed to a given home address.\n\n##### parameters:\n| | | |\n|-|-|-|\n| *address* | homeAddress | The home address of the deployed contract. |\n| *bytes32* | key | The key corresponding to the home address. |\n| *bytes32* | runtimeCodeHash | The runtime code hash of the deployed contract. |\n\n### NewRuntimeStorageContract event\n---\n```Solidity\nevent NewRuntimeStorageContract(\n  address runtimeStorageContract,\n  bytes32 runtimeCodeHash\n);\n```\nFires when a new runtime storage contract is deployed.\n\n##### parameters:\n| | | |\n|-|-|-|\n| *address* | runtimeStorageContract | The address of the deployed runtime storage contract. |\n| *bytes32* | runtimeCodeHash | The runtime code hash of the deployed contract. |\n\n### NewController event\n---\n```Solidity\nevent NewController(bytes32 indexed key, address newController);\n```\nFires when a controller is changed from the default controller.\n\n##### parameters:\n| | | |\n|-|-|-|\n| *bytes32* | key | The key for which control has been reassigned. |\n| *address* | controller | The account that has been granted control of the given key. |\n\n### NewHighScore event\n---\n```Solidity\nevent NewHighScore(bytes32 key, address submitter, uint256 score);\n```\nFires when a new high score is submitted.\n\n##### parameters:\n| | | |\n|-|-|-|\n| *bytes32* | key | The key that was submitted to obtain the current high score. |\n| *address* | holder | The account that submitted the current high score. |\n| *uint256* | score | The current high score. |\n\n\n## How It Works\nHomeWork deploys contracts using the **metamorphic delegator** pattern. The same contract creation bytecode is used for all deployments, but the bytecode is non-deterministic: it simply retrieves an account address from HomeWork, then performs a `DELEGATECALL` to that address, executing the bytecode there and passing along the return or revert values. The contract at the retrieved address is a **runtime storage contract** that contains the **contract creation code** for the *actual* contract. Constructor logic is executed in the context of the home address, and the runtime code returned by the `DELEGATECALL` will be set as the runtime code of the home address.\n\nThe metamorphic delegator pattern confers a few key benefits over other metamorphic deployment methods:\n- Constructors are fully supported *(in contrast to patterns where code is simply cloned from another account)*\n- Address derivation can be performed in one hash / step *(vs. using a transient metamorphic contract, deployed via `CREATE2` that deploys the target contract via `CREATE` and `SELFDESTRUCT`s, which takes 2 steps)*\n- Runtime storage contracts do not need to be deployed every time and can safely be reused *(as opposed to retrieving, deploying, and `DELEGATECALL`ing all in the scope of the metamorphic creation code)*\n\nHere's the 32-byte sequence for deploying contracts:\n```\n0x5859385958601c335a585952fa1582838382515af43d3d93833e601e57fd5bf3\n\nPC  OP  NAME             [STACK] + \u003cMEMORY\u003e + {RETURN} + *RUNTIME*\n--  --  ---------------  ----------------------------------------------------\n00  58  PC               [0]\n01  59  MSIZE            [0, 0]\n02  38  CODESIZE         [0, 0, codesize -\u003e 32]\n03  59  MSIZE            [0, 0, 32, 0]\n04  58  PC               [0, 0, 32, 0, 4]\n05  60  PUSH1 0x1c       [0, 0, 32, 0, 4, 28]\n07  33  CALLER           [0, 0, 32, 0, 4, 28, caller]\n08  5a  GAS              [0, 0, 32, 0, 4, 28, caller, gas]\n09  58  PC               [0, 0, 32, 0, 4, 28, caller, gas, 9 -\u003e selector]\n10  59  MSIZE            [0, 0, 32, 0, 4, 28, caller, gas, selector, 0]\n11  52  MSTORE           [0, 0, 32, 0, 4, 28, caller, gas] \u003cselector\u003e\n12  fa  STATICCALL       [0, 0, 1 =\u003e success] \u003cinit_in_runtime_address\u003e\n13  15  ISZERO           [0, 0, 0]\n14  82  DUP3             [0, 0, 0, 0]\n15  83  DUP4             [0, 0, 0, 0, 0]\n16  83  DUP4             [0, 0, 0, 0, 0, 0]\n17  82  DUP3             [0, 0, 0, 0, 0, 0, 0]\n18  51  MLOAD            [0, 0, 0, 0, 0, 0, init_in_runtime_address]\n19  5a  GAS              [0, 0, 0, 0, 0, 0, init_in_runtime_address, gas]\n20  f4  DELEGATECALL     [0, 0, 1 =\u003e success] {runtime_code_or_revert_msg}\n21  3d  RETURNDATASIZE   [0, 0, 1 =\u003e success, size]\n22  3d  RETURNDATASIZE   [0, 0, 1 =\u003e success, size, size]\n23  93  SWAP4            [size, 0, 1 =\u003e success, size, 0]\n24  83  DUP4             [size, 0, 1 =\u003e success, size, 0, 0]\n25  3e  RETURNDATACOPY   [size, 0, 1 =\u003e success] \u003cruntime_code_or_revert_msg\u003e\n26  60  PUSH1 0x1e       [size, 0, 1 =\u003e success, 30]\n28  57  JUMPI            [size, 0]\n29  fd  REVERT           [] {revert_msg}\n30  5b  JUMPDEST         [size, 0]\n31  f3  RETURN           [] *runtime_code*\n```\n\n## Maintainers\n\n[@0age](https://github.com/0age)\n\n## Contribute\n\nPRs accepted gladly - make sure the tests and linters pass. *(Changes to the contracts themselves should bump the version number and be marked as pre-release.)*\n\n## License\n\nMIT © 2019 0age\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2F0age%2FHomeWork","html_url":"https://awesome.ecosyste.ms/projects/github.com%2F0age%2FHomeWork","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2F0age%2FHomeWork/lists"}