/
relayToEthereum.go
148 lines (126 loc) · 4.44 KB
/
relayToEthereum.go
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
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
package txs
import (
"context"
"crypto/ecdsa"
"fmt"
"log"
"math/big"
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/ethclient"
cosmosbridge "github.com/sun-blockchain/harmony-cosmos-cross/cmd/ebrelayer/contract/generated/bindings/cosmosbridge"
oracle "github.com/sun-blockchain/harmony-cosmos-cross/cmd/ebrelayer/contract/generated/bindings/oracle"
"github.com/sun-blockchain/harmony-cosmos-cross/cmd/ebrelayer/types"
)
const (
// GasLimit the gas limit in Gwei used for transactions sent with TransactOpts
GasLimit = uint64(3000000)
)
// RelayProphecyClaimToEthereum relays the provided ProphecyClaim to CosmosBridge contract on the Ethereum network
func RelayProphecyClaimToEthereum(provider string, contractAddress common.Address, event types.Event,
claim ProphecyClaim, key *ecdsa.PrivateKey) error {
// Initialize client service, validator's tx auth, and target contract address
client, auth, target := initRelayConfig(provider, contractAddress, event, key)
// Initialize CosmosBridge instance
fmt.Println("\nFetching CosmosBridge contract...")
cosmosBridgeInstance, err := cosmosbridge.NewCosmosBridge(target, client)
if err != nil {
log.Fatal(err)
}
// Send transaction
fmt.Println("Sending new ProphecyClaim to CosmosBridge...")
tx, err := cosmosBridgeInstance.NewProphecyClaim(auth, uint8(claim.ClaimType),
claim.CosmosSender, claim.EthereumReceiver, claim.Symbol, claim.Amount)
if err != nil {
log.Fatal(err)
}
fmt.Println("NewProphecyClaim tx hash:", tx.Hash().Hex())
// Get the transaction receipt
receipt, err := client.TransactionReceipt(context.Background(), tx.Hash())
if err != nil {
log.Fatal(err)
}
switch receipt.Status {
case 0:
fmt.Println("Tx Status: 0 - Failed")
case 1:
fmt.Println("Tx Status: 1 - Successful")
}
return nil
}
// RelayOracleClaimToEthereum relays the provided OracleClaim to Oracle contract on the Ethereum network
func RelayOracleClaimToEthereum(provider string, contractAddress common.Address, event types.Event,
claim OracleClaim, key *ecdsa.PrivateKey) error {
// Initialize client service, validator's tx auth, and target contract address
client, auth, target := initRelayConfig(provider, contractAddress, event, key)
// Initialize Oracle instance
fmt.Println("\nFetching Oracle contract...")
oracleInstance, err := oracle.NewOracle(target, client)
if err != nil {
log.Fatal(err)
}
// Send transaction
fmt.Println("Sending new OracleClaim to Oracle...")
tx, err := oracleInstance.NewOracleClaim(auth, claim.ProphecyID, claim.Message, claim.Signature)
if err != nil {
log.Fatal(err)
}
fmt.Println("NewOracleClaim tx hash:", tx.Hash().Hex())
// Get the transaction receipt
receipt, err := client.TransactionReceipt(context.Background(), tx.Hash())
if err != nil {
log.Fatal(err)
}
switch receipt.Status {
case 0:
fmt.Println("Tx Status: 0 - Failed")
case 1:
fmt.Println("Tx Status: 1 - Successful")
}
return nil
}
// initRelayConfig set up Ethereum client, validator's transaction auth, and the target contract's address
func initRelayConfig(provider string, registry common.Address, event types.Event, key *ecdsa.PrivateKey,
) (*ethclient.Client, *bind.TransactOpts, common.Address) {
// Start Ethereum client
client, err := ethclient.Dial(provider)
if err != nil {
log.Fatal(err)
}
// Load the validator's address
sender, err := LoadSender()
if err != nil {
log.Fatal(err)
}
nonce, err := client.PendingNonceAt(context.Background(), sender)
if err != nil {
log.Fatal(err)
}
gasPrice, err := client.SuggestGasPrice(context.Background())
if err != nil {
log.Fatal(err)
}
// Set up TransactOpts auth's tx signature authorization
transactOptsAuth := bind.NewKeyedTransactor(key)
transactOptsAuth.Nonce = big.NewInt(int64(nonce))
transactOptsAuth.Value = big.NewInt(0) // in wei
transactOptsAuth.GasLimit = GasLimit
transactOptsAuth.GasPrice = gasPrice
var targetContract ContractRegistry
switch event {
// ProphecyClaims are sent to the CosmosBridge contract
case types.MsgBurn, types.MsgLock:
targetContract = CosmosBridge
// OracleClaims are sent to the Oracle contract
case types.LogNewProphecyClaim:
targetContract = Oracle
default:
panic("invalid target contract address")
}
// Get the specific contract's address
target, err := GetAddressFromBridgeRegistry(client, registry, targetContract)
if err != nil {
log.Fatal(err)
}
return client, transactOptsAuth, target
}