@victorkanu1.near [Posted on DevHub](/devgovgigs.near/widget/Post?id=2524) {"title":"Quick Guide to Building Ethereum Apps on the BOS 👨🏽‍💻","subtitle":"","description":"","date":"2023-12-13T10:15:09.349Z","content":"# Introduction\n\nBuilding Ethereum dApps on the BOS Network involves interacting with your Ethereum wallet and smart contracts. BOS allows you to connect the Ether.js library (Ethereum API) within its virtual machine (VM), enabling seamless interaction with smart contracts and your MetaMask wallet. This quick guide will walk you through the essential steps.\n\n### **Step 1: Getting the Contract Address**\n\nThe first step is to identify the smart contract you want to interact with. Most projects, like Gains Network on the BOS or Uniswap, provide a website with links to their contract addresses. Once you have the contract address in mind, you'll need to obtain the ABI (Application Binary Interface) for the contract. The ABI defines the functions that you can call on the contract, and it can usually be found on Etherscan.\n\n### **Step 2: Establishing Wallet Connectivity**\n\nTo interact, you need to connect your wallet because it is used to make RPC calls. BOS provides a widget known as `\"web3 connect\"` to handle wallet connections. This component seamlessly integrates with MetaMask. When you click on it, it opens up your MetaMask, prompting you to grant permission to connect your wallet.\n\n\n```\n<Web3Connect\n className=\"CssClassName\"\n connectLabel=\"ButtonLabel\"\n />\n )}\n```\n\nOnce the connection is successful you have access to the connected account, you can make contract calls with your existing deployed contract using your existing contract address (Address that was used to deploy your contract) and ABI (Application Binary Interface). \n\n**Note**: This means you must have deployed your App and you actually have an ABI before trying to make such contract calls.\n\n\n### **Step 3: Setting up the Contract Interface**\n\nNow you need to call the contract, so you have to convert the ABI into a proper interface by calling an ethers function and then passing in that ABI to the function. To convert the ABI into a usable interface, you can use the following code:\n\n```\nconst iface = new ethers.utils.Interface(stakingAbi.body);\n```\n\nThis code transforms the ABI into a proper interface. With this interface, you can call functions from the contract with ease. For example:\n\n```\nconst getTokenBalance = (receiver) => {\n const encodedData = tokenIFace.encodeFunctionData(\"balanceOf\", [receiver]);\n```\n\nBasically you call the interface you converted, then you do `.encodefunctiondata` which means you're trying to encode the function that we are trying to call. Then you pass in the name of the function which is `balanceOf` , and if the function takes a parameter, you pass in an \"array\".\n\n### **Step 4: Interacting with the Contract**\n\n```\nconst getRewardBalance = () => {\n const encodedData = iface.encodeFunctionData(\"accDaiPerToken\");\n return Ethers.provider()\n .call({\n to: gainsStakingContract,\n data: encodedData,\n })\n```\n\ngetRewardBalance is a javascript function responsible for calling the contract method called `“accDaiPerToken”` on the Gains Staking contract. it does this by encoding the call data on the interface and then making an RPC call with the `Ethers.provider` code piece to the gainsContract sending the encoded data along. `“accDaiPerToken”` function call takes no params, if it did the the data encoding will change thus: `const encodedData = iface.encodeFunctionData(\"accDaiPerToken\", [param1, param2]);` where param1 and param2 are function parameters of `“accDaiPerToken”`\n\nThis function fetches the reward balance of a user for the staked token. Make sure to adjust this code according to the specific contract functions you want to interact with.\n\n### **Step 5: State Management**\n\nAfter interacting with the contract , you obviously want to manage the variables, you can do so by using state management api on the BOS\n\n**2 functions:**\n\n`State.init` : This is what you use to initialize your contract state , to set default values \n\n`State.update`: This changes values on your state\n\n```\ngetRewardBalance().then((rewards) => {\n State.update({ rewards });\n });\n```\n\nIn the snippet above, after calling the getRewardBalance function which calls a contract function to get this value, we await the response and then set it in state using State.update updates a value if found in state, if the value does not exist prior, it sets it.\n\nNote: Styling on the BOS can be done using either “styled components” or “Bootstrap”\n\n\n### **Calling swap methods on Uniswap**\n\nIn case you're wondering how calling a swap method on Uniswap would look like, take a look at this code snippet:\n\n```jsx\nconst SwapToken = () => {\n const encodedData = uniIface.encodeFunctionData(\"exactInputSingle\", [tokenIn, tokenOut,fee,recipient,deadline,amountIn,amountOutMinimum,sqrtPriceLimitX96]);\n return Ethers.provider()\n .call({\n to: swapRouterContract,\n data: encodedData,\n })\n```\n\nThe above snippet is a sample contract call to the uniswap router contract which swaps a token `tokenIn` for another token `tokenOut`.\n\n**More examples of calling swap methods on Uniswap:** https://docs.uniswap.org/contracts/v3/guides/swaps/single-swaps\n\n\n## **List of API's for building on ethereum**\n\nBOS has imported the Ethers Library (ethers.js) allowing for seamless connection with Ethereum nodes.\n\nThe Ethers Object Exposes the Provider Connection.\n\n- `Ethers.provider()` - this is a read-only connection to the blockchain which allows querying the blockchain state. This can be used to fetch information about accounts, block or transaction details, or even event logs.\n - `Ethers().provider().getSigner()` - abstracts the class that interacts with an account.\n - `Ethers().provider().getBlockNumber()`- Looks up current block number. e.t.c you can reference the [ethers docs](https://docs.ethers.org/v6/getting-started/) for more examples\n \n\t**Examples**\n\n1. **How to get a User account:**\n \n *`const* receiver = Ethers.provider().send(\"eth_requestAccounts\", [])[0];` \n \n This single line of code will check for the user-connected account on which ever chain and assign it to the variable `receiver`. Keep in mind that if the user is connected to a web3 wallet (e.g Metamask) it’s going to return a `null` value.\n \n2. **How to get Current ChainID:** \n \n This is very useful when working with multi-chain, it’s good to know which chain the user is connected to, allowing you to throw errors when connected to the wrong chains, also most contract calls needs to be made with the chain Id.\n \n ```jsx\n Ethers.provider().getNetwork().then((chainIdData) => {`\n \n `console.log(chainIdData.chainId);`\n \n });\n ```\n \n The `chainId` is logged out in the above example, but you could also assign that to a state variable\n \n3. ****************************How to Retrieve Gas Price:**************************** \n \n When interacting with the Ethereum blockchain, it's important to be aware of the current gas prices to estimate transaction fees. The following code snippet demonstrates how to retrieve the current gas price:\n\t\n```\n\nEthers.provider().getGasPrice().then((gasPrice) => {\nconsole.log(Current gas price: ${gasPrice.toString()} Wei);\n});\n```\n\n4. **Fetch Transaction Receipt:**\n \n After sending a transaction, it's often necessary to check its status and obtain additional details. The **`getTransactionReceipt`** method can be used for this purpose:\n \n ```jsx\n const txHash = '0xabcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890';\n \n Ethers.provider().getTransactionReceipt(txHash).then((receipt) => {\n console.log(`Transaction Receipt: ${JSON.stringify(receipt, null, 2)}`);\n });\n ```\n \n5. **Query Contract State**\n \n ```jsx\n const contractAddress = '0x1234567890123456789012345678901234567890';\n const contractAbi = [...]; // ABI of your contract (After Compiling)\n \n For example, if you have a Solidity file named MyContract.sol, compiling it with solc might generate a file like MyContract.json that contains the ABI. \n \n const contract = new ethers.Contract(contractAddress, contractAbi, Ethers.provider());\n \n contract.someReadOnlyFunction().then((result) => {\n console.log(`Result of read-only function: ${result}`);\n });\n \n // someReadOnlyFunction is just a placeholder for the name of the read-only\n // function in your contract, so it could be anything based on what's defined\n // in your contract\n ```\n \n **Note**: When you compile your Solidity contract using a Solidity compiler, such as solc (the Solidity compiler), the compiler will generate various artifacts, including the ABI. This information is often stored in a separate file, usually with a `.json` extension.\n \n Also Remember to replace the placeholder values like `txHash`, `contractAddress`, and `contractAbi` with your actual values. \n \n **These examples demonstrate different use cases for the `Provider` object in the Ethers library.**\n\t","author":"","category":"guide"}