/
rpc.go
138 lines (112 loc) · 3.28 KB
/
rpc.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
package blockchain
import (
"time"
"github.com/ethereum/go-ethereum/common"
gethTypes "github.com/ethereum/go-ethereum/core/types"
providers "github.com/openweb3/go-rpc-provider/provider_wrapper"
"github.com/openweb3/web3go"
"github.com/openweb3/web3go/interfaces"
"github.com/openweb3/web3go/signers"
"github.com/openweb3/web3go/types"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
)
var Web3LogEnabled bool
type RetryOption struct {
Rounds uint
Interval time.Duration
}
func MustNewWeb3(url, key string) *web3go.Client {
client, err := NewWeb3(url, key)
if err != nil {
logrus.WithError(err).WithField("url", url).Fatal("Failed to connect to fullnode")
}
return client
}
func NewWeb3(url, key string) (*web3go.Client, error) {
sm := signers.MustNewSignerManagerByPrivateKeyStrings([]string{key})
option := new(web3go.ClientOption).
WithRetry(3, time.Second).
WithTimout(5 * time.Second).
WithSignerManager(sm)
if Web3LogEnabled {
option = option.WithLooger(logrus.StandardLogger().Out)
}
return web3go.NewClientWithOption(url, *option)
}
func NewWeb3WithOption(url, key string, option ...providers.Option) (*web3go.Client, error) {
var opt web3go.ClientOption
if len(option) > 0 {
opt.Option = option[0]
}
sm := signers.MustNewSignerManagerByPrivateKeyStrings([]string{key})
return web3go.NewClientWithOption(url, *opt.WithSignerManager(sm))
}
func WaitForReceipt(client *web3go.Client, txHash common.Hash, successRequired bool, opts ...RetryOption) (receipt *types.Receipt, err error) {
var opt RetryOption
if len(opts) > 0 {
opt = opts[0]
} else {
// default infinite wait
opt.Rounds = 0
opt.Interval = time.Second * 3
}
var tries uint
for receipt == nil {
if tries > opt.Rounds+1 && opt.Rounds != 0 {
return nil, errors.New("no receipt after max retries")
}
time.Sleep(opt.Interval)
if receipt, err = client.Eth.TransactionReceipt(txHash); err != nil {
return nil, err
}
tries++
}
if receipt.Status == nil {
return nil, errors.New("Status not found in receipt")
}
switch *receipt.Status {
case gethTypes.ReceiptStatusSuccessful:
return receipt, nil
case gethTypes.ReceiptStatusFailed:
if !successRequired {
return receipt, nil
}
if receipt.TxExecErrorMsg == nil {
return nil, errors.New("Transaction execution failed")
}
return nil, errors.Errorf("Transaction execution failed, %v", *receipt.TxExecErrorMsg)
default:
return nil, errors.Errorf("Unknown receipt status %v", *receipt.Status)
}
}
func defaultSigner(clientWithSigner *web3go.Client) (interfaces.Signer, error) {
sm, err := clientWithSigner.GetSignerManager()
if err != nil {
return nil, errors.WithMessage(err, "Failed to get signer manager from client")
}
if sm == nil {
return nil, errors.New("Signer not specified")
}
signers := sm.List()
if len(signers) == 0 {
return nil, errors.WithMessage(err, "Account not configured in signer manager")
}
return signers[0], nil
}
func ConvertToGethLog(log *types.Log) *gethTypes.Log {
if log == nil {
return nil
}
return &gethTypes.Log{
Address: log.Address,
Topics: log.Topics,
Data: log.Data,
BlockNumber: log.BlockNumber,
TxHash: log.TxHash,
TxIndex: log.TxIndex,
BlockHash: log.BlockHash,
Index: log.Index,
Removed: log.Removed,
}
}