Skip to content

Commit

Permalink
feat: deploy wrapped coin
Browse files Browse the repository at this point in the history
  • Loading branch information
hanchon committed Aug 21, 2024
1 parent 56e43bc commit e139700
Show file tree
Hide file tree
Showing 4 changed files with 136 additions and 8 deletions.
36 changes: 30 additions & 6 deletions cmd/playground/tx/solidity/deployERC20.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ import (

// deployERC20Cmd represents the deploy command
var deployERC20Cmd = &cobra.Command{
Use: "deploy-erc20 [name] [symbol] [initial_amount]",
Args: cobra.ExactArgs(3),
Use: "deploy-erc20 [name] [symbol]",
Args: cobra.ExactArgs(2),
Short: "Deploy an erc20 contract",
Run: func(cmd *cobra.Command, args []string) {
queries := sql.InitDBFromCmd(cmd)
Expand All @@ -31,9 +31,14 @@ var deployERC20Cmd = &cobra.Command{
os.Exit(1)
}

initialAmount, err := cmd.Flags().GetString("initial-amount")
if err != nil {
fmt.Println("incorrect initial-amount")
os.Exit(1)
}

name := args[0]
symbol := args[1]
initialAmount := args[2]

// TODO: allow mainnet as a valid endpoint
e := evmos.NewEvmosFromDB(queries, nodeID)
Expand All @@ -58,16 +63,32 @@ var deployERC20Cmd = &cobra.Command{
os.Exit(1)
}

// Create the contract
contract := solidity.GenerateERC20Contract(path, name, symbol, initialAmount)
isWrapped, err := cmd.Flags().GetBool("is-wrapped-coin")
if err != nil {
fmt.Println("incorrect wrapped flag")
os.Exit(1)
}

contract := ""
solcVersion := "0.8.25"
switch isWrapped {
case false:
// Normal ERC20
contract = solidity.GenerateERC20Contract(path, name, symbol, initialAmount)
case true:
// Wrapping base denom, use WETH9
contract = solidity.GenerateWrappedCoinContract(name, symbol, "18")
solcVersion = "0.4.18"
}

contractPath := filesmanager.GetBranchFolder(folderName) + "/mycontract.sol"
if err := filesmanager.SaveFile([]byte(contract), contractPath); err != nil {
fmt.Println("could not save the contract file:", err.Error())
os.Exit(1)
}

// Compile the contract
err = solidity.CompileWithSolc("0.8.25", contractPath, filesmanager.GetBranchFolder(folderName))
err = solidity.CompileWithSolc(solcVersion, contractPath, filesmanager.GetBranchFolder(folderName))
if err != nil {
fmt.Println("could not compile the erc20 contract:", err.Error())
os.Exit(1)
Expand Down Expand Up @@ -110,4 +131,7 @@ var deployERC20Cmd = &cobra.Command{
func init() {
SolidityCmd.AddCommand(deployERC20Cmd)
deployERC20Cmd.Flags().Int("gas-limit", 2_000_000, "GasLimit to be used to deploy the transaction")
deployERC20Cmd.Flags().String("initial-amount", "1000000", "Initial amout of coins sent to the deployer address")
deployERC20Cmd.Flags().Bool("is-wrapped-coin", false, "Flag used to indenfity if the contract is representing the base denom. It uses WETH9 instead of OpenZeppelin contracts")

}
24 changes: 23 additions & 1 deletion cmd/playground/tx/solidity/deployUniswapV2Factory.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,12 @@ package solidity

import (
"encoding/hex"
"encoding/json"
"fmt"
"os"

"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/crypto"
"github.com/hanchon/hanchond/lib/smartcontract"
"github.com/hanchon/hanchond/playground/evmos"
"github.com/hanchon/hanchond/playground/filesmanager"
Expand Down Expand Up @@ -119,7 +122,26 @@ var deployUniswapV2FactoryCmd = &cobra.Command{
os.Exit(1)
}

fmt.Printf("{\"contract_address\":\"%s\", \"tx_hash\":\"%s\"}\n", receipt.Result.ContractAddress, txHash)
codeHash, err := e.NewRequester().EthCode(receipt.Result.ContractAddress, "latest")
if err != nil {
fmt.Println("failed to get the eth code:", err.Error())
os.Exit(1)
}
type code struct {
Result string `json:"result"`
}
var c code
if err := json.Unmarshal(codeHash, &c); err != nil {
fmt.Println("failed to get the eth code:", err.Error())
os.Exit(1)
}

// Perform keccak256 hashing
hash := crypto.Keccak256(common.Hex2Bytes(c.Result[2:]))
// Convert hash to hexadecimal string for display
hashHex := hex.EncodeToString(hash)

fmt.Printf("{\"contract_address\":\"%s\", \"code_hash\":\"%s\", \"tx_hash\":\"%s\"}\n", receipt.Result.ContractAddress, "0x"+hashHex, txHash)

// Clean up files
if err := filesmanager.CleanUpTempFolder(); err != nil {
Expand Down
15 changes: 14 additions & 1 deletion docs/pages/hanchond/playground/tx/solidity/deployERC20.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,26 @@ Params:

- Name
- Symbol
- Initial Amount (will be sent to the deployer)

Optional:

- Initial Amount (will be sent to the deployer) `--initial-amount`
- IsWrappedCoin (if it's wrapping the base denom) `--is-wrapped-coin`. This requires `solc v0.4.18`

:::warning
If you are creating a network with Evmos v19+, the Wrapped Evmos will be automatically generated.
:::

```sh
hanchond playground tx solidity deploy-erc20 Hanchon HCH 10000000
{"contract_address":"0xe38de16950d3f1048f940268f80ef80bdd10d750", "tx_hash":"0x0ba8e69c71013345f28d7514125c7f323464b4179a68b2a8c28defcf2e96ef3a"}
```

```sh
hanchond playground tx solidity deploy-erc20 WrappedEvmos WEVMOS --is-wrapped-coin
{"contract_address":"0x0d5b94e15b5b6068e7cc4a9b6ee3a1cde89113ca", "tx_hash":"0x7eeda7ef271f64eb21aebfe64a9cac8e8631692d5201a1be63c4fbf001b5e84a"}
```

:::info
The flag `gas-limit` can be set to use custom gas. It defaults to 2_000_000.
:::
69 changes: 69 additions & 0 deletions playground/solidity/erc20builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,3 +29,72 @@ contract %s is ERC20, ERC20Permit {
}
`, openzeppelinPath, openzeppelinPath, name, name, symbol, name, initialAmount)
}

func GenerateWrappedCoinContract(name, symbol, decimals string) string {
name = StringToTitle(name)
symbol = strings.ToUpper(symbol)
return fmt.Sprintf(`pragma solidity ^0.4.18;
contract %s {
string public name = "%s";
string public symbol = "%s";
uint8 public decimals = %s;
event Approval(address indexed src, address indexed guy, uint wad);
event Transfer(address indexed src, address indexed dst, uint wad);
event Deposit(address indexed dst, uint wad);
event Withdrawal(address indexed src, uint wad);
mapping(address => uint) public balanceOf;
mapping(address => mapping(address => uint)) public allowance;
function() public payable {
deposit();
}
function deposit() public payable {
balanceOf[msg.sender] += msg.value;
Deposit(msg.sender, msg.value);
}
function withdraw(uint wad) public {
require(balanceOf[msg.sender] >= wad);
balanceOf[msg.sender] -= wad;
msg.sender.transfer(wad);
Withdrawal(msg.sender, wad);
}
function totalSupply() public view returns (uint) {
return this.balance;
}
function approve(address guy, uint wad) public returns (bool) {
allowance[msg.sender][guy] = wad;
Approval(msg.sender, guy, wad);
return true;
}
function transfer(address dst, uint wad) public returns (bool) {
return transferFrom(msg.sender, dst, wad);
}
function transferFrom(
address src,
address dst,
uint wad
) public returns (bool) {
require(balanceOf[src] >= wad);
if (src != msg.sender && allowance[src][msg.sender] != uint(-1)) {
require(allowance[src][msg.sender] >= wad);
allowance[src][msg.sender] -= wad;
}
balanceOf[src] -= wad;
balanceOf[dst] += wad;
Transfer(src, dst, wad);
return true;
}
}`, name, name, symbol, decimals)
}

0 comments on commit e139700

Please sign in to comment.