Skip to content

Commit fd589e9

Browse files
Internal contract2 (#195)
* add new internal contracts * update internal contracts * add test unpack for tuple * nil * update * nil
1 parent 2ef4b71 commit fd589e9

File tree

5 files changed

+426
-1
lines changed

5 files changed

+426
-1
lines changed

cfxclient/bulk/bulk_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import (
1313

1414
// use
1515
func TestBulkCall(t *testing.T) {
16-
_client, err := client.NewClient("https://test.confluxrpc.com")
16+
_client, err := client.NewClient("https://test.confluxrpc.com", client.ClientOption{RetryCount: 3})
1717
// _client.UseBatchCallRpcMiddleware(middleware.BatchCallRpcConsoleMiddleware)
1818
if err != nil {
1919
panic(err)
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
package internalcontract
2+
3+
import (
4+
"bytes"
5+
"encoding/hex"
6+
"math/big"
7+
"testing"
8+
9+
"github.com/ethereum/go-ethereum/accounts/abi"
10+
"github.com/stretchr/testify/assert"
11+
)
12+
13+
func TestUnpackToTuple(t *testing.T) {
14+
data, err := hex.DecodeString("00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000")
15+
assert.NoError(t, err)
16+
17+
abiStr := "[{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"identifier\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"votePower\",\"type\":\"uint64\"}],\"name\":\"IncreaseStake\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"identifier\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"blsPubKey\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"vrfPubKey\",\"type\":\"bytes\"}],\"name\":\"Register\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"identifier\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"votePower\",\"type\":\"uint64\"}],\"name\":\"Retire\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"}],\"name\":\"addressToIdentifier\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"identifier\",\"type\":\"bytes32\"}],\"name\":\"getVotes\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"identifier\",\"type\":\"bytes32\"}],\"name\":\"identifierToAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"votePower\",\"type\":\"uint64\"}],\"name\":\"increaseStake\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"indentifier\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"votePower\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"blsPubKey\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"vrfPubKey\",\"type\":\"bytes\"},{\"internalType\":\"bytes[2]\",\"name\":\"blsPubKeyProof\",\"type\":\"bytes[2]\"}],\"name\":\"register\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"votePower\",\"type\":\"uint64\"}],\"name\":\"retire\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]"
18+
_abi, err := abi.JSON(bytes.NewReader([]byte(abiStr)))
19+
assert.NoError(t, err)
20+
21+
var out [2]*big.Int
22+
err = _abi.UnpackIntoInterface(&out, "getVotes", data)
23+
assert.NoError(t, err)
24+
25+
assert.Equal(t, out[0].String(), "1")
26+
assert.Equal(t, out[1].String(), "0")
27+
}
Lines changed: 184 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,184 @@
1+
package internalcontract
2+
3+
import (
4+
"math/big"
5+
"sync"
6+
7+
sdk "github.com/Conflux-Chain/go-conflux-sdk"
8+
"github.com/Conflux-Chain/go-conflux-sdk/types"
9+
"github.com/Conflux-Chain/go-conflux-sdk/types/cfxaddress"
10+
"github.com/ethereum/go-ethereum/common"
11+
"github.com/pkg/errors"
12+
)
13+
14+
// CrossSpaceCall contract
15+
type CrossSpaceCall struct {
16+
sdk.Contract
17+
}
18+
19+
var crossSpaceCallMap sync.Map
20+
var crossSpaceCallMu sync.Mutex
21+
22+
// NewCrossSpaceCall gets the CrossSpaceCall contract object
23+
func NewCrossSpaceCall(client sdk.ClientOperator) (s CrossSpaceCall, err error) {
24+
netId, err := client.GetNetworkID()
25+
if err != nil {
26+
return CrossSpaceCall{}, err
27+
}
28+
val, ok := crossSpaceCallMap.Load(netId)
29+
if !ok {
30+
crossSpaceCallMu.Lock()
31+
defer crossSpaceCallMu.Unlock()
32+
abi := getCrossSpaceCallAbi()
33+
address, e := getCrossSpaceCallAddress(client)
34+
if e != nil {
35+
return s, errors.Wrap(e, "failed to get CrossSpaceCall address")
36+
}
37+
contract, e := sdk.NewContract([]byte(abi), client, &address)
38+
if e != nil {
39+
return s, errors.Wrap(e, "failed to new CrossSpaceCall contract")
40+
}
41+
42+
val = CrossSpaceCall{Contract: *contract}
43+
crossSpaceCallMap.Store(netId, val)
44+
}
45+
return val.(CrossSpaceCall), nil
46+
}
47+
48+
func getCrossSpaceCallAbi() string {
49+
return "[{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes20\",\"name\":\"sender\",\"type\":\"bytes20\"},{\"indexed\":true,\"internalType\":\"bytes20\",\"name\":\"receiver\",\"type\":\"bytes20\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"Call\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes20\",\"name\":\"sender\",\"type\":\"bytes20\"},{\"indexed\":true,\"internalType\":\"bytes20\",\"name\":\"contract_address\",\"type\":\"bytes20\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"init\",\"type\":\"bytes\"}],\"name\":\"Create\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"}],\"name\":\"Outcome\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes20\",\"name\":\"sender\",\"type\":\"bytes20\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"}],\"name\":\"Withdraw\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"bytes20\",\"name\":\"to\",\"type\":\"bytes20\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"callEVM\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"output\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"init\",\"type\":\"bytes\"}],\"name\":\"createEVM\",\"outputs\":[{\"internalType\":\"bytes20\",\"name\":\"\",\"type\":\"bytes20\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"}],\"name\":\"mappedBalance\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"}],\"name\":\"mappedNonce\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes20\",\"name\":\"to\",\"type\":\"bytes20\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"staticCallEVM\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"output\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes20\",\"name\":\"to\",\"type\":\"bytes20\"}],\"name\":\"transferEVM\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"output\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"withdrawFromMapped\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]"
50+
}
51+
52+
func getCrossSpaceCallAddress(client sdk.ClientOperator) (types.Address, error) {
53+
addr := cfxaddress.MustNewFromHex("0888000000000000000000000000000000000006")
54+
err := addr.CompleteByClient(client)
55+
return addr, err
56+
}
57+
58+
// =================== calls ==================
59+
60+
func (ac *CrossSpaceCall) MappedBalance(opts *types.ContractMethodCallOption, addr types.Address) (*big.Int, error) {
61+
var tmp *big.Int = new(big.Int)
62+
err := ac.Call(opts, &tmp, "mappedBalance", addr.MustGetCommonAddress())
63+
if err != nil {
64+
return nil, err
65+
}
66+
return tmp, nil
67+
}
68+
69+
func (ac *CrossSpaceCall) MappedNonce(opts *types.ContractMethodCallOption, addr types.Address) (*big.Int, error) {
70+
var tmp *big.Int = new(big.Int)
71+
err := ac.Call(opts, &tmp, "mappedNonce", addr.MustGetCommonAddress())
72+
if err != nil {
73+
return nil, err
74+
}
75+
return tmp, nil
76+
}
77+
78+
func (ac *CrossSpaceCall) StaticCallEVM(opts *types.ContractMethodCallOption, to common.Address, data []byte) ([]byte, error) {
79+
var tmp []byte
80+
err := ac.Call(opts, &tmp, "staticCallEVM", to, data)
81+
if err != nil {
82+
return nil, err
83+
}
84+
return tmp, nil
85+
}
86+
87+
// =================== sends ==================
88+
89+
func (s *CrossSpaceCall) CallEVM(opts *types.ContractMethodSendOption, to common.Address, data []byte) (types.Hash, error) {
90+
return s.SendTransaction(opts, "callEVM", to, data)
91+
}
92+
93+
func (s *CrossSpaceCall) CreateEVM(opts *types.ContractMethodSendOption, init []byte) (types.Hash, error) {
94+
return s.SendTransaction(opts, "createEVM", init)
95+
}
96+
97+
func (s *CrossSpaceCall) TransferEVM(opts *types.ContractMethodSendOption, to common.Address) (types.Hash, error) {
98+
return s.SendTransaction(opts, "transferEVM", to)
99+
}
100+
101+
func (s *CrossSpaceCall) WithdrawFromMapped(opts *types.ContractMethodSendOption, value *big.Int) (types.Hash, error) {
102+
return s.SendTransaction(opts, "withdrawFromMapped", value)
103+
}
104+
105+
func (s *CrossSpaceCall) DeployEip1820(opts *types.ContractMethodSendOption) (types.Hash, error) {
106+
return s.SendTransaction(opts, "deployEip1820")
107+
}
108+
109+
// =================== events ==================
110+
111+
type CrossSpaceCallCall struct {
112+
Sender common.Address
113+
Receiver common.Address
114+
Value *big.Int
115+
Nonce *big.Int
116+
Data []byte
117+
Raw types.Log // Blockchain specific contextual infos
118+
}
119+
120+
func (s *CrossSpaceCall) ParseCall(log types.Log) (*CrossSpaceCallCall, error) {
121+
event := new(CrossSpaceCallCall)
122+
if err := s.DecodeEvent(event, "Call", log); err != nil {
123+
return nil, err
124+
}
125+
event.Raw = log
126+
return event, nil
127+
}
128+
129+
type CrossSpaceCallCreate struct {
130+
Sender [20]byte
131+
ContractAddress [20]byte
132+
Value *big.Int
133+
Nonce *big.Int
134+
Init []byte
135+
Raw types.Log // Blockchain specific contextual infos
136+
}
137+
138+
func (s *CrossSpaceCall) ParseCreate(log types.Log) (*CrossSpaceCallCreate, error) {
139+
event := new(CrossSpaceCallCreate)
140+
if err := s.DecodeEvent(event, "Create", log); err != nil {
141+
return nil, err
142+
}
143+
event.Raw = log
144+
return event, nil
145+
}
146+
147+
// CrossSpaceCallOutcome represents a Outcome event raised by the CrossSpaceCall contract.
148+
type CrossSpaceCallOutcome struct {
149+
Success bool
150+
Raw types.Log // Blockchain specific contextual infos
151+
}
152+
153+
// ParseOutcome is a log parse operation binding the contract event 0xbc11eabb6efd378a0a489b58a574c6e0d0403060e8a8c7b8eab45db47900edfe.
154+
//
155+
// Solidity: event Outcome(bool success)
156+
func (s *CrossSpaceCall) ParseOutcome(log types.Log) (*CrossSpaceCallOutcome, error) {
157+
event := new(CrossSpaceCallOutcome)
158+
if err := s.DecodeEvent(event, "Outcome", log); err != nil {
159+
return nil, err
160+
}
161+
event.Raw = log
162+
return event, nil
163+
}
164+
165+
// CrossSpaceCallWithdraw represents a Withdraw event raised by the CrossSpaceCall contract.
166+
type CrossSpaceCallWithdraw struct {
167+
Sender [20]byte
168+
Receiver common.Address
169+
Value *big.Int
170+
Nonce *big.Int
171+
Raw types.Log // Blockchain specific contextual infos
172+
}
173+
174+
// ParseWithdraw is a log parse operation binding the contract event 0x31328e08abcc622b23d8be96d45b371b10e42989dafc8ac56c85b33bb3584b92.
175+
//
176+
// Solidity: event Withdraw(bytes20 indexed sender, address indexed receiver, uint256 value, uint256 nonce)
177+
func (s *CrossSpaceCall) ParseWithdraw(log types.Log) (*CrossSpaceCallWithdraw, error) {
178+
event := new(CrossSpaceCallWithdraw)
179+
if err := s.DecodeEvent(event, "Withdraw", log); err != nil {
180+
return nil, err
181+
}
182+
event.Raw = log
183+
return event, nil
184+
}
Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
package internalcontract
2+
3+
import (
4+
"math/big"
5+
"sync"
6+
7+
sdk "github.com/Conflux-Chain/go-conflux-sdk"
8+
"github.com/Conflux-Chain/go-conflux-sdk/types"
9+
"github.com/Conflux-Chain/go-conflux-sdk/types/cfxaddress"
10+
"github.com/pkg/errors"
11+
)
12+
13+
// ParamsControl contract
14+
type ParamsControl struct {
15+
sdk.Contract
16+
}
17+
18+
type ParamsControlVote struct {
19+
TopicIndex uint16
20+
Votes [3]*big.Int
21+
}
22+
23+
var paramsControlMap sync.Map
24+
var paramsControlMu sync.Mutex
25+
26+
// NewParamsControl gets the ParamsControl contract object
27+
func NewParamsControl(client sdk.ClientOperator) (s ParamsControl, err error) {
28+
netId, err := client.GetNetworkID()
29+
if err != nil {
30+
return ParamsControl{}, err
31+
}
32+
val, ok := paramsControlMap.Load(netId)
33+
if !ok {
34+
paramsControlMu.Lock()
35+
defer paramsControlMu.Unlock()
36+
abi := getParamsControlAbi()
37+
address, e := getParamsControlAddress(client)
38+
if e != nil {
39+
return s, errors.Wrap(e, "failed to get ParamsControl address")
40+
}
41+
contract, e := sdk.NewContract([]byte(abi), client, &address)
42+
if e != nil {
43+
return s, errors.Wrap(e, "failed to new ParamsControl contract")
44+
}
45+
val = ParamsControl{Contract: *contract}
46+
paramsControlMap.Store(netId, val)
47+
}
48+
return val.(ParamsControl), nil
49+
}
50+
51+
func getParamsControlAbi() string {
52+
return "[{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"vote_round\",\"type\":\"uint64\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint16\",\"name\":\"topic_index\",\"type\":\"uint16\"},{\"indexed\":false,\"internalType\":\"uint256[3]\",\"name\":\"votes\",\"type\":\"uint256[3]\"}],\"name\":\"CastVote\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"vote_round\",\"type\":\"uint64\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint16\",\"name\":\"topic_index\",\"type\":\"uint16\"},{\"indexed\":false,\"internalType\":\"uint256[3]\",\"name\":\"votes\",\"type\":\"uint256[3]\"}],\"name\":\"RevokeVote\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"vote_round\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"uint16\",\"name\":\"topic_index\",\"type\":\"uint16\"},{\"internalType\":\"uint256[3]\",\"name\":\"votes\",\"type\":\"uint256[3]\"}],\"internalType\":\"structParamsControl.Vote[]\",\"name\":\"vote_data\",\"type\":\"tuple[]\"}],\"name\":\"castVote\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"}],\"name\":\"readVote\",\"outputs\":[{\"components\":[{\"internalType\":\"uint16\",\"name\":\"topic_index\",\"type\":\"uint16\"},{\"internalType\":\"uint256[3]\",\"name\":\"votes\",\"type\":\"uint256[3]\"}],\"internalType\":\"structParamsControl.Vote[]\",\"name\":\"\",\"type\":\"tuple[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"vote_round\",\"type\":\"uint64\"}],\"name\":\"totalVotes\",\"outputs\":[{\"components\":[{\"internalType\":\"uint16\",\"name\":\"topic_index\",\"type\":\"uint16\"},{\"internalType\":\"uint256[3]\",\"name\":\"votes\",\"type\":\"uint256[3]\"}],\"internalType\":\"structParamsControl.Vote[]\",\"name\":\"\",\"type\":\"tuple[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"voteRound\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]"
53+
}
54+
55+
func getParamsControlAddress(client sdk.ClientOperator) (types.Address, error) {
56+
addr := cfxaddress.MustNewFromHex("0888000000000000000000000000000000000007")
57+
err := addr.CompleteByClient(client)
58+
return addr, err
59+
}
60+
61+
// =================== calls ==================
62+
63+
func (p *ParamsControl) ReadVote(opts *types.ContractMethodCallOption, addr types.Address) ([]ParamsControlVote, error) {
64+
out := []ParamsControlVote{}
65+
err := p.Call(opts, &out, "readVote", addr.MustGetCommonAddress())
66+
if err != nil {
67+
return nil, err
68+
}
69+
return out, nil
70+
}
71+
72+
func (p *ParamsControl) TotalVotes(opts *types.ContractMethodCallOption, vote_round uint64) ([]ParamsControlVote, error) {
73+
out := []ParamsControlVote{}
74+
err := p.Call(opts, &out, "totalVotes", vote_round)
75+
if err != nil {
76+
return nil, err
77+
}
78+
return out, nil
79+
}
80+
81+
func (p *ParamsControl) CurrentRound(opts *types.ContractMethodCallOption) (uint64, error) {
82+
var out uint64
83+
err := p.Call(opts, &out, "currentRound")
84+
if err != nil {
85+
return 0, err
86+
}
87+
return out, nil
88+
}
89+
90+
func (p *ParamsControl) PosStakeForVotes(opts *types.ContractMethodCallOption, arg0 uint64) (*big.Int, error) {
91+
var out = new(big.Int)
92+
err := p.Call(opts, &out, "posStakeForVotes")
93+
if err != nil {
94+
return nil, err
95+
}
96+
return out, nil
97+
}
98+
99+
// =================== sends ==================
100+
101+
func (p *ParamsControl) CastVote(opts *types.ContractMethodSendOption, vote_round uint64, vote_data []ParamsControlVote) (types.Hash, error) {
102+
return p.SendTransaction(opts, "castVote", vote_round, vote_data)
103+
}

0 commit comments

Comments
 (0)