-
Notifications
You must be signed in to change notification settings - Fork 0
/
contract.go
100 lines (80 loc) · 2.26 KB
/
contract.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
// Copyright (C) 2023 Wooyang2018
// Licensed under the GNU General Public License v3.0
package runtime
import (
"math/big"
"strings"
"github.com/ethereum/go-ethereum/accounts/abi"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/holiman/uint256"
"github.com/wooyang2018/svp-blockchain/logger"
)
type Contract struct {
Abi abi.ABI
Cfg *Config
Address common.Address
AutoCommit bool
}
func Ensure(err error) {
if err != nil {
panic(err)
}
}
func Create2Contract(cfg *Config, jsonABI, hexCode string, salt uint64, params ...interface{}) *Contract {
contractBin, err := hexutil.Decode(hexCode)
Ensure(err)
cabi, err := abi.JSON(strings.NewReader(jsonABI))
Ensure(err)
var p []byte
if len(params) != 0 {
p, err = cabi.Pack("", params...)
Ensure(err)
}
deploy := append(contractBin, p...)
_, ctAddr, leftGas, err := Create2(deploy, cfg, uint256.NewInt(0).SetUint64(salt))
Ensure(err)
logger.I().Infof("deploy code at: %s, used gas: %d", ctAddr.String(), cfg.GasLimit-leftGas)
return &Contract{
Abi: cabi,
Cfg: cfg,
Address: ctAddr,
}
}
// CreateContract create and deploy a contract
func CreateContract(cfg *Config, jsonABI string, hexCode string, params ...interface{}) *Contract {
contractBin, err := hexutil.Decode(hexCode)
Ensure(err)
cabi, err := abi.JSON(strings.NewReader(jsonABI))
Ensure(err)
var p []byte
if len(params) != 0 {
p, err = cabi.Pack("", params...)
Ensure(err)
}
deploy := append(contractBin, p...)
_, ctAddr, leftGas, err := Create(deploy, cfg)
Ensure(err)
logger.I().Infof("deploy code at: %s, used gas: %d", ctAddr.String(), cfg.GasLimit-leftGas)
return &Contract{
Abi: cabi,
Cfg: cfg,
Address: ctAddr,
}
}
func (self *Contract) Call(method string, params ...interface{}) ([]byte, uint64, error) {
input, err := self.Abi.Pack(method, params...)
Ensure(err)
ret, gas, err := Call(self.Address, input, self.Cfg)
if self.AutoCommit {
err := self.Cfg.State.Commit()
Ensure(err)
}
return ret, self.Cfg.GasLimit - gas, err
}
func (self *Contract) Balance() *big.Int {
return self.Cfg.State.GetBalance(self.Address)
}
func (self *Contract) BalanceOf(addr common.Address) *big.Int {
return self.Cfg.State.GetBalance(addr)
}