{"id":860,"date":"2023-03-29T22:50:45","date_gmt":"2023-03-29T14:50:45","guid":{"rendered":"https:\/\/vinta.ws\/code\/?p=860"},"modified":"2026-03-17T01:18:24","modified_gmt":"2026-03-16T17:18:24","slug":"solidity-create-vs-create2","status":"publish","type":"post","link":"https:\/\/vinta.ws\/code\/solidity-create-vs-create2.html","title":{"rendered":"Solidity: CREATE vs CREATE2"},"content":{"rendered":"<p>In Solidity, there are two opcodes for creating contracts: <code>CREATE<\/code> and <code>CREATE2<\/code>. Also, the deployed contract address can be precomputed via:<\/p>\n<ul>\n<li><code>keccak256(deployerAddress, deployerNonce)<\/code> if you're using <code>CREATE<\/code> opcode<\/li>\n<li><code>keccak256(0xFF, deployerAddress, salt, bytecode)<\/code> if you're using <code>CREATE2<\/code> opcode<\/li>\n<\/ul>\n<p>ref:<br \/>\n<a href=\"https:\/\/ethereum.stackexchange.com\/questions\/101336\/what-is-the-benefit-of-using-create2-to-create-a-smart-contract\">https:\/\/ethereum.stackexchange.com\/questions\/101336\/what-is-the-benefit-of-using-create2-to-create-a-smart-contract<\/a><\/p>\n<h2>CREATE<\/h2>\n<p>Default opcode used when deploying smart contracts. If you're deploying a contract using <code>new YourContract()<\/code> without <code>salt<\/code>, then you're using <code>CREATE<\/code>.<\/p>\n<p>The following code written in TypeScript and ethers.js, shows how to deploy a contract using <code>CREATE<\/code> under the hood:<\/p>\n<pre class=\"line-numbers\"><code class=\"language-typescript\">import { ethers } from 'ethers';\n\nconst deployer = await ethers.getNamedSigner(\"deployer\")\nconst nonce = await deployer.getTransactionCount()\nconst computedAddress = ethers.utils.getContractAddress({\n    from: deployer.address,\n    nonce: nonce,\n})\nconsole.log(<code>computed address: ${computedAddress}<\/code>)\n\nconst ktbArbitrageurFactory = await ethers.getContractFactory(\"KtbArbitrageur\", deployer)\nconst ktbArbitrageur = await ktbArbitrageurFactory.deploy(oinchAggregationRouterV5)\nconsole.log(<code>deployed address: ${ktbArbitrageur.address}<\/code>)<\/code><\/pre>\n<p>Though it's pretty inefficient, but you can specify the deployed address (to some extent) by keeping increasing <code>nonce<\/code> until it meets some conditions you set:<\/p>\n<pre class=\"line-numbers\"><code class=\"language-typescript\">async increaseNonceToDeployUpgradeable(condition: string, targetAddr: string) {\n    const { ethers } = this._hre\n    const deployer = await ethers.getNamedSigner(\"deployer\")\n\n    \/\/ We use deployer's address and nonce to compute a contract's address which deployed with that nonce,\n    \/\/ to find the nonce that matches the condition\n    let nonce = await deployer.getTransactionCount()\n    console.log(<code>Next nonce: ${nonce}<\/code>)\n\n    let computedAddress = \"0x0\"\n    let count = 0\n    while (\n        count &lt; 2 ||\n        (condition == \"GREATER_THAN\"\n            ? computedAddress.toLowerCase() &lt;= targetAddr.toLowerCase()\n            : computedAddress.toLowerCase() &gt;= targetAddr.toLowerCase())\n    ) {\n        \/\/ Increase the nonce until we find a contract address that matches the condition\n        computedAddress = ethers.utils.getContractAddress({\n            from: deployer.address,\n            nonce: nonce,\n        })\n        console.log(<code>Computed address: ${nonce}, ${computedAddress}<\/code>)\n        nonce += 1\n        count += 1\n    }\n\n    \/\/ When deploying an upgradeable contract,\n    \/\/ it will deploy the implementation contract first, then deploy the proxy\n    \/\/ so we need to increase the nonce to \"the expected nonce - 1\"\n    let nextNonce = await deployer.getTransactionCount()\n    for (let i = 0; i &lt; count - 1 - 1; i++) {\n        nextNonce += 1\n        console.log(<code>Increasing nonce to ${nextNonce}<\/code>)\n        const tx = await deployer.sendTransaction({\n            to: deployer.address,\n            value: ethers.utils.parseEther(\"0\"),\n        })\n        await tx.wait()\n    }\n\n    console.log(<code>Finalized nonce<\/code>)\n}<\/code><\/pre>\n<p>ref:<br \/>\n<a href=\"https:\/\/docs.ethers.org\/v5\/api\/utils\/address\/#utils-getContractAddress\">https:\/\/docs.ethers.org\/v5\/api\/utils\/address\/#utils-getContractAddress<\/a><\/p>\n<h2>CREATE2<\/h2>\n<p>The Solidity code below demonstrates how to deploy a contract using <code>CREATE2<\/code> which is introduced in EIP-1014 to provide more flexible and predictable address generation:<\/p>\n<pre class=\"line-numbers\"><code class=\"language-solidity\">bytes32 salt = bytes32(\"perp\");\naddress oinchAggregationRouterV5 = 0x1111111254EEB25477B68fb85Ed929f73A960582;\n\naddress computedAddress = address(\n    uint256(\n        keccak256(\n            abi.encodePacked(\n                bytes1(0xff), \/\/ avoid conflict with CREATE\n                address(this), \/\/ deployer\n                salt,\n                keccak256(\n                    abi.encodePacked(\n                        type(KtbArbitrageur).creationCode, \/\/ bytecode\n                        abi.encode(oinchAggregationRouterV5) \/\/ constructor parameter\n                    )\n                )\n            )\n        )\n    )\n);\n\nKtbArbitrageur ktbArbitrageur = new KtbArbitrageur{ salt: salt }(oinchAggregationRouterV5);\nconsole.logAddress(address(ktbArbitrageur));\nconsole.logAddress(computedAddress);<\/code><\/pre>\n<p>You can change <code>salt<\/code> to an arbitrary value to produce different contract addresses.<\/p>\n<p>ref:<br \/>\n<a href=\"https:\/\/docs.soliditylang.org\/en\/v0.7.6\/control-structures.html#salted-contract-creations-create2\">https:\/\/docs.soliditylang.org\/en\/v0.7.6\/control-structures.html#salted-contract-creations-create2<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>How to deploy a contract using `CREATE2` which is introduced in EIP-1014 to provide more flexible address generation.<\/p>\n","protected":false},"author":1,"featured_media":861,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[137],"tags":[138,144,11,147,143,140],"class_list":["post-860","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-blockchain","tag-ethereum","tag-ethers-js","tag-javascript","tag-smart-contract","tag-solidity","tag-typescript"],"_links":{"self":[{"href":"https:\/\/vinta.ws\/code\/wp-json\/wp\/v2\/posts\/860","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/vinta.ws\/code\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/vinta.ws\/code\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/vinta.ws\/code\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/vinta.ws\/code\/wp-json\/wp\/v2\/comments?post=860"}],"version-history":[{"count":0,"href":"https:\/\/vinta.ws\/code\/wp-json\/wp\/v2\/posts\/860\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/vinta.ws\/code\/wp-json\/wp\/v2\/media\/861"}],"wp:attachment":[{"href":"https:\/\/vinta.ws\/code\/wp-json\/wp\/v2\/media?parent=860"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/vinta.ws\/code\/wp-json\/wp\/v2\/categories?post=860"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/vinta.ws\/code\/wp-json\/wp\/v2\/tags?post=860"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}