aboutsummaryrefslogtreecommitdiff
path: root/examples/arc20/main.go
blob: 303d620d2bc1355302204bcf1c08d3cbe0d0428c (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
package main

import (
	"context"
	"crypto/ecdsa"
	"fmt"
	"math/big"

	"github.com/ava-labs/coreth/params"
	"github.com/ethereum/go-ethereum/common"
	"github.com/ethereum/go-ethereum/core/types"
	"github.com/ethereum/go-ethereum/crypto"
	"github.com/ethereum/go-ethereum/ethclient"
)

var (
	uri                    = "http://127.0.0.1:9650/ext/bc/C/rpc"
	nativeAssetBalanceAddr = common.HexToAddress("0x0100000000000000000000000000000000000001")
	nativeAssetCallAddr    = common.HexToAddress("0x0100000000000000000000000000000000000002")
	chainID                = new(big.Int).SetUint64(43112)
	privateKey             *ecdsa.PrivateKey
	address                common.Address
	erc20                  common.Address
	assetID                *big.Int
	amount                 *big.Int
	gasLimit               = uint64(700000)
	gasPrice               = params.MinGasPrice
)

func init() {
	// Private Key to sign deposit transaction
	// To export from MetaMask:
	// 1) Click ellipsis on right hand side of account page
	// 2) View Account Details
	// 3) Export Private Key
	pk, err := crypto.HexToECDSA("da777cd656c8760a7d378ae04d7dd0cd7a703c450c84e6c2faa886ca97517df7")
	if err != nil {
		panic(err)
	}
	privateKey = pk
	// Extract From Address from the private key
	address = crypto.PubkeyToAddress(privateKey.PublicKey)
	// erc20 = common.HexToAddress("0xea75d59faF258F1fdf2b94F158e54D7ad44359B6")
	// Address of ARC-20 to deposit funds in
	erc20 = common.HexToAddress("0x721F9Af7631605713133ccc502E32eA4d43CDfec")
	// AssetID as a uint256 integer as displayed in Remix of the ARC-20
	assetID = common.HexToHash("0x42f0d24c970eb6c567ea63a68b97d8e357a7fc8d9f73489c7761f1382b295db4").Big()
	amount = new(big.Int).SetUint64(100)
}

// createDepositCallData creates the callData argument to nativeAssetTransfer to move [amount]
// of [assetID] to [erc20] address and call the deposit function with signature "deposit()"
func createDepositCallData(erc20 common.Address, assetID, amount *big.Int) []byte {
	// erc20 addr, assetID, assetAmount, callData
	signatureHash := crypto.Keccak256([]byte("deposit()"))
	fmt.Printf("signatureHash: 0x%x\n", signatureHash)
	functionSignature := signatureHash[:4]
	data := make([]byte, 0, 84)
	data = append(data, erc20.Bytes()...)
	data = append(data, common.LeftPadBytes(assetID.Bytes(), 32)...)
	data = append(data, common.LeftPadBytes(amount.Bytes(), 32)...)
	data = append(data, functionSignature...) // Add this back in to trigger call to deposit
	fmt.Printf("deposit callData: 0x%x\n", data)
	return data
}

// createDepositTransaction creates a transaction to deposit native asset funds in [erc20]
func createDepositTransaction(nonce uint64, erc20 common.Address, assetID, amount *big.Int, gasLimit uint64, gasPrice *big.Int) *types.Transaction {
	callData := createDepositCallData(erc20, assetID, amount)
	return types.NewTransaction(nonce, nativeAssetCallAddr, new(big.Int), gasLimit, gasPrice, callData)
}

// deploy ARC-20 contract with specific assetID
func main() {
	client, err := ethclient.Dial(uri)
	if err != nil {
		panic(err)
	}
	ctx := context.Background()
	nonce, err := client.NonceAt(ctx, address, nil)
	if err != nil {
		panic(err)
	}
	fmt.Printf("Creating deposit transaction from: %s, erc20 address: %s, assetID: %d, amount: %d, nonce: %d\n", address.Hex(), erc20.Hex(), assetID, amount, nonce)
	// Create and sign deposit transaction from account that has been funded with sufficient AVAX to
	// pay gas costs and sufficient amount of the native asset to make the deposit
	tx := createDepositTransaction(nonce, erc20, assetID, amount, gasLimit, gasPrice)
	signer := types.NewEIP155Signer(chainID)
	signedTx, err := types.SignTx(tx, signer, privateKey)
	if err != nil {
		panic(err)
	}
	// Send the signed transaction to the client
	if err := client.SendTransaction(ctx, signedTx); err != nil {
		panic(err)
	}
	txHash := signedTx.Hash()
	fmt.Printf("txHash: %s\n", txHash.Hex())
}