From 7984e1a8a0fea8d1264a58358d2d9b0c5d0d6f5a Mon Sep 17 00:00:00 2001 From: Tschakki Date: Mon, 15 Apr 2024 15:35:32 +0200 Subject: [PATCH] Deploy website - based on 14b308f2a016f0b2fea4e2822da4b5895323e14e --- 404.html | 2 +- assets/js/5f139d3e.10282a6d.js | 1 + assets/js/5f139d3e.75d8310a.js | 1 - assets/js/a8c021bd.0269c486.js | 1 - assets/js/a8c021bd.d8c9495e.js | 1 + ...time~main.03e2e4c7.js => runtime~main.7880ad69.js} | 2 +- building-on-lisk/add-token-to-lisk.html | 2 +- building-on-lisk/add-token-to-lisk/custom-token.html | 11 +++-------- .../add-token-to-lisk/standard-token.html | 8 ++------ .../deploying-smart-contract/with-Foundry.html | 2 +- .../deploying-smart-contract/with-Hardhat.html | 2 +- .../deploying-smart-contract/with-thirdweb.html | 2 +- .../interacting-with-the-blockchain/ethers.html | 2 +- .../interacting-with-the-blockchain/web3.html | 2 +- building-on-lisk/migration-guide.html | 2 +- category/building-on-lisk.html | 2 +- connecting-to-a-wallet.html | 2 +- contracts.html | 2 +- fees.html | 2 +- index.html | 2 +- interacting-with-blockchain/viem.html | 2 +- lisk-tools/api-providers.html | 2 +- lisk-tools/bridges.html | 2 +- lisk-tools/indexers.html | 2 +- lisk-tools/oracles.html | 2 +- lisk-tools/utilities.html | 2 +- markdown-page.html | 2 +- network-info.html | 2 +- search.html | 2 +- 29 files changed, 30 insertions(+), 39 deletions(-) create mode 100644 assets/js/5f139d3e.10282a6d.js delete mode 100644 assets/js/5f139d3e.75d8310a.js delete mode 100644 assets/js/a8c021bd.0269c486.js create mode 100644 assets/js/a8c021bd.d8c9495e.js rename assets/js/{runtime~main.03e2e4c7.js => runtime~main.7880ad69.js} (97%) diff --git a/404.html b/404.html index 5e4effb9f..2dbc6bcd9 100644 --- a/404.html +++ b/404.html @@ -5,7 +5,7 @@ Lisk Documentation - + diff --git a/assets/js/5f139d3e.10282a6d.js b/assets/js/5f139d3e.10282a6d.js new file mode 100644 index 000000000..f2b36cff7 --- /dev/null +++ b/assets/js/5f139d3e.10282a6d.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunklisk_docs=self.webpackChunklisk_docs||[]).push([[672],{8473:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>d,contentTitle:()=>a,default:()=>h,frontMatter:()=>s,metadata:()=>r,toc:()=>l});var o=n(5893),i=n(1151);const s={title:"Deploying a standard token",slug:"/building-on-lisk/add-token-to-lisk/standard-token",description:"Learn how to add your standard ERC-20 token to Lisk using the standard bridge.",keywords:["ERC-20 contract","Standard token","Lisk Testnet","Sepolia","Ethereum","Lisk Sepolia","Optimism Superchain token list"]},a="Deploying your Standard ERC-20 token to Lisk",r={id:"building-on-lisk/add-token-to-lisk/standard-token",title:"Deploying a standard token",description:"Learn how to add your standard ERC-20 token to Lisk using the standard bridge.",source:"@site/docs/building-on-lisk/add-token-to-lisk/standard-token.md",sourceDirName:"building-on-lisk/add-token-to-lisk",slug:"/building-on-lisk/add-token-to-lisk/standard-token",permalink:"/lisk-documentation/building-on-lisk/add-token-to-lisk/standard-token",draft:!1,unlisted:!1,editUrl:"https://github.com/LiskHQ/lisk-documentation/tree/main/docs/building-on-lisk/add-token-to-lisk/standard-token.md",tags:[],version:"current",frontMatter:{title:"Deploying a standard token",slug:"/building-on-lisk/add-token-to-lisk/standard-token",description:"Learn how to add your standard ERC-20 token to Lisk using the standard bridge.",keywords:["ERC-20 contract","Standard token","Lisk Testnet","Sepolia","Ethereum","Lisk Sepolia","Optimism Superchain token list"]},sidebar:"documentationSidebar",previous:{title:"Deploying an ERC-20 Token to Lisk",permalink:"/lisk-documentation/building-on-lisk/add-token-to-lisk"},next:{title:"Deploying a custom token",permalink:"/lisk-documentation/building-on-lisk/add-token-to-lisk/custom-token"}},d={},l=[{value:"Dependencies",id:"dependencies",level:2},{value:"Prerequisites",id:"prerequisites",level:2},{value:"Get ETH on Sepolia and Lisk Sepolia",id:"get-eth-on-sepolia-and-lisk-sepolia",level:3},{value:"Get an L1 ERC-20 Token Address",id:"get-an-l1-erc-20-token-address",level:3},{value:"Create an L2 ERC-20 token",id:"create-an-l2-erc-20-token",level:2},{value:"1. Add a private key to your environment",id:"1-add-a-private-key-to-your-environment",level:3},{value:"2. Add the Lisk Sepolia RPC URL to your environment",id:"2-add-the-lisk-sepolia-rpc-url-to-your-environment",level:3},{value:"3. Add your L1 ERC-20 token address to your environment",id:"3-add-your-l1-erc-20-token-address-to-your-environment",level:3},{value:"4. Deploy your L2 ERC-20 token",id:"4-deploy-your-l2-erc-20-token",level:3}];function c(e){const t={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",h3:"h3",li:"li",mdxAdmonitionTitle:"mdxAdmonitionTitle",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,i.a)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(t.h1,{id:"deploying-your-standard-erc-20-token-to-lisk",children:"Deploying your Standard ERC-20 token to Lisk"}),"\n",(0,o.jsxs)(t.p,{children:["In this tutorial, you'll learn how to bridge a standard ERC-20 token from Ethereum to Lisk using the ",(0,o.jsx)(t.a,{href:"https://docs.optimism.io/builders/dapp-developers/bridging/standard-bridge",children:"Standard Bridge system"}),".\nThis tutorial is meant for developers who already have an existing ERC-20 token on Ethereum and want to create a bridged representation of that token on Lisk."]}),"\n",(0,o.jsxs)(t.p,{children:["This tutorial explains how to use the ",(0,o.jsx)(t.a,{href:"https://github.com/ethereum-optimism/optimism/blob/186e46a47647a51a658e699e9ff047d39444c2de/packages/contracts-bedrock/contracts/universal/OptimismMintableERC20Factory.sol",children:(0,o.jsx)(t.code,{children:"OptimismMintableERC20Factory"})})," to deploy a standardized ERC-20 token on Lisk Sepolia.\nTokens created by this factory contract are compatible with the Standard Bridge system and include basic logic for deposits, transfers, and withdrawals.\nIf you want to include specialized logic within your L2 token, see the tutorial on ",(0,o.jsx)(t.a,{href:"./custom-token",children:"Bridging Your Custom ERC-20 Token to Lisk"})," instead."]}),"\n",(0,o.jsx)(t.h2,{id:"dependencies",children:"Dependencies"}),"\n",(0,o.jsxs)(t.ul,{children:["\n",(0,o.jsx)(t.li,{children:(0,o.jsx)(t.a,{href:"https://book.getfoundry.sh/getting-started/installation",children:"cast"})}),"\n"]}),"\n",(0,o.jsx)(t.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,o.jsx)(t.h3,{id:"get-eth-on-sepolia-and-lisk-sepolia",children:"Get ETH on Sepolia and Lisk Sepolia"}),"\n",(0,o.jsx)(t.p,{children:"This tutorial explains how to create a bridged ERC-20 token on Lisk Sepolia.\nYou will need to get some ETH on both of these testnets."}),"\n",(0,o.jsx)(t.admonition,{type:"info",children:(0,o.jsxs)(t.p,{children:["You can use ",(0,o.jsx)(t.a,{href:"https://sepoliafaucet.com/",children:"ETH Sepolia Faucet"})," to get ETH on Sepolia.\nYou can use the ",(0,o.jsx)(t.a,{href:"https://app.optimism.io/faucet?utm_source=docs",children:"Superchain Faucet"})," to get ETH on Lisk Sepolia."]})}),"\n",(0,o.jsx)(t.h3,{id:"get-an-l1-erc-20-token-address",children:"Get an L1 ERC-20 Token Address"}),"\n",(0,o.jsxs)(t.p,{children:["You will need an L1 ERC-20 token for this tutorial.\nIf you already have an L1 ERC-20 token deployed on Sepolia, you can skip this step.\nOtherwise, you can use the testing token located at ",(0,o.jsx)(t.a,{href:"https://sepolia.etherscan.io/address/0x5589BB8228C07c4e15558875fAf2B859f678d129",children:(0,o.jsx)(t.code,{children:"0x5589BB8228C07c4e15558875fAf2B859f678d129"})})," that includes a ",(0,o.jsx)(t.code,{children:"faucet()"})," function that can be used to mint tokens."]}),"\n",(0,o.jsx)(t.h2,{id:"create-an-l2-erc-20-token",children:"Create an L2 ERC-20 token"}),"\n",(0,o.jsxs)(t.p,{children:["Once you have an L1 ERC-20 token, you can use the ",(0,o.jsx)(t.a,{href:"https://github.com/ethereum-optimism/optimism/blob/186e46a47647a51a658e699e9ff047d39444c2de/packages/contracts-bedrock/contracts/universal/OptimismMintableERC20Factory.sol",children:(0,o.jsx)(t.code,{children:"OptimismMintableERC20Factory"})})," to create a corresponding L2 ERC-20 token on Lisk Sepolia.\nAll tokens created by the factory implement the ",(0,o.jsx)(t.code,{children:"IOptimismMintableERC20"})," interface and are compatible with the Standard Bridge system.\nTo create an L2 ERC-20 token, do the following:"]}),"\n",(0,o.jsx)(t.h3,{id:"1-add-a-private-key-to-your-environment",children:"1. Add a private key to your environment"}),"\n",(0,o.jsxs)(t.p,{children:["You'll need a private key in order to sign transactions.\nSet your private key as an environment variable with the ",(0,o.jsx)(t.code,{children:"export"})," command.\nMake sure this private key corresponds to an address that has ETH on Lisk Sepolia."]}),"\n",(0,o.jsx)(t.pre,{children:(0,o.jsx)(t.code,{className:"language-bash",children:"export TUTORIAL_PRIVATE_KEY=0x...\n"})}),"\n",(0,o.jsx)(t.h3,{id:"2-add-the-lisk-sepolia-rpc-url-to-your-environment",children:"2. Add the Lisk Sepolia RPC URL to your environment"}),"\n",(0,o.jsxs)(t.p,{children:["You'll need an RPC URL in order to connect to Lisk Sepolia.\nSet your RPC URL as an environment variable with the ",(0,o.jsx)(t.code,{children:"export"})," command."]}),"\n",(0,o.jsx)(t.pre,{children:(0,o.jsx)(t.code,{className:"language-bash",children:"export TUTORIAL_RPC_URL=https://rpc.sepolia-api.lisk.com\n"})}),"\n",(0,o.jsx)(t.h3,{id:"3-add-your-l1-erc-20-token-address-to-your-environment",children:"3. Add your L1 ERC-20 token address to your environment"}),"\n",(0,o.jsxs)(t.p,{children:["You'll need to know the address of your L1 ERC-20 token in order to create a bridged representation of it on Lisk Sepolia.\nSet your L1 ERC-20 token address as an environment variable with the ",(0,o.jsx)(t.code,{children:"export"})," command."]}),"\n",(0,o.jsx)(t.pre,{children:(0,o.jsx)(t.code,{className:"language-bash",children:"# Replace this with your L1 ERC-20 token if not using the testing token!\nexport TUTORIAL_L1_ERC20_ADDRESS=0x5589BB8228C07c4e15558875fAf2B859f678d129\n"})}),"\n",(0,o.jsx)(t.h3,{id:"4-deploy-your-l2-erc-20-token",children:"4. Deploy your L2 ERC-20 token"}),"\n",(0,o.jsxs)(t.p,{children:["You can now deploy your L2 ERC-20 token using the ",(0,o.jsx)(t.a,{href:"https://github.com/ethereum-optimism/optimism/blob/186e46a47647a51a658e699e9ff047d39444c2de/packages/contracts-bedrock/contracts/universal/OptimismMintableERC20Factory.sol",children:(0,o.jsx)(t.code,{children:"OptimismMintableERC20Factory"})}),".\nUse the ",(0,o.jsx)(t.code,{children:"cast"}),' command to trigger the deployment function on the factory contract.\nThis example command creates a token with the name "My Standard Demo Token" and the symbol "L2TKN".\nThe resulting L2 ERC-20 token address is printed to the console.']}),"\n",(0,o.jsx)(t.pre,{children:(0,o.jsx)(t.code,{className:"language-bash",children:'cast send 0x4200000000000000000000000000000000000012 "createOptimismMintableERC20(address,string,string)" $TUTORIAL_L1_ERC20_ADDRESS "My Standard Demo Token" "L2TKN" --private-key $TUTORIAL_PRIVATE_KEY --rpc-url $TUTORIAL_RPC_URL --json | jq -r \'.logs[0].topics[2]\' | cast parse-bytes32-address\n'})}),"\n",(0,o.jsx)(t.p,{children:"If all goes well, it will respond with the address of the newly deployed contract:"}),"\n",(0,o.jsx)(t.pre,{children:(0,o.jsx)(t.code,{className:"language-text",children:"0x891C582b83F69B7c2d3107cd73A3e491CB33962F\n"})}),"\n",(0,o.jsxs)(t.admonition,{type:"note",children:[(0,o.jsxs)(t.mdxAdmonitionTitle,{children:["Using factories is ",(0,o.jsx)(t.strong,{children:"not"})," recommended for production"]}),(0,o.jsx)(t.p,{children:"Factories make it easy to deploy contracts out of the box.\nThe downside of this is, that you do not have control over the source code of the contract that is going to be deployed, as this is performed by the factory."}),(0,o.jsx)(t.p,{children:"Furthermore, it is not so straightforward to verify those contracts on Blockscout, as the source code of the contract is required for the verification."})]})]})}function h(e={}){const{wrapper:t}={...(0,i.a)(),...e.components};return t?(0,o.jsx)(t,{...e,children:(0,o.jsx)(c,{...e})}):c(e)}},1151:(e,t,n)=>{n.d(t,{Z:()=>r,a:()=>a});var o=n(7294);const i={},s=o.createContext(i);function a(e){const t=o.useContext(s);return o.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function r(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:a(e.components),o.createElement(s.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/5f139d3e.75d8310a.js b/assets/js/5f139d3e.75d8310a.js deleted file mode 100644 index a85264d28..000000000 --- a/assets/js/5f139d3e.75d8310a.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunklisk_docs=self.webpackChunklisk_docs||[]).push([[672],{8473:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>d,contentTitle:()=>r,default:()=>h,frontMatter:()=>s,metadata:()=>a,toc:()=>l});var o=n(5893),i=n(1151);const s={title:"Deploying a standard token",slug:"/building-on-lisk/add-token-to-lisk/standard-token",description:"Learn how to add your standard ERC-20 token to Lisk using the standard bridge.",keywords:["ERC-20 contract","Standard token","Lisk Testnet","Sepolia","Ethereum","Lisk Sepolia","Optimism Superchain token list"]},r="Deploying your Standard ERC-20 token to Lisk",a={id:"building-on-lisk/add-token-to-lisk/standard-token",title:"Deploying a standard token",description:"Learn how to add your standard ERC-20 token to Lisk using the standard bridge.",source:"@site/docs/building-on-lisk/add-token-to-lisk/standard-token.md",sourceDirName:"building-on-lisk/add-token-to-lisk",slug:"/building-on-lisk/add-token-to-lisk/standard-token",permalink:"/lisk-documentation/building-on-lisk/add-token-to-lisk/standard-token",draft:!1,unlisted:!1,editUrl:"https://github.com/LiskHQ/lisk-documentation/tree/main/docs/building-on-lisk/add-token-to-lisk/standard-token.md",tags:[],version:"current",frontMatter:{title:"Deploying a standard token",slug:"/building-on-lisk/add-token-to-lisk/standard-token",description:"Learn how to add your standard ERC-20 token to Lisk using the standard bridge.",keywords:["ERC-20 contract","Standard token","Lisk Testnet","Sepolia","Ethereum","Lisk Sepolia","Optimism Superchain token list"]},sidebar:"documentationSidebar",previous:{title:"Deploying an ERC-20 Token to Lisk",permalink:"/lisk-documentation/building-on-lisk/add-token-to-lisk"},next:{title:"Deploying a custom token",permalink:"/lisk-documentation/building-on-lisk/add-token-to-lisk/custom-token"}},d={},l=[{value:"Dependencies",id:"dependencies",level:2},{value:"Prerequisites",id:"prerequisites",level:2},{value:"Get ETH on Sepolia and Lisk Sepolia",id:"get-eth-on-sepolia-and-lisk-sepolia",level:3},{value:"Get an L1 ERC-20 Token Address",id:"get-an-l1-erc-20-token-address",level:3},{value:"Create an L2 ERC-20 token",id:"create-an-l2-erc-20-token",level:2},{value:"1. Add a private key to your environment",id:"1-add-a-private-key-to-your-environment",level:3},{value:"2. Add the Lisk Sepolia RPC URL to your environment",id:"2-add-the-lisk-sepolia-rpc-url-to-your-environment",level:3},{value:"3. Add your L1 ERC-20 token address to your environment",id:"3-add-your-l1-erc-20-token-address-to-your-environment",level:3},{value:"4. Deploy your L2 ERC-20 token",id:"4-deploy-your-l2-erc-20-token",level:3},{value:"Bridge Some Tokens",id:"bridge-some-tokens",level:2}];function c(e){const t={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",h3:"h3",li:"li",mdxAdmonitionTitle:"mdxAdmonitionTitle",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,i.a)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(t.h1,{id:"deploying-your-standard-erc-20-token-to-lisk",children:"Deploying your Standard ERC-20 token to Lisk"}),"\n",(0,o.jsxs)(t.admonition,{type:"info",children:[(0,o.jsx)(t.p,{children:(0,o.jsx)(t.strong,{children:"This tutorial is for developers who want to bridge a new Standard ERC-20 token to Lisk Sepolia."})}),(0,o.jsxs)(t.p,{children:["If you want to bridge existing tokens, you can follow the tutorial on ",(0,o.jsx)(t.a,{href:"https://docs.optimism.io/builders/app-developers/tutorials/cross-dom-bridge-erc20",children:"Bridging ERC-20 tokens with the Optimism SDK"}),"."]})]}),"\n",(0,o.jsxs)(t.p,{children:["In this tutorial, you'll learn how to bridge a standard ERC-20 token from Ethereum to Lisk using the ",(0,o.jsx)(t.a,{href:"https://docs.optimism.io/builders/dapp-developers/bridging/standard-bridge",children:"Standard Bridge system"}),".\nThis tutorial is meant for developers who already have an existing ERC-20 token on Ethereum and want to create a bridged representation of that token on Lisk."]}),"\n",(0,o.jsxs)(t.p,{children:["This tutorial explains how to use the ",(0,o.jsx)(t.a,{href:"https://github.com/ethereum-optimism/optimism/blob/186e46a47647a51a658e699e9ff047d39444c2de/packages/contracts-bedrock/contracts/universal/OptimismMintableERC20Factory.sol",children:(0,o.jsx)(t.code,{children:"OptimismMintableERC20Factory"})})," to deploy a standardized ERC-20 token on Lisk Sepolia.\nTokens created by this factory contract are compatible with the Standard Bridge system and include basic logic for deposits, transfers, and withdrawals.\nIf you want to include specialized logic within your L2 token, see the tutorial on ",(0,o.jsx)(t.a,{href:"./custom-token",children:"Bridging Your Custom ERC-20 Token to Lisk"})," instead."]}),"\n",(0,o.jsx)(t.h2,{id:"dependencies",children:"Dependencies"}),"\n",(0,o.jsxs)(t.ul,{children:["\n",(0,o.jsx)(t.li,{children:(0,o.jsx)(t.a,{href:"https://book.getfoundry.sh/getting-started/installation",children:"cast"})}),"\n"]}),"\n",(0,o.jsx)(t.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,o.jsx)(t.h3,{id:"get-eth-on-sepolia-and-lisk-sepolia",children:"Get ETH on Sepolia and Lisk Sepolia"}),"\n",(0,o.jsx)(t.p,{children:"This tutorial explains how to create a bridged ERC-20 token on Lisk Sepolia.\nYou will need to get some ETH on both of these testnets."}),"\n",(0,o.jsx)(t.admonition,{type:"info",children:(0,o.jsxs)(t.p,{children:["You can use ",(0,o.jsx)(t.a,{href:"https://sepoliafaucet.com/",children:"ETH Sepolia Faucet"})," to get ETH on Sepolia.\nYou can use the ",(0,o.jsx)(t.a,{href:"https://app.optimism.io/faucet?utm_source=docs",children:"Superchain Faucet"})," to get ETH on Lisk Sepolia."]})}),"\n",(0,o.jsx)(t.h3,{id:"get-an-l1-erc-20-token-address",children:"Get an L1 ERC-20 Token Address"}),"\n",(0,o.jsxs)(t.p,{children:["You will need an L1 ERC-20 token for this tutorial.\nIf you already have an L1 ERC-20 token deployed on Sepolia, you can skip this step.\nOtherwise, you can use the testing token located at ",(0,o.jsx)(t.a,{href:"https://sepolia.etherscan.io/address/0x5589BB8228C07c4e15558875fAf2B859f678d129",children:(0,o.jsx)(t.code,{children:"0x5589BB8228C07c4e15558875fAf2B859f678d129"})})," that includes a ",(0,o.jsx)(t.code,{children:"faucet()"})," function that can be used to mint tokens."]}),"\n",(0,o.jsx)(t.h2,{id:"create-an-l2-erc-20-token",children:"Create an L2 ERC-20 token"}),"\n",(0,o.jsxs)(t.p,{children:["Once you have an L1 ERC-20 token, you can use the ",(0,o.jsx)(t.a,{href:"https://github.com/ethereum-optimism/optimism/blob/186e46a47647a51a658e699e9ff047d39444c2de/packages/contracts-bedrock/contracts/universal/OptimismMintableERC20Factory.sol",children:(0,o.jsx)(t.code,{children:"OptimismMintableERC20Factory"})})," to create a corresponding L2 ERC-20 token on Lisk Sepolia.\nAll tokens created by the factory implement the ",(0,o.jsx)(t.code,{children:"IOptimismMintableERC20"})," interface and are compatible with the Standard Bridge system.\nTo create an L2 ERC-20 token, do the following:"]}),"\n",(0,o.jsx)(t.h3,{id:"1-add-a-private-key-to-your-environment",children:"1. Add a private key to your environment"}),"\n",(0,o.jsxs)(t.p,{children:["You'll need a private key in order to sign transactions.\nSet your private key as an environment variable with the ",(0,o.jsx)(t.code,{children:"export"})," command.\nMake sure this private key corresponds to an address that has ETH on Lisk Sepolia."]}),"\n",(0,o.jsx)(t.pre,{children:(0,o.jsx)(t.code,{className:"language-bash",children:"export TUTORIAL_PRIVATE_KEY=0x...\n"})}),"\n",(0,o.jsx)(t.h3,{id:"2-add-the-lisk-sepolia-rpc-url-to-your-environment",children:"2. Add the Lisk Sepolia RPC URL to your environment"}),"\n",(0,o.jsxs)(t.p,{children:["You'll need an RPC URL in order to connect to Lisk Sepolia.\nSet your RPC URL as an environment variable with the ",(0,o.jsx)(t.code,{children:"export"})," command."]}),"\n",(0,o.jsx)(t.pre,{children:(0,o.jsx)(t.code,{className:"language-bash",children:"export TUTORIAL_RPC_URL=https://rpc.sepolia-api.lisk.com\n"})}),"\n",(0,o.jsx)(t.h3,{id:"3-add-your-l1-erc-20-token-address-to-your-environment",children:"3. Add your L1 ERC-20 token address to your environment"}),"\n",(0,o.jsxs)(t.p,{children:["You'll need to know the address of your L1 ERC-20 token in order to create a bridged representation of it on Lisk Sepolia.\nSet your L1 ERC-20 token address as an environment variable with the ",(0,o.jsx)(t.code,{children:"export"})," command."]}),"\n",(0,o.jsx)(t.pre,{children:(0,o.jsx)(t.code,{className:"language-bash",children:"# Replace this with your L1 ERC-20 token if not using the testing token!\nexport TUTORIAL_L1_ERC20_ADDRESS=0x5589BB8228C07c4e15558875fAf2B859f678d129\n"})}),"\n",(0,o.jsx)(t.h3,{id:"4-deploy-your-l2-erc-20-token",children:"4. Deploy your L2 ERC-20 token"}),"\n",(0,o.jsxs)(t.p,{children:["You can now deploy your L2 ERC-20 token using the ",(0,o.jsx)(t.a,{href:"https://github.com/ethereum-optimism/optimism/blob/186e46a47647a51a658e699e9ff047d39444c2de/packages/contracts-bedrock/contracts/universal/OptimismMintableERC20Factory.sol",children:(0,o.jsx)(t.code,{children:"OptimismMintableERC20Factory"})}),".\nUse the ",(0,o.jsx)(t.code,{children:"cast"}),' command to trigger the deployment function on the factory contract.\nThis example command creates a token with the name "My Standard Demo Token" and the symbol "L2TKN".\nThe resulting L2 ERC-20 token address is printed to the console.']}),"\n",(0,o.jsx)(t.pre,{children:(0,o.jsx)(t.code,{className:"language-bash",children:'cast send 0x4200000000000000000000000000000000000012 "createOptimismMintableERC20(address,string,string)" $TUTORIAL_L1_ERC20_ADDRESS "My Standard Demo Token" "L2TKN" --private-key $TUTORIAL_PRIVATE_KEY --rpc-url $TUTORIAL_RPC_URL --json | jq -r \'.logs[0].topics[2]\' | cast parse-bytes32-address\n'})}),"\n",(0,o.jsx)(t.p,{children:"If all goes well, it will respond with the address of the newly deployed contract:"}),"\n",(0,o.jsx)(t.pre,{children:(0,o.jsx)(t.code,{className:"language-text",children:"0x891C582b83F69B7c2d3107cd73A3e491CB33962F\n"})}),"\n",(0,o.jsxs)(t.admonition,{type:"note",children:[(0,o.jsxs)(t.mdxAdmonitionTitle,{children:["Using factories is ",(0,o.jsx)(t.strong,{children:"not"})," recommended for production"]}),(0,o.jsx)(t.p,{children:"Factories make it easy to deploy contracts out of the box.\nThe downside of this is, that you do not have control over the source code of the contract that is going to be deployed, as this is performed by the factory."}),(0,o.jsx)(t.p,{children:"Furthermore, it is not so straightforward to verify those contracts on Blockscout, as the source code of the contract is required for the verification."})]}),"\n",(0,o.jsx)(t.h2,{id:"bridge-some-tokens",children:"Bridge Some Tokens"}),"\n",(0,o.jsx)(t.p,{children:"Now that you have an L2 ERC-20 token, you can bridge some tokens from L1 to L2."}),"\n",(0,o.jsxs)(t.p,{children:["Check out the tutorial on ",(0,o.jsx)(t.a,{href:"https://docs.optimism.io/builders/app-developers/tutorials/cross-dom-bridge-erc20",children:"Bridging ERC-20 tokens with the Optimism SDK"})," to learn how to bridge your L1 ERC-20 to L2s and vice versa using the Optimism SDK."]})]})}function h(e={}){const{wrapper:t}={...(0,i.a)(),...e.components};return t?(0,o.jsx)(t,{...e,children:(0,o.jsx)(c,{...e})}):c(e)}},1151:(e,t,n)=>{n.d(t,{Z:()=>a,a:()=>r});var o=n(7294);const i={},s=o.createContext(i);function r(e){const t=o.useContext(s);return o.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:r(e.components),o.createElement(s.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/a8c021bd.0269c486.js b/assets/js/a8c021bd.0269c486.js deleted file mode 100644 index 223435c75..000000000 --- a/assets/js/a8c021bd.0269c486.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunklisk_docs=self.webpackChunklisk_docs||[]).push([[936],{5642:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>d,contentTitle:()=>s,default:()=>h,frontMatter:()=>r,metadata:()=>a,toc:()=>l});var o=n(5893),i=n(1151);const r={title:"Deploying a custom token",slug:"/building-on-lisk/add-token-to-lisk/custom-token",description:"Learn how to bridge your custom ERC-20 token to Lisk using the standard bridge.",keywords:["ERC-20 contract","Custom token","Lisk Testnet","Sepolia","Ethereum","Lisk Sepolia","Optimism Superchain token list"]},s="Deploying your Custom ERC-20 token to Lisk",a={id:"building-on-lisk/add-token-to-lisk/custom-token",title:"Deploying a custom token",description:"Learn how to bridge your custom ERC-20 token to Lisk using the standard bridge.",source:"@site/docs/building-on-lisk/add-token-to-lisk/custom-token.mdx",sourceDirName:"building-on-lisk/add-token-to-lisk",slug:"/building-on-lisk/add-token-to-lisk/custom-token",permalink:"/lisk-documentation/building-on-lisk/add-token-to-lisk/custom-token",draft:!1,unlisted:!1,editUrl:"https://github.com/LiskHQ/lisk-documentation/tree/main/docs/building-on-lisk/add-token-to-lisk/custom-token.mdx",tags:[],version:"current",frontMatter:{title:"Deploying a custom token",slug:"/building-on-lisk/add-token-to-lisk/custom-token",description:"Learn how to bridge your custom ERC-20 token to Lisk using the standard bridge.",keywords:["ERC-20 contract","Custom token","Lisk Testnet","Sepolia","Ethereum","Lisk Sepolia","Optimism Superchain token list"]},sidebar:"documentationSidebar",previous:{title:"Deploying a standard token",permalink:"/lisk-documentation/building-on-lisk/add-token-to-lisk/standard-token"},next:{title:"...with viem",permalink:"/lisk-documentation/interacting-with-blockchain/viem"}},d={},l=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Get ETH on Sepolia and Lisk Sepolia",id:"get-eth-on-sepolia-and-lisk-sepolia",level:3},{value:"Add Lisk Sepolia to Your Wallet",id:"add-lisk-sepolia-to-your-wallet",level:3},{value:"Get an L1 ERC-20 Token Address",id:"get-an-l1-erc-20-token-address",level:3},{value:"Create an L2 ERC-20 Token",id:"create-an-l2-erc-20-token",level:2},{value:"1. Open Remix",id:"1-open-remix",level:3},{value:"2. Create a new file",id:"2-create-a-new-file",level:3},{value:"3. Copy the example contract",id:"3-copy-the-example-contract",level:3},{value:"4. Review the example contract",id:"4-review-the-example-contract",level:3},{value:"5. Compile the contract",id:"5-compile-the-contract",level:3},{value:"6. Deploy the contract",id:"6-deploy-the-contract",level:3},{value:"Bridge Some Tokens",id:"bridge-some-tokens",level:2}];function c(e){const t={a:"a",admonition:"admonition",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",p:"p",pre:"pre",strong:"strong",...(0,i.a)(),...e.components},{Details:n}=t;return n||function(e,t){throw new Error("Expected "+(t?"component":"object")+" `"+e+"` to be defined: you likely forgot to import, pass, or provide it.")}("Details",!0),(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(t.h1,{id:"deploying-your-custom-erc-20-token-to-lisk",children:"Deploying your Custom ERC-20 token to Lisk"}),"\n",(0,o.jsxs)(t.admonition,{type:"info",children:[(0,o.jsx)(t.p,{children:(0,o.jsx)(t.strong,{children:"This tutorial is for developers who want to bridge a new Custom ERC-20 token to Lisk Mainnet."})}),(0,o.jsxs)(t.p,{children:["If you want to bridge existing tokens, you can follow the tutorial on ",(0,o.jsx)(t.a,{href:"https://docs.optimism.io/builders/app-developers/tutorials/cross-dom-bridge-erc20",children:"Bridging ERC-20 tokens with the Optimism SDK"}),"."]})]}),"\n",(0,o.jsxs)(t.p,{children:["In this tutorial you'll learn how to bridge a custom ERC-20 token from Ethereum to Lisk Sepolia using the ",(0,o.jsx)(t.a,{href:"https://docs.optimism.io/builders/dapp-developers/bridging/standard-bridge",children:"Standard Bridge system"}),".\nThis tutorial is meant for developers who already have an existing ERC-20 token on Ethereum and want to create a bridged representation of that token on Lisk Sepolia."]}),"\n",(0,o.jsxs)(t.p,{children:["Learn step-by-step how you can create a custom token that conforms to the ",(0,o.jsx)(t.a,{href:"https://github.com/ethereum-optimism/optimism/blob/v1.1.4/packages/contracts-bedrock/src/universal/IOptimismMintableERC20.sol",children:(0,o.jsx)(t.code,{children:"IOptimismMintableERC20"})})," interface so that it can be used with the Standard Bridge system.\nA custom token allows you to do things like trigger extra logic whenever a token is deposited.\nIf you don't need extra functionality like this, consider following the tutorial on ",(0,o.jsx)(t.a,{href:"./standard-token",children:"Deploying your Standard ERC-20 token to Lisk"})," instead."]}),"\n",(0,o.jsx)(t.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,o.jsx)(t.h3,{id:"get-eth-on-sepolia-and-lisk-sepolia",children:"Get ETH on Sepolia and Lisk Sepolia"}),"\n",(0,o.jsx)(t.p,{children:"You will need to get some ETH on both, Sepolia and Lisk Sepolia networks."}),"\n",(0,o.jsx)(t.admonition,{type:"info",children:(0,o.jsxs)(t.p,{children:["You can use ",(0,o.jsx)(t.a,{href:"https://sepoliafaucet.com/",children:"ETH Sepolia Faucet"})," to get ETH on Sepolia.\nYou can use the ",(0,o.jsx)(t.a,{href:"https://app.optimism.io/faucet?utm_source=docs",children:"Superchain Faucet"})," to get ETH on Lisk Sepolia."]})}),"\n",(0,o.jsx)(t.h3,{id:"add-lisk-sepolia-to-your-wallet",children:"Add Lisk Sepolia to Your Wallet"}),"\n",(0,o.jsxs)(t.p,{children:["This tutorial uses ",(0,o.jsx)(t.a,{href:"https://remix.ethereum.org",children:"Remix"})," to deploy contracts.\nYou will need to add the Lisk Sepolia network to your wallet in order to follow this tutorial.\nPlease follow the ",(0,o.jsx)(t.a,{href:"/lisk-documentation/connecting-to-a-wallet",children:"How to connect Lisk to a wallet"})," guide, to connect your wallet to Lisk Sepolia."]}),"\n",(0,o.jsx)(t.h3,{id:"get-an-l1-erc-20-token-address",children:"Get an L1 ERC-20 Token Address"}),"\n",(0,o.jsxs)(t.p,{children:["You will need an L1 ERC-20 token for this tutorial.\nIf you already have an L1 ERC-20 token deployed on Sepolia, you can skip this step.\nOtherwise, you can use the testing token located at ",(0,o.jsx)(t.a,{href:"https://sepolia.etherscan.io/address/0x5589BB8228C07c4e15558875fAf2B859f678d129",children:(0,o.jsx)(t.code,{children:"0x5589BB8228C07c4e15558875fAf2B859f678d129"})})," that includes a ",(0,o.jsx)(t.code,{children:"faucet()"})," function that can be used to mint tokens."]}),"\n",(0,o.jsx)(t.h2,{id:"create-an-l2-erc-20-token",children:"Create an L2 ERC-20 Token"}),"\n",(0,o.jsxs)(t.p,{children:["Once you have an L1 ERC-20 token, you can create a corresponding L2 ERC-20 token on Lisk Sepolia.\nThis tutorial uses ",(0,o.jsx)(t.a,{href:"https://remix.ethereum.org",children:"Remix"}),", so you can easily deploy a token without a framework like ",(0,o.jsx)(t.a,{href:"https://hardhat.org",children:"Hardhat"})," or ",(0,o.jsx)(t.a,{href:"https://getfoundry.sh",children:"Foundry"}),".\nYou can follow the same general process within your favorite framework if you prefer."]}),"\n",(0,o.jsx)(t.p,{children:"In this section, you'll be creating an ERC-20 token that can be deposited but cannot be withdrawn.\nThis is just one example of the endless ways in which you could customize your L2 token."}),"\n",(0,o.jsx)(t.h3,{id:"1-open-remix",children:"1. Open Remix"}),"\n",(0,o.jsxs)(t.p,{children:["Navigate to ",(0,o.jsx)(t.a,{href:"https://remix.ethereum.org",children:"Remix"})," in your browser."]}),"\n",(0,o.jsx)(t.h3,{id:"2-create-a-new-file",children:"2. Create a new file"}),"\n",(0,o.jsxs)(t.p,{children:['Click the \ud83d\udcc4 ("Create new file") button to create a new empty Solidity file.\nYou can name this file whatever you\'d like, e.g. ',(0,o.jsx)(t.code,{children:"custom-token.sol"}),"."]}),"\n",(0,o.jsx)(t.h3,{id:"3-copy-the-example-contract",children:"3. Copy the example contract"}),"\n",(0,o.jsx)(t.p,{children:"Copy the following example contract into your new file:"}),"\n",(0,o.jsxs)(n,{children:[(0,o.jsx)("summary",{children:"custom-token.sol"}),(0,o.jsx)(t.pre,{children:(0,o.jsx)(t.code,{className:"language-solidity",children:'// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport { ERC20 } from "@openzeppelin/contracts/token/ERC20/ERC20.sol";\nimport { IERC165 } from "@openzeppelin/contracts/utils/introspection/IERC165.sol";\nimport { IOptimismMintableERC20 } from "https://github.com/ethereum-optimism/optimism/blob/v1.1.4/packages/contracts-bedrock/src/universal/IOptimismMintableERC20.sol";\n\ncontract MyCustomL2Token is IOptimismMintableERC20, ERC20 {\n /// @notice Address of the corresponding version of this token on the remote chain.\n address public immutable REMOTE_TOKEN;\n\n /// @notice Address of the StandardBridge on this network.\n address public immutable BRIDGE;\n\n /// @notice Emitted whenever tokens are minted for an account.\n /// @param account Address of the account tokens are being minted for.\n /// @param amount Amount of tokens minted.\n event Mint(address indexed account, uint256 amount);\n\n /// @notice Emitted whenever tokens are burned from an account.\n /// @param account Address of the account tokens are being burned from.\n /// @param amount Amount of tokens burned.\n event Burn(address indexed account, uint256 amount);\n\n /// @notice A modifier that only allows the bridge to call.\n modifier onlyBridge() {\n require(msg.sender == BRIDGE, "MyCustomL2Token: only bridge can mint and burn");\n _;\n }\n\n /// @param _bridge Address of the L2 standard bridge.\n /// @param _remoteToken Address of the corresponding L1 token.\n /// @param _name ERC20 name.\n /// @param _symbol ERC20 symbol.\n constructor(\n address _bridge,\n address _remoteToken,\n string memory _name,\n string memory _symbol\n )\n ERC20(_name, _symbol)\n {\n REMOTE_TOKEN = _remoteToken;\n BRIDGE = _bridge;\n }\n\n /// @custom:legacy\n /// @notice Legacy getter for REMOTE_TOKEN.\n function remoteToken() public view returns (address) {\n return REMOTE_TOKEN;\n }\n\n /// @custom:legacy\n /// @notice Legacy getter for BRIDGE.\n function bridge() public view returns (address) {\n return BRIDGE;\n }\n\n /// @notice ERC165 interface check function.\n /// @param _interfaceId Interface ID to check.\n /// @return Whether or not the interface is supported by this contract.\n function supportsInterface(bytes4 _interfaceId) external pure virtual returns (bool) {\n bytes4 iface1 = type(IERC165).interfaceId;\n // Interface corresponding to the updated OptimismMintableERC20 (this contract).\n bytes4 iface2 = type(IOptimismMintableERC20).interfaceId;\n return _interfaceId == iface1 || _interfaceId == iface2;\n }\n\n /// @notice Allows the StandardBridge on this network to mint tokens.\n /// @param _to Address to mint tokens to.\n /// @param _amount Amount of tokens to mint.\n function mint(\n address _to,\n uint256 _amount\n )\n external\n virtual\n override(IOptimismMintableERC20)\n onlyBridge\n {\n _mint(_to, _amount);\n emit Mint(_to, _amount);\n }\n\n /// @notice Prevents tokens from being withdrawn to L1.\n function burn(\n address,\n uint256\n )\n external\n virtual\n override(IOptimismMintableERC20)\n onlyBridge\n {\n revert("MyCustomL2Token cannot be withdrawn");\n }\n}\n'})})]}),"\n",(0,o.jsx)(t.h3,{id:"4-review-the-example-contract",children:"4. Review the example contract"}),"\n",(0,o.jsxs)(t.p,{children:["Take a moment to review the example contract.\nIt's almost the same as the standard ",(0,o.jsx)(t.a,{href:"https://github.com/ethereum-optimism/optimism/blob/v1.1.4/packages/contracts-bedrock/src/universal/OptimismMintableERC20.sol",children:(0,o.jsx)(t.code,{children:"OptimismMintableERC20"})})," contract except that the ",(0,o.jsx)(t.code,{children:"_burn"})," function has been made to always revert."]}),"\n",(0,o.jsxs)(t.p,{children:["The contract for the custom token inherits from the ",(0,o.jsx)(t.a,{href:"https://github.com/ethereum-optimism/optimism/blob/v1.1.4/packages/contracts-bedrock/src/universal/IOptimismMintableERC20.sol",children:(0,o.jsx)(t.code,{children:"IOptimismMintableERC20"})})," interface and the ",(0,o.jsx)(t.code,{children:"ERC20"})," contract.\nThe constructor takes the address of the L2 standard bridge, the address of the corresponding L1 token, the name of the ERC20 token, and the symbol of the ERC20 token.\nThe ",(0,o.jsx)(t.code,{children:"mint"})," function allows the bridge to mint tokens for users.\nSince the bridge needs to burn tokens when users want to withdraw them to L1, this means that users will not be able to withdraw tokens from this contract, which is what we intend for this example."]}),"\n",(0,o.jsx)(t.pre,{children:(0,o.jsx)(t.code,{className:"language-solidity",children:'/// @notice Prevents tokens from being withdrawn to L1.\nfunction burn(\n address,\n uint256\n)\n external\n virtual\n override(IOptimismMintableERC20)\n onlyBridge\n{\n revert("MyCustomL2Token cannot be withdrawn");\n}\n'})}),"\n",(0,o.jsx)(t.h3,{id:"5-compile-the-contract",children:"5. Compile the contract"}),"\n",(0,o.jsx)(t.p,{children:'Save the file to automatically compile the contract.\nIf you\'ve disabled auto-compile, you\'ll need to manually compile the contract by clicking the "Solidity Compiler" tab (this looks like the letter "S") and pressing the blue "Compile" button.'}),"\n",(0,o.jsx)(t.h3,{id:"6-deploy-the-contract",children:"6. Deploy the contract"}),"\n",(0,o.jsxs)(t.p,{children:['Open the deployment tab (this looks like an Ethereum logo with an arrow pointing right).\nMake sure that your environment is set to "Injected Provider", your wallet is connected to Lisk Sepolia, and Remix has access to your wallet.\nThen, select the ',(0,o.jsx)(t.code,{children:"MyCustomL2Token"})," contract from the deployment dropdown and deploy it with the following parameters:"]}),"\n",(0,o.jsx)(t.pre,{children:(0,o.jsx)(t.code,{className:"language-text",children:'_BRIDGE: "0x4200000000000000000000000000000000000007"\n_REMOTETOKEN: ""\n_NAME: "My Custom Lisk L2 Token"\n_SYMBOL: "MCL2T"\n'})}),"\n",(0,o.jsx)(t.admonition,{type:"tip",children:(0,o.jsxs)(t.p,{children:["If you used the testing token described in step ",(0,o.jsx)(t.a,{href:"#get-an-l1-erc-20-token-address",children:"Get an L1 ERC-20 Token Address"}),", use the address ",(0,o.jsx)(t.code,{children:"0x5589BB8228C07c4e15558875fAf2B859f678d129"})," for the ",(0,o.jsx)(t.code,{children:"_REMOTETOKEN"})," parameter."]})}),"\n",(0,o.jsx)(t.h2,{id:"bridge-some-tokens",children:"Bridge Some Tokens"}),"\n",(0,o.jsx)(t.p,{children:"Now that you have an L2 ERC-20 token, you can bridge some tokens from L1 to L2."}),"\n","\n",(0,o.jsxs)(t.p,{children:["Check out the tutorial on ",(0,o.jsx)(t.a,{href:"https://docs.optimism.io/builders/app-developers/tutorials/cross-dom-bridge-erc20",children:"Bridging ERC-20 tokens with the Optimism SDK"})," to learn how to bridge your L1 ERC-20 to Lisk using the Optimism SDK.\nRemember that the withdrawal step will ",(0,o.jsx)(t.em,{children:"not"})," work for the token you just created!\nThis is exactly what this tutorial was meant to demonstrate."]})]})}function h(e={}){const{wrapper:t}={...(0,i.a)(),...e.components};return t?(0,o.jsx)(t,{...e,children:(0,o.jsx)(c,{...e})}):c(e)}},1151:(e,t,n)=>{n.d(t,{Z:()=>a,a:()=>s});var o=n(7294);const i={},r=o.createContext(i);function s(e){const t=o.useContext(r);return o.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:s(e.components),o.createElement(r.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/a8c021bd.d8c9495e.js b/assets/js/a8c021bd.d8c9495e.js new file mode 100644 index 000000000..0db5b3fa8 --- /dev/null +++ b/assets/js/a8c021bd.d8c9495e.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunklisk_docs=self.webpackChunklisk_docs||[]).push([[936],{5642:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>s,default:()=>h,frontMatter:()=>r,metadata:()=>a,toc:()=>d});var o=n(5893),i=n(1151);const r={title:"Deploying a custom token",slug:"/building-on-lisk/add-token-to-lisk/custom-token",description:"Learn how to bridge your custom ERC-20 token to Lisk using the standard bridge.",keywords:["ERC-20 contract","Custom token","Lisk Testnet","Sepolia","Ethereum","Lisk Sepolia","Optimism Superchain token list"]},s="Deploying your Custom ERC-20 token to Lisk",a={id:"building-on-lisk/add-token-to-lisk/custom-token",title:"Deploying a custom token",description:"Learn how to bridge your custom ERC-20 token to Lisk using the standard bridge.",source:"@site/docs/building-on-lisk/add-token-to-lisk/custom-token.mdx",sourceDirName:"building-on-lisk/add-token-to-lisk",slug:"/building-on-lisk/add-token-to-lisk/custom-token",permalink:"/lisk-documentation/building-on-lisk/add-token-to-lisk/custom-token",draft:!1,unlisted:!1,editUrl:"https://github.com/LiskHQ/lisk-documentation/tree/main/docs/building-on-lisk/add-token-to-lisk/custom-token.mdx",tags:[],version:"current",frontMatter:{title:"Deploying a custom token",slug:"/building-on-lisk/add-token-to-lisk/custom-token",description:"Learn how to bridge your custom ERC-20 token to Lisk using the standard bridge.",keywords:["ERC-20 contract","Custom token","Lisk Testnet","Sepolia","Ethereum","Lisk Sepolia","Optimism Superchain token list"]},sidebar:"documentationSidebar",previous:{title:"Deploying a standard token",permalink:"/lisk-documentation/building-on-lisk/add-token-to-lisk/standard-token"},next:{title:"...with viem",permalink:"/lisk-documentation/interacting-with-blockchain/viem"}},l={},d=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Get ETH on Sepolia and Lisk Sepolia",id:"get-eth-on-sepolia-and-lisk-sepolia",level:3},{value:"Add Lisk Sepolia to Your Wallet",id:"add-lisk-sepolia-to-your-wallet",level:3},{value:"Get an L1 ERC-20 Token Address",id:"get-an-l1-erc-20-token-address",level:3},{value:"Create an L2 ERC-20 Token",id:"create-an-l2-erc-20-token",level:2},{value:"1. Open Remix",id:"1-open-remix",level:3},{value:"2. Create a new file",id:"2-create-a-new-file",level:3},{value:"3. Copy the example contract",id:"3-copy-the-example-contract",level:3},{value:"4. Review the example contract",id:"4-review-the-example-contract",level:3},{value:"5. Compile the contract",id:"5-compile-the-contract",level:3},{value:"6. Deploy the contract",id:"6-deploy-the-contract",level:3}];function c(e){const t={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",h3:"h3",p:"p",pre:"pre",...(0,i.a)(),...e.components},{Details:n}=t;return n||function(e,t){throw new Error("Expected "+(t?"component":"object")+" `"+e+"` to be defined: you likely forgot to import, pass, or provide it.")}("Details",!0),(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(t.h1,{id:"deploying-your-custom-erc-20-token-to-lisk",children:"Deploying your Custom ERC-20 token to Lisk"}),"\n","\n",(0,o.jsxs)(t.p,{children:["In this tutorial you'll learn how to bridge a custom ERC-20 token from Ethereum to Lisk Sepolia using the ",(0,o.jsx)(t.a,{href:"https://docs.optimism.io/builders/dapp-developers/bridging/standard-bridge",children:"Standard Bridge system"}),".\nThis tutorial is meant for developers who already have an existing ERC-20 token on Ethereum and want to create a bridged representation of that token on Lisk Sepolia."]}),"\n",(0,o.jsxs)(t.p,{children:["Learn step-by-step how you can create a custom token that conforms to the ",(0,o.jsx)(t.a,{href:"https://github.com/ethereum-optimism/optimism/blob/v1.1.4/packages/contracts-bedrock/src/universal/IOptimismMintableERC20.sol",children:(0,o.jsx)(t.code,{children:"IOptimismMintableERC20"})})," interface so that it can be used with the Standard Bridge system.\nA custom token allows you to do things like trigger extra logic whenever a token is deposited.\nIf you don't need extra functionality like this, consider following the tutorial on ",(0,o.jsx)(t.a,{href:"./standard-token",children:"Deploying your Standard ERC-20 token to Lisk"})," instead."]}),"\n",(0,o.jsx)(t.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,o.jsx)(t.h3,{id:"get-eth-on-sepolia-and-lisk-sepolia",children:"Get ETH on Sepolia and Lisk Sepolia"}),"\n",(0,o.jsx)(t.p,{children:"You will need to get some ETH on both, Sepolia and Lisk Sepolia networks."}),"\n",(0,o.jsx)(t.admonition,{type:"info",children:(0,o.jsxs)(t.p,{children:["You can use ",(0,o.jsx)(t.a,{href:"https://sepoliafaucet.com/",children:"ETH Sepolia Faucet"})," to get ETH on Sepolia.\nYou can use the ",(0,o.jsx)(t.a,{href:"https://app.optimism.io/faucet?utm_source=docs",children:"Superchain Faucet"})," to get ETH on Lisk Sepolia."]})}),"\n",(0,o.jsx)(t.h3,{id:"add-lisk-sepolia-to-your-wallet",children:"Add Lisk Sepolia to Your Wallet"}),"\n",(0,o.jsxs)(t.p,{children:["This tutorial uses ",(0,o.jsx)(t.a,{href:"https://remix.ethereum.org",children:"Remix"})," to deploy contracts.\nYou will need to add the Lisk Sepolia network to your wallet in order to follow this tutorial.\nPlease follow the ",(0,o.jsx)(t.a,{href:"/lisk-documentation/connecting-to-a-wallet",children:"How to connect Lisk to a wallet"})," guide, to connect your wallet to Lisk Sepolia."]}),"\n",(0,o.jsx)(t.h3,{id:"get-an-l1-erc-20-token-address",children:"Get an L1 ERC-20 Token Address"}),"\n",(0,o.jsxs)(t.p,{children:["You will need an L1 ERC-20 token for this tutorial.\nIf you already have an L1 ERC-20 token deployed on Sepolia, you can skip this step.\nOtherwise, you can use the testing token located at ",(0,o.jsx)(t.a,{href:"https://sepolia.etherscan.io/address/0x5589BB8228C07c4e15558875fAf2B859f678d129",children:(0,o.jsx)(t.code,{children:"0x5589BB8228C07c4e15558875fAf2B859f678d129"})})," that includes a ",(0,o.jsx)(t.code,{children:"faucet()"})," function that can be used to mint tokens."]}),"\n",(0,o.jsx)(t.h2,{id:"create-an-l2-erc-20-token",children:"Create an L2 ERC-20 Token"}),"\n",(0,o.jsxs)(t.p,{children:["Once you have an L1 ERC-20 token, you can create a corresponding L2 ERC-20 token on Lisk Sepolia.\nThis tutorial uses ",(0,o.jsx)(t.a,{href:"https://remix.ethereum.org",children:"Remix"}),", so you can easily deploy a token without a framework like ",(0,o.jsx)(t.a,{href:"https://hardhat.org",children:"Hardhat"})," or ",(0,o.jsx)(t.a,{href:"https://getfoundry.sh",children:"Foundry"}),".\nYou can follow the same general process within your favorite framework if you prefer."]}),"\n",(0,o.jsx)(t.p,{children:"In this section, you'll be creating an ERC-20 token that can be deposited but cannot be withdrawn.\nThis is just one example of the endless ways in which you could customize your L2 token."}),"\n",(0,o.jsx)(t.h3,{id:"1-open-remix",children:"1. Open Remix"}),"\n",(0,o.jsxs)(t.p,{children:["Navigate to ",(0,o.jsx)(t.a,{href:"https://remix.ethereum.org",children:"Remix"})," in your browser."]}),"\n",(0,o.jsx)(t.h3,{id:"2-create-a-new-file",children:"2. Create a new file"}),"\n",(0,o.jsxs)(t.p,{children:['Click the \ud83d\udcc4 ("Create new file") button to create a new empty Solidity file.\nYou can name this file whatever you\'d like, e.g. ',(0,o.jsx)(t.code,{children:"custom-token.sol"}),"."]}),"\n",(0,o.jsx)(t.h3,{id:"3-copy-the-example-contract",children:"3. Copy the example contract"}),"\n",(0,o.jsx)(t.p,{children:"Copy the following example contract into your new file:"}),"\n",(0,o.jsxs)(n,{children:[(0,o.jsx)("summary",{children:"custom-token.sol"}),(0,o.jsx)(t.pre,{children:(0,o.jsx)(t.code,{className:"language-solidity",children:'// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport { ERC20 } from "@openzeppelin/contracts/token/ERC20/ERC20.sol";\nimport { IERC165 } from "@openzeppelin/contracts/utils/introspection/IERC165.sol";\nimport { IOptimismMintableERC20 } from "https://github.com/ethereum-optimism/optimism/blob/v1.1.4/packages/contracts-bedrock/src/universal/IOptimismMintableERC20.sol";\n\ncontract MyCustomL2Token is IOptimismMintableERC20, ERC20 {\n /// @notice Address of the corresponding version of this token on the remote chain.\n address public immutable REMOTE_TOKEN;\n\n /// @notice Address of the StandardBridge on this network.\n address public immutable BRIDGE;\n\n /// @notice Emitted whenever tokens are minted for an account.\n /// @param account Address of the account tokens are being minted for.\n /// @param amount Amount of tokens minted.\n event Mint(address indexed account, uint256 amount);\n\n /// @notice Emitted whenever tokens are burned from an account.\n /// @param account Address of the account tokens are being burned from.\n /// @param amount Amount of tokens burned.\n event Burn(address indexed account, uint256 amount);\n\n /// @notice A modifier that only allows the bridge to call.\n modifier onlyBridge() {\n require(msg.sender == BRIDGE, "MyCustomL2Token: only bridge can mint and burn");\n _;\n }\n\n /// @param _bridge Address of the L2 standard bridge.\n /// @param _remoteToken Address of the corresponding L1 token.\n /// @param _name ERC20 name.\n /// @param _symbol ERC20 symbol.\n constructor(\n address _bridge,\n address _remoteToken,\n string memory _name,\n string memory _symbol\n )\n ERC20(_name, _symbol)\n {\n REMOTE_TOKEN = _remoteToken;\n BRIDGE = _bridge;\n }\n\n /// @custom:legacy\n /// @notice Legacy getter for REMOTE_TOKEN.\n function remoteToken() public view returns (address) {\n return REMOTE_TOKEN;\n }\n\n /// @custom:legacy\n /// @notice Legacy getter for BRIDGE.\n function bridge() public view returns (address) {\n return BRIDGE;\n }\n\n /// @notice ERC165 interface check function.\n /// @param _interfaceId Interface ID to check.\n /// @return Whether or not the interface is supported by this contract.\n function supportsInterface(bytes4 _interfaceId) external pure virtual returns (bool) {\n bytes4 iface1 = type(IERC165).interfaceId;\n // Interface corresponding to the updated OptimismMintableERC20 (this contract).\n bytes4 iface2 = type(IOptimismMintableERC20).interfaceId;\n return _interfaceId == iface1 || _interfaceId == iface2;\n }\n\n /// @notice Allows the StandardBridge on this network to mint tokens.\n /// @param _to Address to mint tokens to.\n /// @param _amount Amount of tokens to mint.\n function mint(\n address _to,\n uint256 _amount\n )\n external\n virtual\n override(IOptimismMintableERC20)\n onlyBridge\n {\n _mint(_to, _amount);\n emit Mint(_to, _amount);\n }\n\n /// @notice Prevents tokens from being withdrawn to L1.\n function burn(\n address,\n uint256\n )\n external\n virtual\n override(IOptimismMintableERC20)\n onlyBridge\n {\n revert("MyCustomL2Token cannot be withdrawn");\n }\n}\n'})})]}),"\n",(0,o.jsx)(t.h3,{id:"4-review-the-example-contract",children:"4. Review the example contract"}),"\n",(0,o.jsxs)(t.p,{children:["Take a moment to review the example contract.\nIt's almost the same as the standard ",(0,o.jsx)(t.a,{href:"https://github.com/ethereum-optimism/optimism/blob/v1.1.4/packages/contracts-bedrock/src/universal/OptimismMintableERC20.sol",children:(0,o.jsx)(t.code,{children:"OptimismMintableERC20"})})," contract except that the ",(0,o.jsx)(t.code,{children:"_burn"})," function has been made to always revert."]}),"\n",(0,o.jsxs)(t.p,{children:["The contract for the custom token inherits from the ",(0,o.jsx)(t.a,{href:"https://github.com/ethereum-optimism/optimism/blob/v1.1.4/packages/contracts-bedrock/src/universal/IOptimismMintableERC20.sol",children:(0,o.jsx)(t.code,{children:"IOptimismMintableERC20"})})," interface and the ",(0,o.jsx)(t.code,{children:"ERC20"})," contract.\nThe constructor takes the address of the L2 standard bridge, the address of the corresponding L1 token, the name of the ERC20 token, and the symbol of the ERC20 token.\nThe ",(0,o.jsx)(t.code,{children:"mint"})," function allows the bridge to mint tokens for users.\nSince the bridge needs to burn tokens when users want to withdraw them to L1, this means that users will not be able to withdraw tokens from this contract, which is what we intend for this example."]}),"\n",(0,o.jsx)(t.pre,{children:(0,o.jsx)(t.code,{className:"language-solidity",children:'/// @notice Prevents tokens from being withdrawn to L1.\nfunction burn(\n address,\n uint256\n)\n external\n virtual\n override(IOptimismMintableERC20)\n onlyBridge\n{\n revert("MyCustomL2Token cannot be withdrawn");\n}\n'})}),"\n",(0,o.jsx)(t.h3,{id:"5-compile-the-contract",children:"5. Compile the contract"}),"\n",(0,o.jsx)(t.p,{children:'Save the file to automatically compile the contract.\nIf you\'ve disabled auto-compile, you\'ll need to manually compile the contract by clicking the "Solidity Compiler" tab (this looks like the letter "S") and pressing the blue "Compile" button.'}),"\n",(0,o.jsx)(t.h3,{id:"6-deploy-the-contract",children:"6. Deploy the contract"}),"\n",(0,o.jsxs)(t.p,{children:['Open the deployment tab (this looks like an Ethereum logo with an arrow pointing right).\nMake sure that your environment is set to "Injected Provider", your wallet is connected to Lisk Sepolia, and Remix has access to your wallet.\nThen, select the ',(0,o.jsx)(t.code,{children:"MyCustomL2Token"})," contract from the deployment dropdown and deploy it with the following parameters:"]}),"\n",(0,o.jsx)(t.pre,{children:(0,o.jsx)(t.code,{className:"language-text",children:'_BRIDGE: "0x4200000000000000000000000000000000000007"\n_REMOTETOKEN: ""\n_NAME: "My Custom Lisk L2 Token"\n_SYMBOL: "MCL2T"\n'})}),"\n",(0,o.jsx)(t.admonition,{type:"tip",children:(0,o.jsxs)(t.p,{children:["If you used the testing token described in step ",(0,o.jsx)(t.a,{href:"#get-an-l1-erc-20-token-address",children:"Get an L1 ERC-20 Token Address"}),", use the address ",(0,o.jsx)(t.code,{children:"0x5589BB8228C07c4e15558875fAf2B859f678d129"})," for the ",(0,o.jsx)(t.code,{children:"_REMOTETOKEN"})," parameter."]})}),"\n"]})}function h(e={}){const{wrapper:t}={...(0,i.a)(),...e.components};return t?(0,o.jsx)(t,{...e,children:(0,o.jsx)(c,{...e})}):c(e)}},1151:(e,t,n)=>{n.d(t,{Z:()=>a,a:()=>s});var o=n(7294);const i={},r=o.createContext(i);function s(e){const t=o.useContext(r);return o.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:s(e.components),o.createElement(r.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/runtime~main.03e2e4c7.js b/assets/js/runtime~main.7880ad69.js similarity index 97% rename from assets/js/runtime~main.03e2e4c7.js rename to assets/js/runtime~main.7880ad69.js index f912fbe9b..ea82edbd2 100644 --- a/assets/js/runtime~main.03e2e4c7.js +++ b/assets/js/runtime~main.7880ad69.js @@ -1 +1 @@ -(()=>{"use strict";var e,t,a,r,o,c={},d={};function b(e){var t=d[e];if(void 0!==t)return t.exports;var a=d[e]={exports:{}};return c[e].call(a.exports,a,a.exports,b),a.exports}b.m=c,e=[],b.O=(t,a,r,o)=>{if(!a){var c=1/0;for(i=0;i=o)&&Object.keys(b.O).every((e=>b.O[e](a[n])))?a.splice(n--,1):(d=!1,o0&&e[i-1][2]>o;i--)e[i]=e[i-1];e[i]=[a,r,o]},b.n=e=>{var t=e&&e.__esModule?()=>e.default:()=>e;return b.d(t,{a:t}),t},a=Object.getPrototypeOf?e=>Object.getPrototypeOf(e):e=>e.__proto__,b.t=function(e,r){if(1&r&&(e=this(e)),8&r)return e;if("object"==typeof e&&e){if(4&r&&e.__esModule)return e;if(16&r&&"function"==typeof e.then)return e}var o=Object.create(null);b.r(o);var c={};t=t||[null,a({}),a([]),a(a)];for(var d=2&r&&e;"object"==typeof d&&!~t.indexOf(d);d=a(d))Object.getOwnPropertyNames(d).forEach((t=>c[t]=()=>e[t]));return c.default=()=>e,b.d(o,c),o},b.d=(e,t)=>{for(var a in t)b.o(t,a)&&!b.o(e,a)&&Object.defineProperty(e,a,{enumerable:!0,get:t[a]})},b.f={},b.e=e=>Promise.all(Object.keys(b.f).reduce(((t,a)=>(b.f[a](e,t),t)),[])),b.u=e=>"assets/js/"+({0:"746da5eb",40:"56867589",53:"935f2afb",68:"0eafa1eb",80:"2e7d4620",85:"1f391b9e",124:"de80008c",184:"6ce766bb",318:"b2059c63",368:"a94703ab",375:"d9983e98",379:"f7633811",383:"0480cc7e",388:"1224f3e7",414:"393be207",421:"bcc5765f",444:"6183c0e3",445:"951748bc",462:"f58537f1",468:"d38dfec1",518:"a7bd4aaa",567:"8bcd76a4",568:"dad52d3b",661:"5e95c892",671:"0e384e19",672:"5f139d3e",799:"6541bca2",817:"14eb3368",895:"4984adb1",918:"17896441",920:"1a4e3797",936:"a8c021bd",939:"8d261ba2"}[e]||e)+"."+{0:"9fb4d017",40:"15df44d3",53:"3b1ca015",68:"06991558",80:"69cc0dae",85:"8026121d",124:"cdaa3942",184:"52e3af1f",318:"31821c9d",325:"4aa58665",368:"68ae7f1b",375:"b0a38668",379:"a03228b3",383:"f247d45d",388:"f648b06f",414:"6280be6b",421:"8265f4a6",426:"ead49eea",444:"8af2ec63",445:"e857cfc4",462:"81742591",468:"0f9546ee",518:"3fa599de",567:"01f5b5fa",568:"77f099aa",661:"a29fc91b",671:"d4de47e6",672:"75d8310a",772:"a8815bbe",799:"9829201e",817:"c2ce7c33",894:"b6b85857",895:"e005492a",918:"dca4dae4",920:"06752a99",936:"0269c486",939:"7debcb5f",945:"ca5c17e3"}[e]+".js",b.miniCssF=e=>{},b.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||new Function("return this")()}catch(e){if("object"==typeof window)return window}}(),b.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),r={},o="lisk-docs:",b.l=(e,t,a,c)=>{if(r[e])r[e].push(t);else{var d,n;if(void 0!==a)for(var f=document.getElementsByTagName("script"),i=0;i{d.onerror=d.onload=null,clearTimeout(s);var o=r[e];if(delete r[e],d.parentNode&&d.parentNode.removeChild(d),o&&o.forEach((e=>e(a))),t)return t(a)},s=setTimeout(l.bind(null,void 0,{type:"timeout",target:d}),12e4);d.onerror=l.bind(null,d.onerror),d.onload=l.bind(null,d.onload),n&&document.head.appendChild(d)}},b.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},b.p="/lisk-documentation/",b.gca=function(e){return e={17896441:"918",56867589:"40","746da5eb":"0","935f2afb":"53","0eafa1eb":"68","2e7d4620":"80","1f391b9e":"85",de80008c:"124","6ce766bb":"184",b2059c63:"318",a94703ab:"368",d9983e98:"375",f7633811:"379","0480cc7e":"383","1224f3e7":"388","393be207":"414",bcc5765f:"421","6183c0e3":"444","951748bc":"445",f58537f1:"462",d38dfec1:"468",a7bd4aaa:"518","8bcd76a4":"567",dad52d3b:"568","5e95c892":"661","0e384e19":"671","5f139d3e":"672","6541bca2":"799","14eb3368":"817","4984adb1":"895","1a4e3797":"920",a8c021bd:"936","8d261ba2":"939"}[e]||e,b.p+b.u(e)},(()=>{var e={303:0,532:0};b.f.j=(t,a)=>{var r=b.o(e,t)?e[t]:void 0;if(0!==r)if(r)a.push(r[2]);else if(/^(303|532)$/.test(t))e[t]=0;else{var o=new Promise(((a,o)=>r=e[t]=[a,o]));a.push(r[2]=o);var c=b.p+b.u(t),d=new Error;b.l(c,(a=>{if(b.o(e,t)&&(0!==(r=e[t])&&(e[t]=void 0),r)){var o=a&&("load"===a.type?"missing":a.type),c=a&&a.target&&a.target.src;d.message="Loading chunk "+t+" failed.\n("+o+": "+c+")",d.name="ChunkLoadError",d.type=o,d.request=c,r[1](d)}}),"chunk-"+t,t)}},b.O.j=t=>0===e[t];var t=(t,a)=>{var r,o,c=a[0],d=a[1],n=a[2],f=0;if(c.some((t=>0!==e[t]))){for(r in d)b.o(d,r)&&(b.m[r]=d[r]);if(n)var i=n(b)}for(t&&t(a);f{"use strict";var e,t,a,r,o,c={},d={};function b(e){var t=d[e];if(void 0!==t)return t.exports;var a=d[e]={exports:{}};return c[e].call(a.exports,a,a.exports,b),a.exports}b.m=c,e=[],b.O=(t,a,r,o)=>{if(!a){var c=1/0;for(i=0;i=o)&&Object.keys(b.O).every((e=>b.O[e](a[n])))?a.splice(n--,1):(d=!1,o0&&e[i-1][2]>o;i--)e[i]=e[i-1];e[i]=[a,r,o]},b.n=e=>{var t=e&&e.__esModule?()=>e.default:()=>e;return b.d(t,{a:t}),t},a=Object.getPrototypeOf?e=>Object.getPrototypeOf(e):e=>e.__proto__,b.t=function(e,r){if(1&r&&(e=this(e)),8&r)return e;if("object"==typeof e&&e){if(4&r&&e.__esModule)return e;if(16&r&&"function"==typeof e.then)return e}var o=Object.create(null);b.r(o);var c={};t=t||[null,a({}),a([]),a(a)];for(var d=2&r&&e;"object"==typeof d&&!~t.indexOf(d);d=a(d))Object.getOwnPropertyNames(d).forEach((t=>c[t]=()=>e[t]));return c.default=()=>e,b.d(o,c),o},b.d=(e,t)=>{for(var a in t)b.o(t,a)&&!b.o(e,a)&&Object.defineProperty(e,a,{enumerable:!0,get:t[a]})},b.f={},b.e=e=>Promise.all(Object.keys(b.f).reduce(((t,a)=>(b.f[a](e,t),t)),[])),b.u=e=>"assets/js/"+({0:"746da5eb",40:"56867589",53:"935f2afb",68:"0eafa1eb",80:"2e7d4620",85:"1f391b9e",124:"de80008c",184:"6ce766bb",318:"b2059c63",368:"a94703ab",375:"d9983e98",379:"f7633811",383:"0480cc7e",388:"1224f3e7",414:"393be207",421:"bcc5765f",444:"6183c0e3",445:"951748bc",462:"f58537f1",468:"d38dfec1",518:"a7bd4aaa",567:"8bcd76a4",568:"dad52d3b",661:"5e95c892",671:"0e384e19",672:"5f139d3e",799:"6541bca2",817:"14eb3368",895:"4984adb1",918:"17896441",920:"1a4e3797",936:"a8c021bd",939:"8d261ba2"}[e]||e)+"."+{0:"9fb4d017",40:"15df44d3",53:"3b1ca015",68:"06991558",80:"69cc0dae",85:"8026121d",124:"cdaa3942",184:"52e3af1f",318:"31821c9d",325:"4aa58665",368:"68ae7f1b",375:"b0a38668",379:"a03228b3",383:"f247d45d",388:"f648b06f",414:"6280be6b",421:"8265f4a6",426:"ead49eea",444:"8af2ec63",445:"e857cfc4",462:"81742591",468:"0f9546ee",518:"3fa599de",567:"01f5b5fa",568:"77f099aa",661:"a29fc91b",671:"d4de47e6",672:"10282a6d",772:"a8815bbe",799:"9829201e",817:"c2ce7c33",894:"b6b85857",895:"e005492a",918:"dca4dae4",920:"06752a99",936:"d8c9495e",939:"7debcb5f",945:"ca5c17e3"}[e]+".js",b.miniCssF=e=>{},b.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||new Function("return this")()}catch(e){if("object"==typeof window)return window}}(),b.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),r={},o="lisk-docs:",b.l=(e,t,a,c)=>{if(r[e])r[e].push(t);else{var d,n;if(void 0!==a)for(var f=document.getElementsByTagName("script"),i=0;i{d.onerror=d.onload=null,clearTimeout(s);var o=r[e];if(delete r[e],d.parentNode&&d.parentNode.removeChild(d),o&&o.forEach((e=>e(a))),t)return t(a)},s=setTimeout(l.bind(null,void 0,{type:"timeout",target:d}),12e4);d.onerror=l.bind(null,d.onerror),d.onload=l.bind(null,d.onload),n&&document.head.appendChild(d)}},b.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},b.p="/lisk-documentation/",b.gca=function(e){return e={17896441:"918",56867589:"40","746da5eb":"0","935f2afb":"53","0eafa1eb":"68","2e7d4620":"80","1f391b9e":"85",de80008c:"124","6ce766bb":"184",b2059c63:"318",a94703ab:"368",d9983e98:"375",f7633811:"379","0480cc7e":"383","1224f3e7":"388","393be207":"414",bcc5765f:"421","6183c0e3":"444","951748bc":"445",f58537f1:"462",d38dfec1:"468",a7bd4aaa:"518","8bcd76a4":"567",dad52d3b:"568","5e95c892":"661","0e384e19":"671","5f139d3e":"672","6541bca2":"799","14eb3368":"817","4984adb1":"895","1a4e3797":"920",a8c021bd:"936","8d261ba2":"939"}[e]||e,b.p+b.u(e)},(()=>{var e={303:0,532:0};b.f.j=(t,a)=>{var r=b.o(e,t)?e[t]:void 0;if(0!==r)if(r)a.push(r[2]);else if(/^(303|532)$/.test(t))e[t]=0;else{var o=new Promise(((a,o)=>r=e[t]=[a,o]));a.push(r[2]=o);var c=b.p+b.u(t),d=new Error;b.l(c,(a=>{if(b.o(e,t)&&(0!==(r=e[t])&&(e[t]=void 0),r)){var o=a&&("load"===a.type?"missing":a.type),c=a&&a.target&&a.target.src;d.message="Loading chunk "+t+" failed.\n("+o+": "+c+")",d.name="ChunkLoadError",d.type=o,d.request=c,r[1](d)}}),"chunk-"+t,t)}},b.O.j=t=>0===e[t];var t=(t,a)=>{var r,o,c=a[0],d=a[1],n=a[2],f=0;if(c.some((t=>0!==e[t]))){for(r in d)b.o(d,r)&&(b.m[r]=d[r]);if(n)var i=n(b)}for(t&&t(a);f Deploying an ERC-20 Token to Lisk | Lisk Documentation - + diff --git a/building-on-lisk/add-token-to-lisk/custom-token.html b/building-on-lisk/add-token-to-lisk/custom-token.html index 9ef7e9aef..f36c39cfa 100644 --- a/building-on-lisk/add-token-to-lisk/custom-token.html +++ b/building-on-lisk/add-token-to-lisk/custom-token.html @@ -5,7 +5,7 @@ Deploying a custom token | Lisk Documentation - + @@ -13,7 +13,7 @@

Deploying your Custom ERC-20 token to Lisk

-
info

This tutorial is for developers who want to bridge a new Custom ERC-20 token to Lisk Mainnet.

If you want to bridge existing tokens, you can follow the tutorial on Bridging ERC-20 tokens with the Optimism SDK.

+

In this tutorial you'll learn how to bridge a custom ERC-20 token from Ethereum to Lisk Sepolia using the Standard Bridge system. This tutorial is meant for developers who already have an existing ERC-20 token on Ethereum and want to create a bridged representation of that token on Lisk Sepolia.

Learn step-by-step how you can create a custom token that conforms to the IOptimismMintableERC20 interface so that it can be used with the Standard Bridge system. @@ -63,12 +63,7 @@

6. Dep Then, select the MyCustomL2Token contract from the deployment dropdown and deploy it with the following parameters:

_BRIDGE:      "0x4200000000000000000000000000000000000007"
_REMOTETOKEN: "<L1 ERC-20 address>"
_NAME: "My Custom Lisk L2 Token"
_SYMBOL: "MCL2T"
tip

If you used the testing token described in step Get an L1 ERC-20 Token Address, use the address 0x5589BB8228C07c4e15558875fAf2B859f678d129 for the _REMOTETOKEN parameter.

-

Bridge Some Tokens

-

Now that you have an L2 ERC-20 token, you can bridge some tokens from L1 to L2.

- -

Check out the tutorial on Bridging ERC-20 tokens with the Optimism SDK to learn how to bridge your L1 ERC-20 to Lisk using the Optimism SDK. -Remember that the withdrawal step will not work for the token you just created! -This is exactly what this tutorial was meant to demonstrate.