From 3e634b48a148b871293153f729f7d2204686ff56 Mon Sep 17 00:00:00 2001 From: Darren Kelly Date: Sat, 2 Nov 2024 19:48:21 +0000 Subject: [PATCH] feat(builtins): add typed contracts; refactor(thorgen): separate txs and read-only --- .gitignore | 1 + README.md | 157 ++--- accounts/accounts.go | 6 +- accounts/accounts_test.go | 22 +- accounts/contract.go | 60 +- accounts/contract_test.go | 46 +- accounts/deployer_test.go | 4 +- blocks/blocks.go | 1 - builtins/authority.go | 420 +++++++++++ builtins/authority_test.go | 20 + builtins/contract.go | 74 -- builtins/energy.go | 726 +++++++++++++++++++ builtins/energy_test.go | 19 + builtins/executor.go | 896 ++++++++++++++++++++++++ builtins/extension.go | 726 +++++++++++++++++++ builtins/params.go | 333 +++++++++ builtins/prototype.go | 518 ++++++++++++++ client/accounts_test.go | 7 +- client/blocks_test.go | 9 +- client/client.go | 51 +- client/revision.go | 31 + client/transactions_test.go | 5 +- cmd/thorgen/{bind => }/bind.go | 2 +- cmd/thorgen/main.go | 7 +- cmd/thorgen/{bind => }/source.go.tpl | 186 ++--- cmd/thorgen/{bind => }/template.go | 2 +- internal/testcontainer/testcontainer.go | 8 +- thorgo.go | 12 +- thorgo_test.go | 9 +- transactions/transactor.go | 5 +- txmanager/delegator_test.go | 4 +- 31 files changed, 4010 insertions(+), 357 deletions(-) create mode 100644 builtins/authority.go create mode 100644 builtins/authority_test.go delete mode 100644 builtins/contract.go create mode 100644 builtins/energy.go create mode 100644 builtins/energy_test.go create mode 100644 builtins/executor.go create mode 100644 builtins/extension.go create mode 100644 builtins/params.go create mode 100644 builtins/prototype.go create mode 100644 client/revision.go rename cmd/thorgen/{bind => }/bind.go (99%) rename cmd/thorgen/{bind => }/source.go.tpl (70%) rename cmd/thorgen/{bind => }/template.go (99%) diff --git a/.gitignore b/.gitignore index c2bd8ac..580a367 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ vendor .idea coverage.out +cmd/test diff --git a/README.md b/README.md index 0c7ef9c..a447b97 100644 --- a/README.md +++ b/README.md @@ -101,25 +101,28 @@ type Signer interface { package main import ( - "fmt" - - "github.com/darrenvechain/thorgo" - "github.com/darrenvechain/thorgo/solo" - "github.com/ethereum/go-ethereum/common" + "fmt" + + "github.com/darrenvechain/thorgo" + "github.com/darrenvechain/thorgo/solo" + "github.com/ethereum/go-ethereum/common" ) func main() { - // Create a new client - thor, err := thorgo.NewFromURL(solo.URL) - - // Get an accounts balance - acc, err := thor.Account(common.HexToAddress("0x0000000000000000000000000000456e6570")).Get() - fmt.Println(acc.Balance) + // Create a new client + thor := thorgo.New(solo.URL) + + // Get an accounts balance + acc, err := thor.Account(common.HexToAddress("0x0000000000000000000000000000456e6570")).Get() + fmt.Println(acc.Balance) } ``` ### 2: Interacting with a contract + Delegated Transaction +- It is recommended to create your smart contract wrapper using the `thorgen` CLI. This provides a more idiomatic way to + interact with the contract. +
Expand @@ -127,45 +130,44 @@ func main() { package main import ( - "log/slog" - "math/big" - - "github.com/darrenvechain/thorgo" - "github.com/darrenvechain/thorgo/builtins" - "github.com/darrenvechain/thorgo/solo" - "github.com/darrenvechain/thorgo/txmanager" - "github.com/ethereum/go-ethereum/common" + "log/slog" + "math/big" + + "github.com/darrenvechain/thorgo" + "github.com/darrenvechain/thorgo/builtins" + "github.com/darrenvechain/thorgo/solo" + "github.com/darrenvechain/thorgo/txmanager" ) func main() { - thor, _ := thorgo.NewFromURL("http://localhost:8669") - - // Load a contract - vtho := thor.Account(common.HexToAddress("0x0000000000000000000000000000456e65726779")).Contract(builtins.VTHO.ABI) - - // Create a delegated transaction manager - origin := txmanager.FromPK(solo.Keys()[0], thor) - gasPayer := txmanager.NewDelegator(solo.Keys()[1]) - txSender := txmanager.NewDelegatedManager(thor, origin, gasPayer) - - // Create a new account to receive the tokens - recipient, _ := txmanager.GeneratePK(thor) - recipientBalance := new(big.Int) - - // Call the balanceOf function - err := vtho.Call("balanceOf", &recipientBalance, recipient.Address()) - slog.Info("recipient balance before", "balance", recipientBalance, "error", err) - - // Send 1000 tokens to the recipient - tx, _ := vtho.Send(txSender, "transfer", recipient.Address(), big.NewInt(1000)) - receipt, _ := tx.Wait() - slog.Info("receipt", "txID", receipt.Meta.TxID, "reverted", receipt.Reverted) - - // Call the balanceOf function again - err = vtho.Call("balanceOf", &recipientBalance, recipient.Address()) - slog.Info("recipient balance after", "balance", recipientBalance, "error", err) + thor := thorgo.New("http://localhost:8669") + + // Create a delegated transaction manager + origin := txmanager.FromPK(solo.Keys()[0], thor) + gasPayer := txmanager.NewDelegator(solo.Keys()[1]) + txSender := txmanager.NewDelegatedManager(thor, origin, gasPayer) + + // Use the `thorgen` CLI to build your own smart contract wrapper + vtho, _ := builtins.NewEnergyTransactor(thor, txSender) + + // Create a new account to receive the tokens + recipient, _ := txmanager.GeneratePK(thor) + + // Call the balanceOf function + balance, err := vtho.BalanceOf(recipient.Address()) + slog.Info("recipient balance before", "balance", balance, "error", err) + + tx, err := vtho.Transfer(recipient.Address(), big.NewInt(1000000000000000000)) + if err != nil { + slog.Error("transfer error", "error", err) + return + } + receipt, err := tx.Wait() + slog.Info("transfer receipt", "error", err != nil || receipt.Reverted) + + balance, err = vtho.BalanceOf(recipient.Address()) + slog.Info("recipient balance after", "balance", balance, "error", err) } - ```
@@ -179,41 +181,40 @@ func main() { package main import ( - "log/slog" - "math/big" - - "github.com/darrenvechain/thorgo" - "github.com/darrenvechain/thorgo/builtins" - "github.com/darrenvechain/thorgo/crypto/tx" - "github.com/darrenvechain/thorgo/solo" - "github.com/darrenvechain/thorgo/txmanager" - "github.com/ethereum/go-ethereum/common" + "log/slog" + "math/big" + + "github.com/darrenvechain/thorgo" + "github.com/darrenvechain/thorgo/builtins" + "github.com/darrenvechain/thorgo/crypto/tx" + "github.com/darrenvechain/thorgo/solo" + "github.com/darrenvechain/thorgo/txmanager" ) func main() { - thor, _ := thorgo.NewFromURL("http://localhost:8669") - - // Load a contract - vtho := thor.Account(common.HexToAddress("0x0000000000000000000000000000456e65726779")).Contract(builtins.VTHO.ABI) - - origin := txmanager.FromPK(solo.Keys()[0], thor) - - // clause1 - clause1, _ := vtho.AsClause("transfer", common.HexToAddress("0x87AA2B76f29583E4A9095DBb6029A9C41994E25B"), big.NewInt(1000000)) - clause2, _ := vtho.AsClause("transfer", common.HexToAddress("0xdf1b32ec78c1f338F584a2a459f01fD70529dDBF"), big.NewInt(1000000)) - - // Option 1 - Directly using the txmanager.Manager - trx, _ := origin.SendClauses([]*tx.Clause{clause1, clause2}) - receipt, _ := thor.Transaction(trx).Wait() - slog.Info("transaction receipt 1", "id", receipt.Meta.TxID, "reverted", receipt.Reverted) - - // Option 2 - Using the transaction builder with txmanager.Signer - tx2, _ := thor.Transactor([]*tx.Clause{clause1, clause2}). - GasPriceCoef(255). - Send(origin) - receipt2, _ := tx2.Wait() - slog.Info("transaction receipt 2", "id", receipt2.Meta.TxID, "reverted", receipt2.Reverted) + thor := thorgo.New("http://localhost:8669") + + // Create a delegated transaction manager + origin := txmanager.FromPK(solo.Keys()[0], thor) + recipient1, _ := txmanager.GeneratePK(thor) + recipient2, _ := txmanager.GeneratePK(thor) + + vtho, _ := builtins.NewEnergyTransactor(thor, origin) + + clause1, _ := vtho.TransferAsClause(recipient1.Address(), big.NewInt(1000)) + clause2, _ := vtho.TransferAsClause(recipient2.Address(), big.NewInt(9999)) + + txID, _ := origin.SendClauses([]*tx.Clause{clause1, clause2}) + slog.Info("transaction sent", "id", txID) + trx, _ := thor.Transaction(txID).Wait() + slog.Info("transaction mined", "reverted", trx.Reverted) + + balance1, _ := vtho.BalanceOf(recipient1.Address()) + balance2, _ := vtho.BalanceOf(recipient2.Address()) + + slog.Info("recipient1", "balance", balance1) + slog.Info("recipient2", "balance", balance2) } -``` +``` diff --git a/accounts/accounts.go b/accounts/accounts.go index 40625fd..ef01b35 100644 --- a/accounts/accounts.go +++ b/accounts/accounts.go @@ -12,7 +12,7 @@ import ( type Visitor struct { client *client.Client account common.Address - revision *common.Hash + revision *client.Revision } func New(c *client.Client, account common.Address) *Visitor { @@ -20,7 +20,7 @@ func New(c *client.Client, account common.Address) *Visitor { } // Revision sets the optional revision for the API calls. -func (a *Visitor) Revision(revision common.Hash) *Visitor { +func (a *Visitor) Revision(revision client.Revision) *Visitor { a.revision = &revision return a } @@ -78,5 +78,5 @@ func (a *Visitor) Call(calldata []byte) (*client.InspectResponse, error) { // Contract returns a new Contract instance. func (a *Visitor) Contract(abi *abi.ABI) *Contract { - return NewContractAt(a.client, a.account, abi, a.revision) + return NewContract(a.client, a.account, abi) } diff --git a/accounts/accounts_test.go b/accounts/accounts_test.go index f16d985..8c2d4c2 100644 --- a/accounts/accounts_test.go +++ b/accounts/accounts_test.go @@ -17,8 +17,8 @@ import ( var ( thorClient *client.Client thor *thorgo.Thor - vthoContract *accounts.Contract - vtho = builtins.VTHO + vthoContract *builtins.Energy + vthoRaw *accounts.Contract account1 *txmanager.PKManager ) @@ -27,7 +27,9 @@ func TestMain(m *testing.M) { thorClient, cancel = testcontainer.NewSolo() defer cancel() thor = thorgo.NewFromClient(thorClient) - vthoContract = vtho.Load(thor) + vthoContract, _ = builtins.NewEnergy(thor) + abi, _ := builtins.EnergyMetaData.GetAbi() + vthoRaw = accounts.NewContract(thorClient, vthoContract.Address(), abi) account1 = txmanager.FromPK(solo.Keys()[0], thor) m.Run() } @@ -47,7 +49,7 @@ func TestGetAccount(t *testing.T) { // TestGetAccountForRevision fetches a thor solo account for the genesis block // and checks if the balance and energy are greater than 0 func TestGetAccountForRevision(t *testing.T) { - acc, err := accounts.New(thorClient, account1.Address()).Revision(solo.GenesisID()).Get() + acc, err := accounts.New(thorClient, account1.Address()).Revision(client.RevisionID(solo.GenesisID())).Get() assert.NoError(t, err, "Account.httpGet should not return an error") assert.NotNil(t, acc, "Account.httpGet should return an account") @@ -59,7 +61,7 @@ func TestGetAccountForRevision(t *testing.T) { // TestGetCode fetches the code of the VTHO contract and checks if the code length is greater than 2 (0x) func TestGetCode(t *testing.T) { - vtho, err := accounts.New(thorClient, vtho.Address).Code() + vtho, err := accounts.New(thorClient, vthoContract.Address()).Code() assert.NoError(t, err, "Account.Code should not return an error") assert.NotNil(t, vtho, "Account.Code should return a code") @@ -68,7 +70,9 @@ func TestGetCode(t *testing.T) { // TestGetCodeForRevision fetches the code of the VTHO contract for the genesis block func TestGetCodeForRevision(t *testing.T) { - vtho, err := accounts.New(thorClient, vtho.Address).Revision(solo.GenesisID()).Code() + vtho, err := accounts.New(thorClient, vthoContract.Address()). + Revision(client.RevisionID(solo.GenesisID())). + Code() assert.NoError(t, err, "Account.Code should not return an error") assert.NotNil(t, vtho, "Account.Code should return a code") @@ -77,7 +81,7 @@ func TestGetCodeForRevision(t *testing.T) { // TestGetStorage fetches a storage position of the VTHO contract and checks if the value is empty func TestGetStorage(t *testing.T) { - storage, err := accounts.New(thorClient, vtho.Address).Storage(common.Hash{}) + storage, err := accounts.New(thorClient, vthoContract.Address()).Storage(common.Hash{}) assert.NoError(t, err, "Account.Storage should not return an error") assert.NotNil(t, storage, "Account.Storage should return a storage") @@ -86,7 +90,9 @@ func TestGetStorage(t *testing.T) { // TestGetStorageForRevision fetches a storage position of the VTHO contract for the genesis block func TestGetStorageForRevision(t *testing.T) { - storage, err := accounts.New(thorClient, vtho.Address).Revision(solo.GenesisID()).Storage(common.Hash{}) + storage, err := accounts.New(thorClient, vthoContract.Address()). + Revision(client.RevisionID(solo.GenesisID())). + Storage(common.Hash{}) assert.NoError(t, err, "Account.Storage should not return an error") assert.NotNil(t, storage, "Account.Storage should return a storage") diff --git a/accounts/contract.go b/accounts/contract.go index c2d64b5..281cdbf 100644 --- a/accounts/contract.go +++ b/accounts/contract.go @@ -16,10 +16,9 @@ import ( // Contract is a generic representation of a smart contract. type Contract struct { - client *client.Client - revision *common.Hash - ABI *abi.ABI - Address common.Address + client *client.Client + ABI *abi.ABI + Address common.Address } // NewContract creates a new contract instance. @@ -28,21 +27,19 @@ func NewContract( address common.Address, abi *abi.ABI, ) *Contract { - return &Contract{client: client, Address: address, ABI: abi, revision: nil} + return &Contract{client: client, Address: address, ABI: abi} } -// NewContractAt creates a new contract instance at a specific revision. It should be used to query historical contract states. -func NewContractAt( - client *client.Client, - address common.Address, - abi *abi.ABI, - revision *common.Hash, -) *Contract { - return &Contract{client: client, Address: address, ABI: abi, revision: revision} +// Call executes a read-only contract call. +func (c *Contract) Call(method string, results *[]interface{}, args ...interface{}) error { + return c.CallAt(client.RevisionBest(), method, results, args...) } -// Call executes a read-only contract call. -func (c *Contract) Call(method string, value interface{}, args ...interface{}) error { +// CallAt executes a read-only contract call at a specific revision. +func (c *Contract) CallAt(revision client.Revision, method string, results *[]interface{}, args ...interface{}) error { + if results == nil { + results = new([]interface{}) + } packed, err := c.ABI.Pack(method, args...) if err != nil { return fmt.Errorf("failed to pack method %s: %w", method, err) @@ -51,12 +48,7 @@ func (c *Contract) Call(method string, value interface{}, args ...interface{}) e request := client.InspectRequest{ Clauses: []*tx.Clause{clause}, } - var response []client.InspectResponse - if c.revision == nil { - response, err = c.client.Inspect(request) - } else { - response, err = c.client.InspectAt(request, *c.revision) - } + response, err := c.client.InspectAt(request, revision) if err != nil { return fmt.Errorf("failed to inspect contract: %w", err) } @@ -71,11 +63,13 @@ func (c *Contract) Call(method string, value interface{}, args ...interface{}) e if err != nil { return fmt.Errorf("failed to decode data: %w", err) } - err = c.ABI.UnpackIntoInterface(value, method, decoded) - if err != nil { - return fmt.Errorf("failed to unpack method %s: %w", method, err) + if len(*results) == 0 { + res, err := c.ABI.Unpack(method, decoded) + *results = res + return err } - return nil + res := *results + return c.ABI.UnpackIntoInterface(res[0], method, decoded) } // DecodeCall decodes the result of a contract call, for example, decoding a clause's 'data'. @@ -111,13 +105,27 @@ func (c *Contract) AsClause(method string, args ...interface{}) (*tx.Clause, err return tx.NewClause(&c.Address).WithData(packed).WithValue(big.NewInt(0)), nil } +// AsClauseWithVET returns a transaction clause for the given method, value, and arguments. +func (c *Contract) AsClauseWithVET(vet *big.Int, method string, args ...interface{}) (*tx.Clause, error) { + packed, err := c.ABI.Pack(method, args...) + if err != nil { + return nil, fmt.Errorf("failed to pack method %s: %w", method, err) + } + return tx.NewClause(&c.Address).WithData(packed).WithValue(vet), nil +} + type TxManager interface { SendClauses(clauses []*tx.Clause) (common.Hash, error) } // Send executes a transaction with a single clause. func (c *Contract) Send(manager TxManager, method string, args ...interface{}) (*transactions.Visitor, error) { - clause, err := c.AsClause(method, args...) + return c.SendWithVET(manager, big.NewInt(0), method, args...) +} + +// SendWithVET executes a transaction with a single clause and a value. +func (c *Contract) SendWithVET(manager TxManager, vet *big.Int, method string, args ...interface{}) (*transactions.Visitor, error) { + clause, err := c.AsClauseWithVET(vet, method, args...) if err != nil { return &transactions.Visitor{}, fmt.Errorf("failed to pack method %s: %w", method, err) } diff --git a/accounts/contract_test.go b/accounts/contract_test.go index 2907682..183c795 100644 --- a/accounts/contract_test.go +++ b/accounts/contract_test.go @@ -13,30 +13,30 @@ import ( func TestContract_Call(t *testing.T) { // name - var name string - err := vthoContract.Call("name", &name) + var name []interface{} + err := vthoRaw.Call("name", &name) assert.NoError(t, err) - assert.Equal(t, "VeThor", name) + assert.Equal(t, "VeThor", name[0]) // symbol - var symbol string - err = vthoContract.Call("symbol", &symbol) + var symbol []interface{} + err = vthoRaw.Call("symbol", &symbol) assert.NoError(t, err) - assert.Equal(t, "VTHO", symbol) + assert.Equal(t, "VTHO", symbol[0]) // decimals - var decimals uint8 - err = vthoContract.Call("decimals", &decimals) + var decimals []interface{} + err = vthoRaw.Call("decimals", &decimals) assert.NoError(t, err) - assert.Equal(t, uint8(18), decimals) + assert.Equal(t, uint8(18), decimals[0]) } func TestContract_DecodeCall(t *testing.T) { - packed, err := vtho.ABI.Pack("balanceOf", account1.Address()) + packed, err := vthoRaw.ABI.Pack("balanceOf", account1.Address()) assert.NoError(t, err) balance := new(big.Int) - err = vthoContract.DecodeCall(packed, &balance) + err = vthoRaw.DecodeCall(packed, &balance) assert.NoError(t, err) assert.Greater(t, balance.Uint64(), uint64(0)) } @@ -46,17 +46,17 @@ func TestContract_AsClause(t *testing.T) { assert.NoError(t, err) // transfer clause - clause, err := vthoContract.AsClause("transfer", receiver.Address(), big.NewInt(1000)) + clause, err := vthoRaw.AsClause("transfer", receiver.Address(), big.NewInt(1000)) assert.NoError(t, err) assert.Equal(t, clause.Value(), big.NewInt(0)) - assert.Equal(t, clause.To().Hex(), vtho.Address.Hex()) + assert.Equal(t, clause.To().Hex(), vthoContract.Address().Hex()) } func TestContract_Send(t *testing.T) { receiver, err := txmanager.GeneratePK(thor) assert.NoError(t, err) - tx, err := vthoContract.Send(account1, "transfer", receiver.Address(), big.NewInt(1000)) + tx, err := vthoRaw.Send(account1, "transfer", receiver.Address(), big.NewInt(1000)) assert.NoError(t, err) receipt, err := tx.Wait() @@ -68,14 +68,14 @@ func TestContract_EventCriteria(t *testing.T) { receiver, err := txmanager.GeneratePK(thor) assert.NoError(t, err) - tx, err := vthoContract.Send(account1, "transfer", receiver.Address(), big.NewInt(1000)) + tx, err := vthoRaw.Send(account1, "transfer", receiver.Address(), big.NewInt(1000)) assert.NoError(t, err) receipt, _ := tx.Wait() assert.False(t, receipt.Reverted) // event criteria - match the newly created receiver - criteria, err := vthoContract.EventCriteria("Transfer", nil, receiver.Address()) + criteria, err := vthoRaw.EventCriteria("Transfer", nil, receiver.Address()) assert.NoError(t, err) // fetch events @@ -83,15 +83,15 @@ func TestContract_EventCriteria(t *testing.T) { assert.NoError(t, err) // decode events - decodedEvs, err := vthoContract.DecodeEvents(transfers) + decodedEvs, err := vthoRaw.DecodeEvents(transfers) assert.NoError(t, err) ev := decodedEvs[0] assert.Equal(t, "Transfer", ev.Name) - assert.NotNil(t, ev.Args["from"]) - assert.NotNil(t, ev.Args["to"]) - assert.NotNil(t, ev.Args["value"]) - assert.IsType(t, common.Address{}, ev.Args["from"]) - assert.IsType(t, common.Address{}, ev.Args["to"]) - assert.IsType(t, &big.Int{}, ev.Args["value"]) + assert.NotNil(t, ev.Args["_from"]) + assert.NotNil(t, ev.Args["_to"]) + assert.NotNil(t, ev.Args["_value"]) + assert.IsType(t, common.Address{}, ev.Args["_from"]) + assert.IsType(t, common.Address{}, ev.Args["_to"]) + assert.IsType(t, &big.Int{}, ev.Args["_value"]) } diff --git a/accounts/deployer_test.go b/accounts/deployer_test.go index bc4d4ad..3634825 100644 --- a/accounts/deployer_test.go +++ b/accounts/deployer_test.go @@ -20,10 +20,10 @@ func TestDeployer_Deploy(t *testing.T) { assert.NoError(t, err) assert.NotEqual(t, common.Hash{}, txID) - var name string + var name []interface{} err = erc20.Call("name", &name) assert.NoError(t, err) - assert.Equal(t, deployedName, name) + assert.Equal(t, deployedName, name[0]) } var erc20Bytecode = "60806040523480156200001157600080fd5b50604051620014c9380380620014c98339818101604052810190620000379190620001fa565b818181600390816200004a9190620004ca565b5080600490816200005c9190620004ca565b5050505050620005b1565b6000604051905090565b600080fd5b600080fd5b600080fd5b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b620000d08262000085565b810181811067ffffffffffffffff82111715620000f257620000f162000096565b5b80604052505050565b60006200010762000067565b9050620001158282620000c5565b919050565b600067ffffffffffffffff82111562000138576200013762000096565b5b620001438262000085565b9050602081019050919050565b60005b838110156200017057808201518184015260208101905062000153565b60008484015250505050565b6000620001936200018d846200011a565b620000fb565b905082815260208101848484011115620001b257620001b162000080565b5b620001bf84828562000150565b509392505050565b600082601f830112620001df57620001de6200007b565b5b8151620001f18482602086016200017c565b91505092915050565b6000806040838503121562000214576200021362000071565b5b600083015167ffffffffffffffff81111562000235576200023462000076565b5b6200024385828601620001c7565b925050602083015167ffffffffffffffff81111562000267576200026662000076565b5b6200027585828601620001c7565b9150509250929050565b600081519050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b60006002820490506001821680620002d257607f821691505b602082108103620002e857620002e76200028a565b5b50919050565b60008190508160005260206000209050919050565b60006020601f8301049050919050565b600082821b905092915050565b600060088302620003527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8262000313565b6200035e868362000313565b95508019841693508086168417925050509392505050565b6000819050919050565b6000819050919050565b6000620003ab620003a56200039f8462000376565b62000380565b62000376565b9050919050565b6000819050919050565b620003c7836200038a565b620003df620003d682620003b2565b84845462000320565b825550505050565b600090565b620003f6620003e7565b62000403818484620003bc565b505050565b5b818110156200042b576200041f600082620003ec565b60018101905062000409565b5050565b601f8211156200047a576200044481620002ee565b6200044f8462000303565b810160208510156200045f578190505b620004776200046e8562000303565b83018262000408565b50505b505050565b600082821c905092915050565b60006200049f600019846008026200047f565b1980831691505092915050565b6000620004ba83836200048c565b9150826002028217905092915050565b620004d5826200027f565b67ffffffffffffffff811115620004f157620004f062000096565b5b620004fd8254620002b9565b6200050a8282856200042f565b600060209050601f8311600181146200054257600084156200052d578287015190505b620005398582620004ac565b865550620005a9565b601f1984166200055286620002ee565b60005b828110156200057c5784890151825560018201915060208501945060208101905062000555565b868310156200059c578489015162000598601f8916826200048c565b8355505b6001600288020188555050505b505050505050565b610f0880620005c16000396000f3fe608060405234801561001057600080fd5b506004361061009e5760003560e01c806340c10f191161006657806340c10f191461015d57806370a082311461017957806395d89b41146101a9578063a9059cbb146101c7578063dd62ed3e146101f75761009e565b806306fdde03146100a3578063095ea7b3146100c157806318160ddd146100f157806323b872dd1461010f578063313ce5671461013f575b600080fd5b6100ab610227565b6040516100b89190610b5c565b60405180910390f35b6100db60048036038101906100d69190610c17565b6102b9565b6040516100e89190610c72565b60405180910390f35b6100f96102dc565b6040516101069190610c9c565b60405180910390f35b61012960048036038101906101249190610cb7565b6102e6565b6040516101369190610c72565b60405180910390f35b610147610315565b6040516101549190610d26565b60405180910390f35b61017760048036038101906101729190610c17565b61031a565b005b610193600480360381019061018e9190610d41565b610328565b6040516101a09190610c9c565b60405180910390f35b6101b1610370565b6040516101be9190610b5c565b60405180910390f35b6101e160048036038101906101dc9190610c17565b610402565b6040516101ee9190610c72565b60405180910390f35b610211600480360381019061020c9190610d6e565b610425565b60405161021e9190610c9c565b60405180910390f35b60606003805461023690610ddd565b80601f016020809104026020016040519081016040528092919081815260200182805461026290610ddd565b80156102af5780601f10610284576101008083540402835291602001916102af565b820191906000526020600020905b81548152906001019060200180831161029257829003601f168201915b5050505050905090565b6000806102c46104ac565b90506102d18185856104b4565b600191505092915050565b6000600254905090565b6000806102f16104ac565b90506102fe8582856104c6565b61030985858561055a565b60019150509392505050565b600090565b610324828261064e565b5050565b60008060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b60606004805461037f90610ddd565b80601f01602080910402602001604051908101604052809291908181526020018280546103ab90610ddd565b80156103f85780601f106103cd576101008083540402835291602001916103f8565b820191906000526020600020905b8154815290600101906020018083116103db57829003601f168201915b5050505050905090565b60008061040d6104ac565b905061041a81858561055a565b600191505092915050565b6000600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905092915050565b600033905090565b6104c183838360016106d0565b505050565b60006104d28484610425565b90507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81146105545781811015610544578281836040517ffb8f41b200000000000000000000000000000000000000000000000000000000815260040161053b93929190610e1d565b60405180910390fd5b610553848484840360006106d0565b5b50505050565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16036105cc5760006040517f96c6fd1e0000000000000000000000000000000000000000000000000000000081526004016105c39190610e54565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff160361063e5760006040517fec442f050000000000000000000000000000000000000000000000000000000081526004016106359190610e54565b60405180910390fd5b6106498383836108a7565b505050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16036106c05760006040517fec442f050000000000000000000000000000000000000000000000000000000081526004016106b79190610e54565b60405180910390fd5b6106cc600083836108a7565b5050565b600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff16036107425760006040517fe602df050000000000000000000000000000000000000000000000000000000081526004016107399190610e54565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16036107b45760006040517f94280d620000000000000000000000000000000000000000000000000000000081526004016107ab9190610e54565b60405180910390fd5b81600160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555080156108a1578273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925846040516108989190610c9c565b60405180910390a35b50505050565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16036108f95780600260008282546108ed9190610e9e565b925050819055506109cc565b60008060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905081811015610985578381836040517fe450d38c00000000000000000000000000000000000000000000000000000000815260040161097c93929190610e1d565b60405180910390fd5b8181036000808673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550505b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603610a155780600260008282540392505081905550610a62565b806000808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825401925050819055505b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef83604051610abf9190610c9c565b60405180910390a3505050565b600081519050919050565b600082825260208201905092915050565b60005b83811015610b06578082015181840152602081019050610aeb565b60008484015250505050565b6000601f19601f8301169050919050565b6000610b2e82610acc565b610b388185610ad7565b9350610b48818560208601610ae8565b610b5181610b12565b840191505092915050565b60006020820190508181036000830152610b768184610b23565b905092915050565b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000610bae82610b83565b9050919050565b610bbe81610ba3565b8114610bc957600080fd5b50565b600081359050610bdb81610bb5565b92915050565b6000819050919050565b610bf481610be1565b8114610bff57600080fd5b50565b600081359050610c1181610beb565b92915050565b60008060408385031215610c2e57610c2d610b7e565b5b6000610c3c85828601610bcc565b9250506020610c4d85828601610c02565b9150509250929050565b60008115159050919050565b610c6c81610c57565b82525050565b6000602082019050610c876000830184610c63565b92915050565b610c9681610be1565b82525050565b6000602082019050610cb16000830184610c8d565b92915050565b600080600060608486031215610cd057610ccf610b7e565b5b6000610cde86828701610bcc565b9350506020610cef86828701610bcc565b9250506040610d0086828701610c02565b9150509250925092565b600060ff82169050919050565b610d2081610d0a565b82525050565b6000602082019050610d3b6000830184610d17565b92915050565b600060208284031215610d5757610d56610b7e565b5b6000610d6584828501610bcc565b91505092915050565b60008060408385031215610d8557610d84610b7e565b5b6000610d9385828601610bcc565b9250506020610da485828601610bcc565b9150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b60006002820490506001821680610df557607f821691505b602082108103610e0857610e07610dae565b5b50919050565b610e1781610ba3565b82525050565b6000606082019050610e326000830186610e0e565b610e3f6020830185610c8d565b610e4c6040830184610c8d565b949350505050565b6000602082019050610e696000830184610e0e565b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000610ea982610be1565b9150610eb483610be1565b9250828201905080821115610ecc57610ecb610e6f565b5b9291505056fea2646970667358221220e38c2ea7a55d79f2695d7b57320f013a28b9dc41e8b492ba111ddb3eeefc626064736f6c63430008140033" diff --git a/blocks/blocks.go b/blocks/blocks.go index e8b919a..47a6fdb 100644 --- a/blocks/blocks.go +++ b/blocks/blocks.go @@ -75,7 +75,6 @@ func (b *Blocks) poll() { time.Sleep(1 * time.Second) continue } - } } diff --git a/builtins/authority.go b/builtins/authority.go new file mode 100644 index 0000000..ffe9e88 --- /dev/null +++ b/builtins/authority.go @@ -0,0 +1,420 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package builtins + +import ( + "context" + "errors" + "math/big" + "strings" + + "github.com/darrenvechain/thorgo" + "github.com/darrenvechain/thorgo/accounts" + "github.com/darrenvechain/thorgo/client" + "github.com/darrenvechain/thorgo/crypto/tx" + "github.com/darrenvechain/thorgo/transactions" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/hexutil" +) + +// Reference imports to suppress errors if they are not otherwise used. +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = bind.Bind + _ = common.Big1 + _ = abi.ConvertType + _ = hexutil.MustDecode + _ = context.Background + _ = tx.NewClause +) + +// AuthorityMetaData contains all meta data concerning the Authority contract. +var AuthorityMetaData = &bind.MetaData{ + ABI: "[{\"constant\":true,\"inputs\":[],\"name\":\"first\",\"outputs\":[{\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_nodeMaster\",\"type\":\"address\"}],\"name\":\"revoke\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"_nodeMaster\",\"type\":\"address\"}],\"name\":\"next\",\"outputs\":[{\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"_nodeMaster\",\"type\":\"address\"}],\"name\":\"get\",\"outputs\":[{\"name\":\"listed\",\"type\":\"bool\"},{\"name\":\"endorsor\",\"type\":\"address\"},{\"name\":\"identity\",\"type\":\"bytes32\"},{\"name\":\"active\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"executor\",\"outputs\":[{\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_nodeMaster\",\"type\":\"address\"},{\"name\":\"_endorsor\",\"type\":\"address\"},{\"name\":\"_identity\",\"type\":\"bytes32\"}],\"name\":\"add\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"name\":\"nodeMaster\",\"type\":\"address\"},{\"indexed\":false,\"name\":\"action\",\"type\":\"bytes32\"}],\"name\":\"Candidate\",\"type\":\"event\"}]", +} + +// Authority is an auto generated Go binding around an Ethereum contract, allowing you to query and create clauses. +type Authority struct { + thor *thorgo.Thor // Thor connection to use + contract *accounts.Contract // Generic contract wrapper for the low level calls +} + +// AuthorityTransactor is an auto generated Go binding around an Ethereum, allowing you to transact with the contract. +type AuthorityTransactor struct { + Authority + thor *thorgo.Thor // Thor connection to use + contract *accounts.Contract // Generic contract wrapper for the low level calls + manager accounts.TxManager // TxManager to use +} + +// NewAuthority creates a new instance of Authority, bound to a specific deployed contract. +func NewAuthority(thor *thorgo.Thor) (*Authority, error) { + parsed, err := AuthorityMetaData.GetAbi() + if err != nil { + return nil, err + } + contract := thor.Account(common.HexToAddress("0x0000000000000000000000417574686f72697479")).Contract(parsed) + if err != nil { + return nil, err + } + return &Authority{thor: thor, contract: contract}, nil +} + +// NewAuthorityTransactor creates a new instance of AuthorityTransactor, bound to a specific deployed contract. +func NewAuthorityTransactor(thor *thorgo.Thor, manager accounts.TxManager) (*AuthorityTransactor, error) { + parsed, err := AuthorityMetaData.GetAbi() + if err != nil { + return nil, err + } + contract := thor.Account(common.HexToAddress("0x0000000000000000000000417574686f72697479")).Contract(parsed) + if err != nil { + return nil, err + } + return &AuthorityTransactor{Authority{thor: thor, contract: contract}, thor, contract, manager}, nil +} + +// Address returns the address of the contract. +func (_Authority *Authority) Address() common.Address { + return _Authority.contract.Address +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_Authority *Authority) Call(revision client.Revision, result *[]interface{}, method string, params ...interface{}) error { + return _Authority.contract.Call(method, result, params...) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_AuthorityTransactor *AuthorityTransactor) Transact(vetValue *big.Int, method string, params ...interface{}) (*transactions.Visitor, error) { + return _AuthorityTransactor.contract.SendWithVET(_AuthorityTransactor.manager, vetValue, method, params...) +} + +// Executor is a free data retrieval call binding the contract method 0xc34c08e5. +// +// Solidity: function executor() view returns(address) +func (_Authority *Authority) Executor(revision ...client.Revision) (common.Address, error) { + var rev client.Revision + if len(revision) > 0 { + rev = revision[0] + } else { + rev = client.RevisionBest() + } + + var out []interface{} + err := _Authority.Call(rev, &out, "executor") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err +} + +// First is a free data retrieval call binding the contract method 0x3df4ddf4. +// +// Solidity: function first() view returns(address) +func (_Authority *Authority) First(revision ...client.Revision) (common.Address, error) { + var rev client.Revision + if len(revision) > 0 { + rev = revision[0] + } else { + rev = client.RevisionBest() + } + + var out []interface{} + err := _Authority.Call(rev, &out, "first") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err +} + +// Get is a free data retrieval call binding the contract method 0xc2bc2efc. +// +// Solidity: function get(address _nodeMaster) view returns(bool listed, address endorsor, bytes32 identity, bool active) +func (_Authority *Authority) Get(_nodeMaster common.Address, revision ...client.Revision) (struct { + Listed bool + Endorsor common.Address + Identity [32]byte + Active bool +}, error) { + var rev client.Revision + if len(revision) > 0 { + rev = revision[0] + } else { + rev = client.RevisionBest() + } + + var out []interface{} + err := _Authority.Call(rev, &out, "get", _nodeMaster) + + outstruct := new(struct { + Listed bool + Endorsor common.Address + Identity [32]byte + Active bool + }) + if err != nil { + return *outstruct, err + } + + outstruct.Listed = *abi.ConvertType(out[0], new(bool)).(*bool) + outstruct.Endorsor = *abi.ConvertType(out[1], new(common.Address)).(*common.Address) + outstruct.Identity = *abi.ConvertType(out[2], new([32]byte)).(*[32]byte) + outstruct.Active = *abi.ConvertType(out[3], new(bool)).(*bool) + + return *outstruct, err + +} + +// Next is a free data retrieval call binding the contract method 0xab73e316. +// +// Solidity: function next(address _nodeMaster) view returns(address) +func (_Authority *Authority) Next(_nodeMaster common.Address, revision ...client.Revision) (common.Address, error) { + var rev client.Revision + if len(revision) > 0 { + rev = revision[0] + } else { + rev = client.RevisionBest() + } + + var out []interface{} + err := _Authority.Call(rev, &out, "next", _nodeMaster) + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err +} + +// Add is a paid mutator transaction binding the contract method 0xdc0094b8. +// +// Solidity: function add(address _nodeMaster, address _endorsor, bytes32 _identity) returns() +func (_AuthorityTransactor *AuthorityTransactor) Add(_nodeMaster common.Address, _endorsor common.Address, _identity [32]byte, vetValue ...*big.Int) (*transactions.Visitor, error) { + var val *big.Int + if len(vetValue) > 0 { + val = vetValue[0] + } else { + val = big.NewInt(0) + } + return _AuthorityTransactor.Transact(val, "add", _nodeMaster, _endorsor, _identity) +} + +// AddAsClause is a transaction clause generator 0xdc0094b8. +// +// Solidity: function add(address _nodeMaster, address _endorsor, bytes32 _identity) returns() +func (_Authority *Authority) AddAsClause(_nodeMaster common.Address, _endorsor common.Address, _identity [32]byte, vetValue ...*big.Int) (*tx.Clause, error) { + var val *big.Int + if len(vetValue) > 0 { + val = vetValue[0] + } else { + val = big.NewInt(0) + } + return _Authority.contract.AsClauseWithVET(val, "add", _nodeMaster, _endorsor, _identity) +} + +// Revoke is a paid mutator transaction binding the contract method 0x74a8f103. +// +// Solidity: function revoke(address _nodeMaster) returns() +func (_AuthorityTransactor *AuthorityTransactor) Revoke(_nodeMaster common.Address, vetValue ...*big.Int) (*transactions.Visitor, error) { + var val *big.Int + if len(vetValue) > 0 { + val = vetValue[0] + } else { + val = big.NewInt(0) + } + return _AuthorityTransactor.Transact(val, "revoke", _nodeMaster) +} + +// RevokeAsClause is a transaction clause generator 0x74a8f103. +// +// Solidity: function revoke(address _nodeMaster) returns() +func (_Authority *Authority) RevokeAsClause(_nodeMaster common.Address, vetValue ...*big.Int) (*tx.Clause, error) { + var val *big.Int + if len(vetValue) > 0 { + val = vetValue[0] + } else { + val = big.NewInt(0) + } + return _Authority.contract.AsClauseWithVET(val, "revoke", _nodeMaster) +} + +// AuthorityCandidate represents a Candidate event raised by the Authority contract. +type AuthorityCandidate struct { + NodeMaster common.Address + Action [32]byte + Log client.EventLog +} + +type AuthorityCandidateCriteria struct { + NodeMaster *common.Address `abi:"nodeMaster"` +} + +// FilterCandidate is a free log retrieval operation binding the contract event 0xe9e2ad484aeae75ba75479c19d2cbb784b98b2fe4b24dc80a4c8cf142d4c9294. +// +// Solidity: event Candidate(address indexed nodeMaster, bytes32 action) +func (_Authority *Authority) FilterCandidate(criteria []AuthorityCandidateCriteria, opts *client.FilterOptions, rang *client.FilterRange) ([]AuthorityCandidate, error) { + topicHash := _Authority.contract.ABI.Events["Candidate"].ID + + criteriaSet := make([]client.EventCriteria, len(criteria)) + for i, c := range criteria { + crteria := client.EventCriteria{ + Address: &_Authority.contract.Address, + Topic0: &topicHash, + } + if c.NodeMaster != nil { + matcher := *c.NodeMaster + topics, err := abi.MakeTopics([]interface{}{matcher}) + if err != nil { + return nil, err + } + crteria.Topic1 = &topics[0][0] + } + + criteriaSet[i] = crteria + } + + if len(criteriaSet) == 0 { + criteriaSet = append(criteriaSet, client.EventCriteria{ + Address: &_Authority.contract.Address, + Topic0: &topicHash, // Add Topic0 here + }) + } + + filter := &client.EventFilter{ + Range: rang, + Options: opts, + Criteria: &criteriaSet, + } + + logs, err := _Authority.thor.Client.FilterEvents(filter) + if err != nil { + return nil, err + } + + inputs := _Authority.contract.ABI.Events["Candidate"].Inputs + var indexed abi.Arguments + for _, arg := range inputs { + if arg.Indexed { + indexed = append(indexed, arg) + } + } + + events := make([]AuthorityCandidate, len(logs)) + for i, log := range logs { + event := new(AuthorityCandidate) + if err := _Authority.contract.UnpackLog(event, "Candidate", log); err != nil { + return nil, err + } + event.Log = log + events[i] = *event + } + + return events, nil +} + +// WatchCandidate listens for on chain events binding the contract event 0xe9e2ad484aeae75ba75479c19d2cbb784b98b2fe4b24dc80a4c8cf142d4c9294. +// +// Solidity: event Candidate(address indexed nodeMaster, bytes32 action) +func (_Authority *Authority) WatchCandidate(criteria []AuthorityCandidateCriteria, ctx context.Context) (chan *AuthorityCandidate, error) { + topicHash := _Authority.contract.ABI.Events["Candidate"].ID + + criteriaSet := make([]client.EventCriteria, len(criteria)) + for i, c := range criteria { + crteria := client.EventCriteria{ + Address: &_Authority.contract.Address, + Topic0: &topicHash, + } + if c.NodeMaster != nil { + matcher := *c.NodeMaster + topics, err := abi.MakeTopics([]interface{}{matcher}) + if err != nil { + return nil, err + } + crteria.Topic1 = &topics[0][0] + } + + criteriaSet[i] = crteria + } + + eventChan := make(chan *AuthorityCandidate, 100) + blockSub := _Authority.thor.Blocks.Subscribe(ctx) + + go func() { + defer close(eventChan) + + for { + select { + case block := <-blockSub: + // for range in block txs + for _, tx := range block.Transactions { + for index, outputs := range tx.Outputs { + for _, event := range outputs.Events { + if event.Address != _Authority.contract.Address { + continue + } + if topicHash != event.Topics[0] { + continue + } + for _, c := range criteriaSet { + if c.Topic1 != nil && *c.Topic1 != event.Topics[1] { + continue + } + if c.Topic2 != nil && *c.Topic2 != event.Topics[2] { + continue + } + if c.Topic3 != nil && *c.Topic3 != event.Topics[3] { + continue + } + if c.Topic4 != nil && *c.Topic4 != event.Topics[4] { + continue + } + } + + log := client.EventLog{ + Address: &_Authority.contract.Address, + Topics: event.Topics, + Data: event.Data, + Meta: client.LogMeta{ + BlockID: block.ID, + BlockNumber: block.Number, + BlockTime: block.Timestamp, + TxID: tx.ID, + TxOrigin: tx.Origin, + ClauseIndex: int64(index), + }, + } + + ev := new(AuthorityCandidate) + if err := _Authority.contract.UnpackLog(ev, "Candidate", log); err != nil { + continue + } + ev.Log = log + eventChan <- ev + } + } + } + case <-ctx.Done(): + return + } + } + }() + + return eventChan, nil +} diff --git a/builtins/authority_test.go b/builtins/authority_test.go new file mode 100644 index 0000000..1a18da5 --- /dev/null +++ b/builtins/authority_test.go @@ -0,0 +1,20 @@ +package builtins + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestAuthority_FilterCandidate(t *testing.T) { + authority, err := NewAuthority(thor) + assert.NoError(t, err) + + candidates, err := authority.FilterCandidate(make([]AuthorityCandidateCriteria, 0), nil, nil) + assert.NoError(t, err) + assert.NotEmpty(t, candidates) + + res, err := authority.Get(candidates[0].NodeMaster) + assert.NoError(t, err) + assert.NotNil(t, res) +} diff --git a/builtins/contract.go b/builtins/contract.go deleted file mode 100644 index c920a2b..0000000 --- a/builtins/contract.go +++ /dev/null @@ -1,74 +0,0 @@ -package builtins - -import ( - "bytes" - "compress/gzip" - "fmt" - - "github.com/darrenvechain/thorgo" - "github.com/darrenvechain/thorgo/accounts" - "github.com/ethereum/go-ethereum/accounts/abi" - "github.com/ethereum/go-ethereum/common" -) - -type Contract struct { - ABI *abi.ABI - Address common.Address -} - -func (c *Contract) Load(thor *thorgo.Thor) *accounts.Contract { - return thor.Account(c.Address).Contract(c.ABI) -} - -var ( - VTHO = &Contract{ - ABI: mustParseABI(compiledEnergyAbi, "VTHO"), - Address: common.HexToAddress("0x0000000000000000000000000000456e65726779"), - } - Authority = &Contract{ - ABI: mustParseABI(compiledAuthorityAbi, "Authority"), - Address: common.HexToAddress("0x0000000000000000000000417574686f72697479"), - } - Executor = &Contract{ - ABI: mustParseABI(compiledExecutorAbi, "Executor"), - Address: common.HexToAddress("0x0000000000000000000000004578656375746f72"), - } - Extension = &Contract{ - ABI: mustParseABI(compiledExtensionv2Abi, "Extension"), - Address: common.HexToAddress("0x0000000000000000000000457874656e73696f6e"), - } - Prototype = &Contract{ - ABI: mustParseABI(compiledPrototypeAbi, "Prototype"), - Address: common.HexToAddress("0x000000000000000000000050726f746f74797065"), - } - Params = &Contract{ - ABI: mustParseABI(compiledParamsAbi, "Params"), - Address: common.HexToAddress("0x0000000000000000000000000000506172616d73"), - } -) - -func mustParseABI(data []byte, name string) *abi.ABI { - gz, err := gzip.NewReader(bytes.NewBuffer(data)) - if err != nil { - panic(fmt.Errorf("read %q: %v", name, err)) - } - - contractABI, err := abi.JSON(gz) - if err != nil { - panic(fmt.Errorf("parse %q: %v", name, err)) - } - - return &contractABI -} - -var compiledEnergyAbi = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xcc\x56\xcf\xaf\xd3\x30\x0c\xfe\x5f\x7c\xce\x09\x09\x84\x7a\x83\x03\x37\xc4\x01\x6e\x4f\x3b\xb8\xad\x8b\x22\x25\x76\x94\x38\x1b\xd5\xd3\xfb\xdf\xd1\xb6\xac\xab\xa0\xbf\x98\x86\xb6\x53\x2b\xd9\x8e\xbf\xcf\xf6\x97\xf8\xe5\x15\x1a\xe1\xa4\xc8\x0a\x95\xc6\x4c\x06\x2c\x87\xac\x09\xaa\x97\x9d\x01\x46\x4f\x50\x9d\x3f\x06\x24\x6b\x31\xbd\x5e\x2c\x60\x40\xfb\x70\xfc\x4b\x1a\x2d\xff\x84\xb7\x9d\x81\x80\x3d\xd6\x8e\xa0\xea\xd0\x25\x32\x90\x14\x95\xbe\x66\xc5\xda\x3a\xab\x3d\x54\x10\x72\xa4\x6b\x68\x97\xb9\x51\x2b\x0c\x6f\x66\x0c\xa7\x44\x0f\x78\x86\xa4\x29\x10\xb7\x14\xaf\x07\x60\xdb\x46\x4a\xe9\x14\x5f\x7c\xf6\xe8\xf2\x28\x45\xb6\xac\xef\xde\x7f\x38\xc1\x2b\x1e\x18\x42\x94\xfd\x0c\xaf\x94\x9b\xe6\x78\xe2\x70\x40\x2d\xe2\x36\x92\x63\xe1\x8b\xd3\x1a\xc5\xd9\x8a\xab\x28\xba\xef\x39\x04\xd7\xaf\x15\x7e\x4c\x6d\x1d\xdc\xde\xd2\xe1\xf6\xca\x77\x51\xfc\x62\xd9\x55\x16\xcd\xe8\x25\xb3\x2e\xb6\x45\x23\x72\xea\x28\x7e\x39\xa7\x7a\xc2\xde\xb4\xd4\x58\x8f\x2e\x6d\x69\xcc\xc7\x7b\x0a\xe2\x0f\x44\x43\x4a\x39\xf0\xa4\x1a\xae\x90\x6b\x74\xc8\x0d\x7d\xeb\xa6\x31\x17\xf3\x7f\x9d\xa9\xd9\x72\xa6\xde\xd7\xe2\x9e\xe8\x7a\xb9\xdf\x0c\x3f\x74\x7e\x1f\x29\x62\xff\xdc\x17\xeb\xe7\x1c\x99\xda\x07\x5c\xac\xff\xaa\x60\xb3\xe1\xcd\x1b\xbd\x68\xce\xc9\xa1\x08\x79\x82\x59\x24\x8f\x96\x8f\x2a\xba\x3f\x45\x64\xe1\xde\x4b\x4e\x53\x73\x67\xb9\xa5\x5f\xd4\x5e\xe8\xaf\x8e\xe1\xb4\xff\xdc\x54\x0e\xde\x25\xf1\xe6\x05\xe0\xc7\x55\xa5\xc5\x89\xf6\xc4\x7a\x2b\x9f\x85\x1e\x4e\x07\x2c\xae\x31\x37\xb3\xfa\x74\x5a\x6b\xd0\xfd\xc5\x6a\xf7\x3b\x00\x00\xff\xff\x3d\x94\x5b\x7e\xec\x09\x00\x00") - -var compiledAuthorityAbi = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xd4\x93\xcd\x6e\xc2\x40\x0c\x84\xdf\xc5\xe7\x3d\xb5\xb7\x5c\x7b\xe6\x09\x10\x07\x13\x0f\xd5\xaa\xc1\x46\xb1\x37\x25\x42\xbc\x7b\x05\x0a\x24\x45\xb4\xa5\x6a\x51\xd5\x5b\x24\xff\xcc\x37\x93\xf5\x7c\x47\xb5\xa9\x07\x6b\x50\x15\x6d\x41\xa2\xac\x9b\x12\x4e\xd5\x7c\x91\x48\x79\x0d\xaa\x68\x95\x5b\x0f\x4a\x64\x25\x86\xda\xee\x54\xa2\x44\xd1\x6f\x0e\x5f\x2c\xd2\xc2\x9d\xf6\x8b\x44\x1b\xee\x79\xd9\x80\xaa\x15\x37\x8e\x44\x1e\x1c\x98\x95\xe0\x65\x6e\x72\xf4\x54\x51\x97\xf1\x3a\xce\xae\x8a\xd6\x91\x4d\x69\x9f\xa6\x40\xc3\xf4\x99\xe8\xac\xaa\x26\x98\xb1\x07\xda\xeb\xfa\x43\x5b\x8b\xce\x5e\xf0\x0e\xfc\x26\x38\x35\x3d\x35\x7d\x85\x78\x91\xd9\x77\x09\x15\xdb\xbf\x08\xf6\x87\xd4\xcf\xf8\x00\xba\xc9\x1e\x90\x71\x76\x69\xd6\x1c\xa5\x87\x3a\x54\xac\x75\xbb\xb6\x7d\x6c\xca\x02\x8d\x83\x99\x71\x4d\x1f\xf0\xc7\x87\x69\x13\xd7\x91\x3b\x5c\x2a\xdd\x2d\xa1\xd1\x3b\xb6\xa8\x4b\x1c\x2d\xfc\x8f\x73\xf8\xbd\xf4\xc7\x10\x58\xe4\x0e\x57\xc5\x6a\xda\xaf\xad\xf8\x35\xab\x59\x05\x5b\xc8\xe9\xcf\xdc\xe8\xfc\x3c\x35\x2c\x9c\xbc\x1e\xd3\x4f\x2d\x3e\xb1\x4a\x16\x8e\x09\x2c\x3a\x68\xd0\x7e\xf1\x16\x00\x00\xff\xff\x5e\x1e\xdc\x95\x35\x05\x00\x00") - -var compiledExecutorAbi = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xd4\x55\x3d\x6f\xdb\x40\x0c\xfd\x2f\x9c\x35\xb5\x45\x51\x68\x33\xd2\xa5\x43\x01\x4f\x5d\x82\xc0\xa0\x75\x4c\x7a\xa8\x4c\xaa\x77\x3c\x25\x42\x90\xff\x5e\xc4\xd2\xf5\x24\xeb\xa3\x6e\x6a\x58\xe8\x66\xc0\x8f\x4f\x8f\x8f\x8f\xbc\xdb\x67\x28\x84\xbd\x22\x2b\xe4\xea\x02\x65\x60\xb9\x0a\xea\x21\xbf\x7d\x06\xc6\x03\x41\x0e\x90\x81\x36\xd5\xeb\x2f\x34\xc6\x91\xf7\xf0\x72\x97\xc5\x3f\xb1\xaa\x9c\xd4\xe4\x3c\x64\x20\x41\x4f\x6b\xad\x21\x56\xab\x4d\xe2\xd8\x37\x4a\xfe\xfd\x3b\x78\xc9\x12\x88\xb7\xf2\x48\xae\x87\x11\x29\x8f\x1f\xa9\xb0\xc1\x7d\x49\x90\xdf\x63\xe9\x29\x03\xaf\xa8\xf4\x35\x28\xee\x6d\xf9\xca\x9a\x43\x6d\xe9\x31\x15\xde\x07\x2e\xd4\x0a\x1f\xd9\x67\x3b\x1b\xab\xbf\x91\xc0\x3a\xdd\x41\x22\x0f\x96\xf5\xd3\x25\x65\x75\xd5\x63\xc7\x77\x51\xd7\xa2\xf5\x8e\x6a\xf9\x41\x9b\x04\x4d\xea\xcf\xd2\xc8\xc2\x11\xf4\x97\x06\x4e\x98\xf3\x7b\xac\x49\x5f\xe5\xa4\x12\x8f\xe5\x4c\x34\xd4\x1e\x68\x7b\x84\x90\x19\x9a\xfc\xf1\x43\x3f\x1d\x2d\xcd\xa4\x17\x09\xf4\x33\x88\x0b\x87\xd1\xac\x12\xa0\x75\x14\xcb\x38\xe9\x39\x1c\x3d\x51\x11\xb4\xaf\xa8\x0d\x63\x42\x28\xba\x07\xd2\x45\x35\x06\x15\x4f\xac\x59\x3d\x37\x49\xdd\x6e\x61\x29\x7b\xab\x61\xcc\x55\xa2\x35\xdf\xcc\x19\x46\xef\xe6\x9c\x1e\x66\xe7\x4f\x9b\xdd\x6f\xff\x4a\xcd\x15\xc2\xea\xb0\x98\x6a\xaf\x37\x03\x55\x2c\xbe\x7f\x13\xb5\xfc\x70\x93\x0a\xd6\x18\x46\x5c\xe6\x2f\x9f\x97\x53\xd3\x46\x66\x25\x91\x67\x99\x6a\xe8\x7f\x33\xb5\xbb\x49\x2b\x5f\xf8\x09\x2b\xeb\x81\x89\x33\x77\xfe\xd2\xcf\x3a\xb2\x70\x73\x90\xe0\xa7\x9c\xb5\x6c\xe8\x89\x4c\xec\xe7\xe4\x25\x9a\xf4\x39\xeb\x55\x75\x84\x31\xcc\xed\x47\x97\x46\xb3\xed\x98\x13\x88\x6a\x62\x7d\xab\xd0\xe5\xfb\xfd\x76\x99\x9b\x11\xef\x3f\xc9\x8c\x7b\xb6\x31\xe6\xe2\x52\x47\x8b\x39\x14\x7c\xf7\x2b\x00\x00\xff\xff\xa9\x52\x06\x45\xb3\x0a\x00\x00") - -var compiledExtensionv2Abi = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xcc\xd3\x41\x4b\xc3\x30\x14\x07\xf0\xef\xf2\xce\x39\x55\x1d\xd2\xa3\x28\xe2\x41\x18\x6e\xe0\x61\xf4\xf0\xd2\xbe\x4a\x68\x9a\x84\xe4\x65\x2e\x8c\x7d\x77\x69\x99\x5b\x0f\xe2\x2a\xa2\xed\xad\xd0\xfc\x79\x3f\xfe\xbc\xb7\xd9\x43\x69\x4d\x60\x34\x0c\x39\xfb\x48\x02\x94\x71\x91\x03\xe4\x9b\x42\x80\xc1\x96\x20\x07\xb6\x8c\x7a\x15\x9d\xd3\x09\x04\xd8\xc8\xc7\x17\xfb\xcf\x07\x20\x80\x93\xeb\xbe\xa2\x32\x9c\xdd\x2c\xe0\x50\x08\x70\x98\x50\x6a\x82\xbc\x46\x1d\x48\x40\x60\x64\x7a\x8e\x8c\x52\x69\xc5\x09\x72\xd8\x2a\x7a\x3f\x67\xeb\x68\x4a\x56\xd6\xc0\x41\x7c\xc3\x3a\x0d\xad\x90\xf1\x1c\x96\x89\x29\xf4\x63\x8f\xbf\xa5\xc6\x86\x32\xd9\x61\x2e\x98\xfb\xe8\x55\xf6\x1f\x66\x13\xdb\xaf\xbb\x3a\xa1\x6d\xd9\xac\x55\x4b\x33\xea\x79\x94\x79\xa5\xde\x0c\xf9\x4b\x6a\xac\x2a\x4f\x21\xcc\x46\xbd\xee\x17\xbb\xb4\x7e\x54\xdf\x8b\xeb\x3f\x84\x0f\xae\x6d\xf7\x88\x61\x89\x69\x0e\x75\x0e\x55\x0f\x3b\xa7\x3c\xf6\x99\xc9\x97\x73\xe8\x7a\xba\x9f\xfe\xc0\x87\x9e\xa5\xb7\x5b\xaa\x5e\xad\x6f\xa6\xef\xe9\x67\xe7\x30\xb7\x26\xef\x3a\xd4\x0b\xd5\xa3\x54\xb7\xbf\x44\x15\x1f\x01\x00\x00\xff\xff\x30\xf3\x42\x68\x0c\x07\x00\x00") - -var compiledParamsAbi = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xa4\x92\xc1\x6a\xc3\x30\x0c\x86\xdf\xe5\x3f\xfb\xd4\xb1\x1d\xf2\x0e\x3b\xed\x58\xc2\x50\x12\x75\x98\xa5\x72\x88\xa4\xac\xa6\xe4\xdd\xc7\x4a\x12\xc3\xe8\x08\x65\x47\xe3\xcf\xbf\x3e\xa3\xff\x78\x45\x9b\x44\x8d\xc4\x50\x9d\xa8\x57\x0e\x88\x32\xb8\x29\xaa\xe3\x15\x42\x67\x46\x85\xf7\x4f\xce\x08\xb0\x3c\xfc\x9c\x9a\x6c\xac\x4f\x07\xcc\xa1\x00\x13\xf5\xce\x05\xf1\x28\x76\x78\x7e\xc1\x5c\x87\x15\x51\x36\x04\x24\xb7\x25\xbc\x0e\x18\x28\x53\xd3\xf3\x36\x58\x8d\x8c\x5f\xdd\xa8\x89\x7d\xb4\x8c\x0a\x92\x64\x85\xb6\xec\x93\x4b\x6b\x31\xc9\x6d\x7e\x91\xb7\xd1\x1f\x71\x2f\x62\x1f\xbf\xc4\xb6\x97\xf7\xbf\xb3\x2f\x3d\x45\xfe\x7a\x54\xb7\xe8\xf0\x85\x5b\xb7\x34\xee\x39\x51\xd7\x8d\xac\xfa\x7f\x27\x92\x24\xf9\x9c\x5c\xef\x15\x20\x4a\xc7\x17\xee\x56\xdf\xc5\xe2\xcf\x3a\x6c\xf8\x92\xb4\xf0\xfb\xed\x78\xbb\x2d\x61\xb9\xe7\x89\xc5\x30\xd7\xdf\x01\x00\x00\xff\xff\xfb\x8f\x43\xc8\x9d\x02\x00\x00") - -var compiledPrototypeAbi = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xd4\x56\x4d\x8f\xda\x30\x10\xfd\x2f\x3e\xe7\x44\xd5\x1e\x72\x45\xea\x8d\xaa\x6a\xd5\x13\x42\xd5\xc4\x19\xa8\x85\x33\x8e\x3c\x63\x50\x84\xfa\xdf\x57\xa0\x25\x31\x4b\x84\x77\xf9\xd8\x84\x23\xe2\x4d\x3c\xcf\xf3\xde\xf3\xcc\x77\x4a\x3b\x62\x01\x12\x95\x2f\xc1\x32\x66\xca\x50\x1d\x84\x55\x3e\xdf\x29\x82\x0a\x55\xae\xfe\x32\xda\xa5\xca\x94\x34\xf5\xfe\x27\x94\xa5\x47\x66\xf5\x3f\xeb\x10\x84\xdb\x19\xb0\xa0\xef\x81\x2d\xb2\x23\x8c\x51\x5a\x94\x0b\xf2\x7a\xce\x22\x53\x35\x34\x50\x58\x6c\x7b\x60\x01\xc1\x59\x10\x28\x8c\x35\xd2\xa8\x5c\x91\xa3\x23\xa8\x3d\x61\x19\x48\x8b\x71\x74\xe8\xa4\xe3\x21\x3e\x5c\x4b\x23\x70\x82\x81\xe1\x3f\xfc\xa6\xfd\xb6\xba\x2b\x2c\x9c\xb3\x87\xaa\x34\xaf\x8d\xc1\xed\x23\x19\xad\xb1\x89\xfa\x6a\x04\xf9\xcb\xe4\x64\x24\xe2\x3c\xac\xf0\xbb\x4b\x93\x8a\x8a\x87\xe7\x55\x58\xa7\xd7\x3f\x42\x55\xc4\x03\x0b\x86\x64\xf2\xf5\x5b\xcc\x0f\x09\xfd\xaa\x49\x71\x8b\x0b\xef\xc4\xed\x16\x37\x25\x65\xe8\xb1\x72\x1b\x3c\x93\xe2\xd0\x4e\xea\x1a\xd4\xc1\x7b\x24\xf9\x5d\x3b\xe2\xb4\xb4\xe2\x0f\x8c\xe0\xfa\xb5\xc7\xd2\x48\x8f\x3a\x22\x8c\x47\xed\x36\xe8\x9b\x5f\x20\x78\x51\x80\x8c\x32\x3d\x7c\xef\xa7\x05\x7a\xe8\xb4\x6e\xa1\xcc\xed\xa0\x2e\xa5\xb7\x45\xdd\x3b\xd2\xa1\x75\x77\x45\x2e\x14\x60\x81\x34\x3e\x43\x30\x44\x13\x18\xe1\xdd\x47\x9e\xef\x97\xf9\xee\xf4\xff\x8b\xb6\x4a\xbb\x6a\x04\xf1\x90\x4c\x67\x28\xcb\x11\x47\xf3\x3f\xe0\xa9\x2b\x93\xca\x1f\x7a\x87\xe9\x1a\xae\xce\x57\xc6\xcf\x79\x43\x1e\xb9\x48\xee\x01\xd3\xa3\x21\x9e\x28\x82\x02\x8d\x31\x84\x3e\xf8\x92\x19\x7e\xe7\x62\x72\x07\x13\x2c\x5e\x02\x00\x00\xff\xff\xc1\xa7\x82\x58\x64\x0d\x00\x00") diff --git a/builtins/energy.go b/builtins/energy.go new file mode 100644 index 0000000..ebc0233 --- /dev/null +++ b/builtins/energy.go @@ -0,0 +1,726 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package builtins + +import ( + "context" + "errors" + "math/big" + "strings" + + "github.com/darrenvechain/thorgo" + "github.com/darrenvechain/thorgo/accounts" + "github.com/darrenvechain/thorgo/client" + "github.com/darrenvechain/thorgo/crypto/tx" + "github.com/darrenvechain/thorgo/transactions" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/hexutil" +) + +// Reference imports to suppress errors if they are not otherwise used. +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = bind.Bind + _ = common.Big1 + _ = abi.ConvertType + _ = hexutil.MustDecode + _ = context.Background + _ = tx.NewClause +) + +// EnergyMetaData contains all meta data concerning the Energy contract. +var EnergyMetaData = &bind.MetaData{ + ABI: "[{\"constant\":true,\"inputs\":[],\"name\":\"name\",\"outputs\":[{\"name\":\"\",\"type\":\"string\"}],\"payable\":false,\"stateMutability\":\"pure\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_spender\",\"type\":\"address\"},{\"name\":\"_value\",\"type\":\"uint256\"}],\"name\":\"approve\",\"outputs\":[{\"name\":\"success\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"totalSupply\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_from\",\"type\":\"address\"},{\"name\":\"_to\",\"type\":\"address\"},{\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"transferFrom\",\"outputs\":[{\"name\":\"success\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"decimals\",\"outputs\":[{\"name\":\"\",\"type\":\"uint8\"}],\"payable\":false,\"stateMutability\":\"pure\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"_owner\",\"type\":\"address\"}],\"name\":\"balanceOf\",\"outputs\":[{\"name\":\"balance\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"symbol\",\"outputs\":[{\"name\":\"\",\"type\":\"string\"}],\"payable\":false,\"stateMutability\":\"pure\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_to\",\"type\":\"address\"},{\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"transfer\",\"outputs\":[{\"name\":\"success\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_from\",\"type\":\"address\"},{\"name\":\"_to\",\"type\":\"address\"},{\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"move\",\"outputs\":[{\"name\":\"success\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"totalBurned\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"_owner\",\"type\":\"address\"},{\"name\":\"_spender\",\"type\":\"address\"}],\"name\":\"allowance\",\"outputs\":[{\"name\":\"remaining\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"name\":\"_from\",\"type\":\"address\"},{\"indexed\":true,\"name\":\"_to\",\"type\":\"address\"},{\"indexed\":false,\"name\":\"_value\",\"type\":\"uint256\"}],\"name\":\"Transfer\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"name\":\"_owner\",\"type\":\"address\"},{\"indexed\":true,\"name\":\"_spender\",\"type\":\"address\"},{\"indexed\":false,\"name\":\"_value\",\"type\":\"uint256\"}],\"name\":\"Approval\",\"type\":\"event\"}]", +} + +// Energy is an auto generated Go binding around an Ethereum contract, allowing you to query and create clauses. +type Energy struct { + thor *thorgo.Thor // Thor connection to use + contract *accounts.Contract // Generic contract wrapper for the low level calls +} + +// EnergyTransactor is an auto generated Go binding around an Ethereum, allowing you to transact with the contract. +type EnergyTransactor struct { + Energy + thor *thorgo.Thor // Thor connection to use + contract *accounts.Contract // Generic contract wrapper for the low level calls + manager accounts.TxManager // TxManager to use +} + +// NewEnergy creates a new instance of Energy, bound to a specific deployed contract. +func NewEnergy(thor *thorgo.Thor) (*Energy, error) { + parsed, err := EnergyMetaData.GetAbi() + if err != nil { + return nil, err + } + contract := thor.Account(common.HexToAddress("0x0000000000000000000000000000456e65726779")).Contract(parsed) + if err != nil { + return nil, err + } + return &Energy{thor: thor, contract: contract}, nil +} + +// NewEnergyTransactor creates a new instance of EnergyTransactor, bound to a specific deployed contract. +func NewEnergyTransactor(thor *thorgo.Thor, manager accounts.TxManager) (*EnergyTransactor, error) { + parsed, err := EnergyMetaData.GetAbi() + if err != nil { + return nil, err + } + contract := thor.Account(common.HexToAddress("0x0000000000000000000000000000456e65726779")).Contract(parsed) + if err != nil { + return nil, err + } + return &EnergyTransactor{Energy{thor: thor, contract: contract}, thor, contract, manager}, nil +} + +// Address returns the address of the contract. +func (_Energy *Energy) Address() common.Address { + return _Energy.contract.Address +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_Energy *Energy) Call(revision client.Revision, result *[]interface{}, method string, params ...interface{}) error { + return _Energy.contract.Call(method, result, params...) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_EnergyTransactor *EnergyTransactor) Transact(vetValue *big.Int, method string, params ...interface{}) (*transactions.Visitor, error) { + return _EnergyTransactor.contract.SendWithVET(_EnergyTransactor.manager, vetValue, method, params...) +} + +// Allowance is a free data retrieval call binding the contract method 0xdd62ed3e. +// +// Solidity: function allowance(address _owner, address _spender) view returns(uint256 remaining) +func (_Energy *Energy) Allowance(_owner common.Address, _spender common.Address, revision ...client.Revision) (*big.Int, error) { + var rev client.Revision + if len(revision) > 0 { + rev = revision[0] + } else { + rev = client.RevisionBest() + } + + var out []interface{} + err := _Energy.Call(rev, &out, "allowance", _owner, _spender) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err +} + +// BalanceOf is a free data retrieval call binding the contract method 0x70a08231. +// +// Solidity: function balanceOf(address _owner) view returns(uint256 balance) +func (_Energy *Energy) BalanceOf(_owner common.Address, revision ...client.Revision) (*big.Int, error) { + var rev client.Revision + if len(revision) > 0 { + rev = revision[0] + } else { + rev = client.RevisionBest() + } + + var out []interface{} + err := _Energy.Call(rev, &out, "balanceOf", _owner) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err +} + +// Decimals is a free data retrieval call binding the contract method 0x313ce567. +// +// Solidity: function decimals() pure returns(uint8) +func (_Energy *Energy) Decimals(revision ...client.Revision) (uint8, error) { + var rev client.Revision + if len(revision) > 0 { + rev = revision[0] + } else { + rev = client.RevisionBest() + } + + var out []interface{} + err := _Energy.Call(rev, &out, "decimals") + + if err != nil { + return *new(uint8), err + } + + out0 := *abi.ConvertType(out[0], new(uint8)).(*uint8) + + return out0, err +} + +// Name is a free data retrieval call binding the contract method 0x06fdde03. +// +// Solidity: function name() pure returns(string) +func (_Energy *Energy) Name(revision ...client.Revision) (string, error) { + var rev client.Revision + if len(revision) > 0 { + rev = revision[0] + } else { + rev = client.RevisionBest() + } + + var out []interface{} + err := _Energy.Call(rev, &out, "name") + + if err != nil { + return *new(string), err + } + + out0 := *abi.ConvertType(out[0], new(string)).(*string) + + return out0, err +} + +// Symbol is a free data retrieval call binding the contract method 0x95d89b41. +// +// Solidity: function symbol() pure returns(string) +func (_Energy *Energy) Symbol(revision ...client.Revision) (string, error) { + var rev client.Revision + if len(revision) > 0 { + rev = revision[0] + } else { + rev = client.RevisionBest() + } + + var out []interface{} + err := _Energy.Call(rev, &out, "symbol") + + if err != nil { + return *new(string), err + } + + out0 := *abi.ConvertType(out[0], new(string)).(*string) + + return out0, err +} + +// TotalBurned is a free data retrieval call binding the contract method 0xd89135cd. +// +// Solidity: function totalBurned() view returns(uint256) +func (_Energy *Energy) TotalBurned(revision ...client.Revision) (*big.Int, error) { + var rev client.Revision + if len(revision) > 0 { + rev = revision[0] + } else { + rev = client.RevisionBest() + } + + var out []interface{} + err := _Energy.Call(rev, &out, "totalBurned") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err +} + +// TotalSupply is a free data retrieval call binding the contract method 0x18160ddd. +// +// Solidity: function totalSupply() view returns(uint256) +func (_Energy *Energy) TotalSupply(revision ...client.Revision) (*big.Int, error) { + var rev client.Revision + if len(revision) > 0 { + rev = revision[0] + } else { + rev = client.RevisionBest() + } + + var out []interface{} + err := _Energy.Call(rev, &out, "totalSupply") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err +} + +// Approve is a paid mutator transaction binding the contract method 0x095ea7b3. +// +// Solidity: function approve(address _spender, uint256 _value) returns(bool success) +func (_EnergyTransactor *EnergyTransactor) Approve(_spender common.Address, _value *big.Int, vetValue ...*big.Int) (*transactions.Visitor, error) { + var val *big.Int + if len(vetValue) > 0 { + val = vetValue[0] + } else { + val = big.NewInt(0) + } + return _EnergyTransactor.Transact(val, "approve", _spender, _value) +} + +// ApproveAsClause is a transaction clause generator 0x095ea7b3. +// +// Solidity: function approve(address _spender, uint256 _value) returns(bool success) +func (_Energy *Energy) ApproveAsClause(_spender common.Address, _value *big.Int, vetValue ...*big.Int) (*tx.Clause, error) { + var val *big.Int + if len(vetValue) > 0 { + val = vetValue[0] + } else { + val = big.NewInt(0) + } + return _Energy.contract.AsClauseWithVET(val, "approve", _spender, _value) +} + +// Move is a paid mutator transaction binding the contract method 0xbb35783b. +// +// Solidity: function move(address _from, address _to, uint256 _amount) returns(bool success) +func (_EnergyTransactor *EnergyTransactor) Move(_from common.Address, _to common.Address, _amount *big.Int, vetValue ...*big.Int) (*transactions.Visitor, error) { + var val *big.Int + if len(vetValue) > 0 { + val = vetValue[0] + } else { + val = big.NewInt(0) + } + return _EnergyTransactor.Transact(val, "move", _from, _to, _amount) +} + +// MoveAsClause is a transaction clause generator 0xbb35783b. +// +// Solidity: function move(address _from, address _to, uint256 _amount) returns(bool success) +func (_Energy *Energy) MoveAsClause(_from common.Address, _to common.Address, _amount *big.Int, vetValue ...*big.Int) (*tx.Clause, error) { + var val *big.Int + if len(vetValue) > 0 { + val = vetValue[0] + } else { + val = big.NewInt(0) + } + return _Energy.contract.AsClauseWithVET(val, "move", _from, _to, _amount) +} + +// Transfer is a paid mutator transaction binding the contract method 0xa9059cbb. +// +// Solidity: function transfer(address _to, uint256 _amount) returns(bool success) +func (_EnergyTransactor *EnergyTransactor) Transfer(_to common.Address, _amount *big.Int, vetValue ...*big.Int) (*transactions.Visitor, error) { + var val *big.Int + if len(vetValue) > 0 { + val = vetValue[0] + } else { + val = big.NewInt(0) + } + return _EnergyTransactor.Transact(val, "transfer", _to, _amount) +} + +// TransferAsClause is a transaction clause generator 0xa9059cbb. +// +// Solidity: function transfer(address _to, uint256 _amount) returns(bool success) +func (_Energy *Energy) TransferAsClause(_to common.Address, _amount *big.Int, vetValue ...*big.Int) (*tx.Clause, error) { + var val *big.Int + if len(vetValue) > 0 { + val = vetValue[0] + } else { + val = big.NewInt(0) + } + return _Energy.contract.AsClauseWithVET(val, "transfer", _to, _amount) +} + +// TransferFrom is a paid mutator transaction binding the contract method 0x23b872dd. +// +// Solidity: function transferFrom(address _from, address _to, uint256 _amount) returns(bool success) +func (_EnergyTransactor *EnergyTransactor) TransferFrom(_from common.Address, _to common.Address, _amount *big.Int, vetValue ...*big.Int) (*transactions.Visitor, error) { + var val *big.Int + if len(vetValue) > 0 { + val = vetValue[0] + } else { + val = big.NewInt(0) + } + return _EnergyTransactor.Transact(val, "transferFrom", _from, _to, _amount) +} + +// TransferFromAsClause is a transaction clause generator 0x23b872dd. +// +// Solidity: function transferFrom(address _from, address _to, uint256 _amount) returns(bool success) +func (_Energy *Energy) TransferFromAsClause(_from common.Address, _to common.Address, _amount *big.Int, vetValue ...*big.Int) (*tx.Clause, error) { + var val *big.Int + if len(vetValue) > 0 { + val = vetValue[0] + } else { + val = big.NewInt(0) + } + return _Energy.contract.AsClauseWithVET(val, "transferFrom", _from, _to, _amount) +} + +// EnergyApproval represents a Approval event raised by the Energy contract. +type EnergyApproval struct { + Owner common.Address + Spender common.Address + Value *big.Int + Log client.EventLog +} + +type EnergyApprovalCriteria struct { + Owner *common.Address `abi:"_owner"` + Spender *common.Address `abi:"_spender"` +} + +// FilterApproval is a free log retrieval operation binding the contract event 0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925. +// +// Solidity: event Approval(address indexed _owner, address indexed _spender, uint256 _value) +func (_Energy *Energy) FilterApproval(criteria []EnergyApprovalCriteria, opts *client.FilterOptions, rang *client.FilterRange) ([]EnergyApproval, error) { + topicHash := _Energy.contract.ABI.Events["Approval"].ID + + criteriaSet := make([]client.EventCriteria, len(criteria)) + for i, c := range criteria { + crteria := client.EventCriteria{ + Address: &_Energy.contract.Address, + Topic0: &topicHash, + } + if c.Owner != nil { + matcher := *c.Owner + topics, err := abi.MakeTopics([]interface{}{matcher}) + if err != nil { + return nil, err + } + crteria.Topic1 = &topics[0][0] + } + if c.Spender != nil { + matcher := *c.Spender + topics, err := abi.MakeTopics([]interface{}{matcher}) + if err != nil { + return nil, err + } + crteria.Topic2 = &topics[0][0] + } + + criteriaSet[i] = crteria + } + + if len(criteriaSet) == 0 { + criteriaSet = append(criteriaSet, client.EventCriteria{ + Address: &_Energy.contract.Address, + Topic0: &topicHash, // Add Topic0 here + }) + } + + filter := &client.EventFilter{ + Range: rang, + Options: opts, + Criteria: &criteriaSet, + } + + logs, err := _Energy.thor.Client.FilterEvents(filter) + if err != nil { + return nil, err + } + + inputs := _Energy.contract.ABI.Events["Approval"].Inputs + var indexed abi.Arguments + for _, arg := range inputs { + if arg.Indexed { + indexed = append(indexed, arg) + } + } + + events := make([]EnergyApproval, len(logs)) + for i, log := range logs { + event := new(EnergyApproval) + if err := _Energy.contract.UnpackLog(event, "Approval", log); err != nil { + return nil, err + } + event.Log = log + events[i] = *event + } + + return events, nil +} + +// WatchApproval listens for on chain events binding the contract event 0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925. +// +// Solidity: event Approval(address indexed _owner, address indexed _spender, uint256 _value) +func (_Energy *Energy) WatchApproval(criteria []EnergyApprovalCriteria, ctx context.Context) (chan *EnergyApproval, error) { + topicHash := _Energy.contract.ABI.Events["Approval"].ID + + criteriaSet := make([]client.EventCriteria, len(criteria)) + for i, c := range criteria { + crteria := client.EventCriteria{ + Address: &_Energy.contract.Address, + Topic0: &topicHash, + } + if c.Owner != nil { + matcher := *c.Owner + topics, err := abi.MakeTopics([]interface{}{matcher}) + if err != nil { + return nil, err + } + crteria.Topic1 = &topics[0][0] + } + if c.Spender != nil { + matcher := *c.Spender + topics, err := abi.MakeTopics([]interface{}{matcher}) + if err != nil { + return nil, err + } + crteria.Topic2 = &topics[0][0] + } + + criteriaSet[i] = crteria + } + + eventChan := make(chan *EnergyApproval, 100) + blockSub := _Energy.thor.Blocks.Subscribe(ctx) + + go func() { + defer close(eventChan) + + for { + select { + case block := <-blockSub: + // for range in block txs + for _, tx := range block.Transactions { + for index, outputs := range tx.Outputs { + for _, event := range outputs.Events { + if event.Address != _Energy.contract.Address { + continue + } + if topicHash != event.Topics[0] { + continue + } + for _, c := range criteriaSet { + if c.Topic1 != nil && *c.Topic1 != event.Topics[1] { + continue + } + if c.Topic2 != nil && *c.Topic2 != event.Topics[2] { + continue + } + if c.Topic3 != nil && *c.Topic3 != event.Topics[3] { + continue + } + if c.Topic4 != nil && *c.Topic4 != event.Topics[4] { + continue + } + } + + log := client.EventLog{ + Address: &_Energy.contract.Address, + Topics: event.Topics, + Data: event.Data, + Meta: client.LogMeta{ + BlockID: block.ID, + BlockNumber: block.Number, + BlockTime: block.Timestamp, + TxID: tx.ID, + TxOrigin: tx.Origin, + ClauseIndex: int64(index), + }, + } + + ev := new(EnergyApproval) + if err := _Energy.contract.UnpackLog(ev, "Approval", log); err != nil { + continue + } + ev.Log = log + eventChan <- ev + } + } + } + case <-ctx.Done(): + return + } + } + }() + + return eventChan, nil +} + +// EnergyTransfer represents a Transfer event raised by the Energy contract. +type EnergyTransfer struct { + From common.Address + To common.Address + Value *big.Int + Log client.EventLog +} + +type EnergyTransferCriteria struct { + From *common.Address `abi:"_from"` + To *common.Address `abi:"_to"` +} + +// FilterTransfer is a free log retrieval operation binding the contract event 0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef. +// +// Solidity: event Transfer(address indexed _from, address indexed _to, uint256 _value) +func (_Energy *Energy) FilterTransfer(criteria []EnergyTransferCriteria, opts *client.FilterOptions, rang *client.FilterRange) ([]EnergyTransfer, error) { + topicHash := _Energy.contract.ABI.Events["Transfer"].ID + + criteriaSet := make([]client.EventCriteria, len(criteria)) + for i, c := range criteria { + crteria := client.EventCriteria{ + Address: &_Energy.contract.Address, + Topic0: &topicHash, + } + if c.From != nil { + matcher := *c.From + topics, err := abi.MakeTopics([]interface{}{matcher}) + if err != nil { + return nil, err + } + crteria.Topic1 = &topics[0][0] + } + if c.To != nil { + matcher := *c.To + topics, err := abi.MakeTopics([]interface{}{matcher}) + if err != nil { + return nil, err + } + crteria.Topic2 = &topics[0][0] + } + + criteriaSet[i] = crteria + } + + if len(criteriaSet) == 0 { + criteriaSet = append(criteriaSet, client.EventCriteria{ + Address: &_Energy.contract.Address, + Topic0: &topicHash, // Add Topic0 here + }) + } + + filter := &client.EventFilter{ + Range: rang, + Options: opts, + Criteria: &criteriaSet, + } + + logs, err := _Energy.thor.Client.FilterEvents(filter) + if err != nil { + return nil, err + } + + inputs := _Energy.contract.ABI.Events["Transfer"].Inputs + var indexed abi.Arguments + for _, arg := range inputs { + if arg.Indexed { + indexed = append(indexed, arg) + } + } + + events := make([]EnergyTransfer, len(logs)) + for i, log := range logs { + event := new(EnergyTransfer) + if err := _Energy.contract.UnpackLog(event, "Transfer", log); err != nil { + return nil, err + } + event.Log = log + events[i] = *event + } + + return events, nil +} + +// WatchTransfer listens for on chain events binding the contract event 0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef. +// +// Solidity: event Transfer(address indexed _from, address indexed _to, uint256 _value) +func (_Energy *Energy) WatchTransfer(criteria []EnergyTransferCriteria, ctx context.Context) (chan *EnergyTransfer, error) { + topicHash := _Energy.contract.ABI.Events["Transfer"].ID + + criteriaSet := make([]client.EventCriteria, len(criteria)) + for i, c := range criteria { + crteria := client.EventCriteria{ + Address: &_Energy.contract.Address, + Topic0: &topicHash, + } + if c.From != nil { + matcher := *c.From + topics, err := abi.MakeTopics([]interface{}{matcher}) + if err != nil { + return nil, err + } + crteria.Topic1 = &topics[0][0] + } + if c.To != nil { + matcher := *c.To + topics, err := abi.MakeTopics([]interface{}{matcher}) + if err != nil { + return nil, err + } + crteria.Topic2 = &topics[0][0] + } + + criteriaSet[i] = crteria + } + + eventChan := make(chan *EnergyTransfer, 100) + blockSub := _Energy.thor.Blocks.Subscribe(ctx) + + go func() { + defer close(eventChan) + + for { + select { + case block := <-blockSub: + // for range in block txs + for _, tx := range block.Transactions { + for index, outputs := range tx.Outputs { + for _, event := range outputs.Events { + if event.Address != _Energy.contract.Address { + continue + } + if topicHash != event.Topics[0] { + continue + } + for _, c := range criteriaSet { + if c.Topic1 != nil && *c.Topic1 != event.Topics[1] { + continue + } + if c.Topic2 != nil && *c.Topic2 != event.Topics[2] { + continue + } + if c.Topic3 != nil && *c.Topic3 != event.Topics[3] { + continue + } + if c.Topic4 != nil && *c.Topic4 != event.Topics[4] { + continue + } + } + + log := client.EventLog{ + Address: &_Energy.contract.Address, + Topics: event.Topics, + Data: event.Data, + Meta: client.LogMeta{ + BlockID: block.ID, + BlockNumber: block.Number, + BlockTime: block.Timestamp, + TxID: tx.ID, + TxOrigin: tx.Origin, + ClauseIndex: int64(index), + }, + } + + ev := new(EnergyTransfer) + if err := _Energy.contract.UnpackLog(ev, "Transfer", log); err != nil { + continue + } + ev.Log = log + eventChan <- ev + } + } + } + case <-ctx.Done(): + return + } + } + }() + + return eventChan, nil +} diff --git a/builtins/energy_test.go b/builtins/energy_test.go new file mode 100644 index 0000000..52a142e --- /dev/null +++ b/builtins/energy_test.go @@ -0,0 +1,19 @@ +package builtins + +import ( + "testing" + + "github.com/darrenvechain/thorgo" + "github.com/stretchr/testify/assert" +) + +var thor = thorgo.New("https://mainnet.vechain.org") + +func TestEnergy(t *testing.T) { + energy, err := NewEnergy(thor) + assert.NoError(t, err) + + energyBal, err := energy.BalanceOf(energy.Address()) + assert.NoError(t, err) + assert.NotZero(t, energyBal) +} diff --git a/builtins/executor.go b/builtins/executor.go new file mode 100644 index 0000000..0dbc088 --- /dev/null +++ b/builtins/executor.go @@ -0,0 +1,896 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package builtins + +import ( + "context" + "errors" + "math/big" + "strings" + + "github.com/darrenvechain/thorgo" + "github.com/darrenvechain/thorgo/accounts" + "github.com/darrenvechain/thorgo/client" + "github.com/darrenvechain/thorgo/crypto/tx" + "github.com/darrenvechain/thorgo/transactions" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/hexutil" +) + +// Reference imports to suppress errors if they are not otherwise used. +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = bind.Bind + _ = common.Big1 + _ = abi.ConvertType + _ = hexutil.MustDecode + _ = context.Background + _ = tx.NewClause +) + +// ExecutorMetaData contains all meta data concerning the Executor contract. +var ExecutorMetaData = &bind.MetaData{ + ABI: "[{\"constant\":true,\"inputs\":[{\"name\":\"\",\"type\":\"address\"}],\"name\":\"approvers\",\"outputs\":[{\"name\":\"identity\",\"type\":\"bytes32\"},{\"name\":\"inPower\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"approverCount\",\"outputs\":[{\"name\":\"\",\"type\":\"uint8\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_approver\",\"type\":\"address\"}],\"name\":\"revokeApprover\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"proposals\",\"outputs\":[{\"name\":\"timeProposed\",\"type\":\"uint64\"},{\"name\":\"proposer\",\"type\":\"address\"},{\"name\":\"quorum\",\"type\":\"uint8\"},{\"name\":\"approvalCount\",\"type\":\"uint8\"},{\"name\":\"executed\",\"type\":\"bool\"},{\"name\":\"target\",\"type\":\"address\"},{\"name\":\"data\",\"type\":\"bytes\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_approver\",\"type\":\"address\"},{\"name\":\"_identity\",\"type\":\"bytes32\"}],\"name\":\"addApprover\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_target\",\"type\":\"address\"},{\"name\":\"_data\",\"type\":\"bytes\"}],\"name\":\"propose\",\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_contract\",\"type\":\"address\"}],\"name\":\"attachVotingContract\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_proposalID\",\"type\":\"bytes32\"}],\"name\":\"approve\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_contract\",\"type\":\"address\"}],\"name\":\"detachVotingContract\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_proposalID\",\"type\":\"bytes32\"}],\"name\":\"execute\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"\",\"type\":\"address\"}],\"name\":\"votingContracts\",\"outputs\":[{\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"name\":\"proposalID\",\"type\":\"bytes32\"},{\"indexed\":false,\"name\":\"action\",\"type\":\"bytes32\"}],\"name\":\"Proposal\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"name\":\"approver\",\"type\":\"address\"},{\"indexed\":false,\"name\":\"action\",\"type\":\"bytes32\"}],\"name\":\"Approver\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"name\":\"contractAddr\",\"type\":\"address\"},{\"indexed\":false,\"name\":\"action\",\"type\":\"bytes32\"}],\"name\":\"VotingContract\",\"type\":\"event\"}]", +} + +// Executor is an auto generated Go binding around an Ethereum contract, allowing you to query and create clauses. +type Executor struct { + thor *thorgo.Thor // Thor connection to use + contract *accounts.Contract // Generic contract wrapper for the low level calls +} + +// ExecutorTransactor is an auto generated Go binding around an Ethereum, allowing you to transact with the contract. +type ExecutorTransactor struct { + Executor + thor *thorgo.Thor // Thor connection to use + contract *accounts.Contract // Generic contract wrapper for the low level calls + manager accounts.TxManager // TxManager to use +} + +// NewExecutor creates a new instance of Executor, bound to a specific deployed contract. +func NewExecutor(thor *thorgo.Thor) (*Executor, error) { + parsed, err := ExecutorMetaData.GetAbi() + if err != nil { + return nil, err + } + contract := thor.Account(common.HexToAddress("0x0000000000000000000000004578656375746f72")).Contract(parsed) + if err != nil { + return nil, err + } + return &Executor{thor: thor, contract: contract}, nil +} + +// NewExecutorTransactor creates a new instance of ExecutorTransactor, bound to a specific deployed contract. +func NewExecutorTransactor(thor *thorgo.Thor, manager accounts.TxManager) (*ExecutorTransactor, error) { + parsed, err := ExecutorMetaData.GetAbi() + if err != nil { + return nil, err + } + contract := thor.Account(common.HexToAddress("0x0000000000000000000000004578656375746f72")).Contract(parsed) + if err != nil { + return nil, err + } + return &ExecutorTransactor{Executor{thor: thor, contract: contract}, thor, contract, manager}, nil +} + +// Address returns the address of the contract. +func (_Executor *Executor) Address() common.Address { + return _Executor.contract.Address +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_Executor *Executor) Call(revision client.Revision, result *[]interface{}, method string, params ...interface{}) error { + return _Executor.contract.Call(method, result, params...) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_ExecutorTransactor *ExecutorTransactor) Transact(vetValue *big.Int, method string, params ...interface{}) (*transactions.Visitor, error) { + return _ExecutorTransactor.contract.SendWithVET(_ExecutorTransactor.manager, vetValue, method, params...) +} + +// ApproverCount is a free data retrieval call binding the contract method 0x128e9be6. +// +// Solidity: function approverCount() view returns(uint8) +func (_Executor *Executor) ApproverCount(revision ...client.Revision) (uint8, error) { + var rev client.Revision + if len(revision) > 0 { + rev = revision[0] + } else { + rev = client.RevisionBest() + } + + var out []interface{} + err := _Executor.Call(rev, &out, "approverCount") + + if err != nil { + return *new(uint8), err + } + + out0 := *abi.ConvertType(out[0], new(uint8)).(*uint8) + + return out0, err +} + +// Approvers is a free data retrieval call binding the contract method 0x0a144391. +// +// Solidity: function approvers(address ) view returns(bytes32 identity, bool inPower) +func (_Executor *Executor) Approvers(arg0 common.Address, revision ...client.Revision) (struct { + Identity [32]byte + InPower bool +}, error) { + var rev client.Revision + if len(revision) > 0 { + rev = revision[0] + } else { + rev = client.RevisionBest() + } + + var out []interface{} + err := _Executor.Call(rev, &out, "approvers", arg0) + + outstruct := new(struct { + Identity [32]byte + InPower bool + }) + if err != nil { + return *outstruct, err + } + + outstruct.Identity = *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + outstruct.InPower = *abi.ConvertType(out[1], new(bool)).(*bool) + + return *outstruct, err + +} + +// Proposals is a free data retrieval call binding the contract method 0x32ed5b12. +// +// Solidity: function proposals(bytes32 ) view returns(uint64 timeProposed, address proposer, uint8 quorum, uint8 approvalCount, bool executed, address target, bytes data) +func (_Executor *Executor) Proposals(arg0 [32]byte, revision ...client.Revision) (struct { + TimeProposed uint64 + Proposer common.Address + Quorum uint8 + ApprovalCount uint8 + Executed bool + Target common.Address + Data []byte +}, error) { + var rev client.Revision + if len(revision) > 0 { + rev = revision[0] + } else { + rev = client.RevisionBest() + } + + var out []interface{} + err := _Executor.Call(rev, &out, "proposals", arg0) + + outstruct := new(struct { + TimeProposed uint64 + Proposer common.Address + Quorum uint8 + ApprovalCount uint8 + Executed bool + Target common.Address + Data []byte + }) + if err != nil { + return *outstruct, err + } + + outstruct.TimeProposed = *abi.ConvertType(out[0], new(uint64)).(*uint64) + outstruct.Proposer = *abi.ConvertType(out[1], new(common.Address)).(*common.Address) + outstruct.Quorum = *abi.ConvertType(out[2], new(uint8)).(*uint8) + outstruct.ApprovalCount = *abi.ConvertType(out[3], new(uint8)).(*uint8) + outstruct.Executed = *abi.ConvertType(out[4], new(bool)).(*bool) + outstruct.Target = *abi.ConvertType(out[5], new(common.Address)).(*common.Address) + outstruct.Data = *abi.ConvertType(out[6], new([]byte)).(*[]byte) + + return *outstruct, err + +} + +// VotingContracts is a free data retrieval call binding the contract method 0xfa06792b. +// +// Solidity: function votingContracts(address ) view returns(bool) +func (_Executor *Executor) VotingContracts(arg0 common.Address, revision ...client.Revision) (bool, error) { + var rev client.Revision + if len(revision) > 0 { + rev = revision[0] + } else { + rev = client.RevisionBest() + } + + var out []interface{} + err := _Executor.Call(rev, &out, "votingContracts", arg0) + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err +} + +// AddApprover is a paid mutator transaction binding the contract method 0x3ef0c09e. +// +// Solidity: function addApprover(address _approver, bytes32 _identity) returns() +func (_ExecutorTransactor *ExecutorTransactor) AddApprover(_approver common.Address, _identity [32]byte, vetValue ...*big.Int) (*transactions.Visitor, error) { + var val *big.Int + if len(vetValue) > 0 { + val = vetValue[0] + } else { + val = big.NewInt(0) + } + return _ExecutorTransactor.Transact(val, "addApprover", _approver, _identity) +} + +// AddApproverAsClause is a transaction clause generator 0x3ef0c09e. +// +// Solidity: function addApprover(address _approver, bytes32 _identity) returns() +func (_Executor *Executor) AddApproverAsClause(_approver common.Address, _identity [32]byte, vetValue ...*big.Int) (*tx.Clause, error) { + var val *big.Int + if len(vetValue) > 0 { + val = vetValue[0] + } else { + val = big.NewInt(0) + } + return _Executor.contract.AsClauseWithVET(val, "addApprover", _approver, _identity) +} + +// Approve is a paid mutator transaction binding the contract method 0xa53a1adf. +// +// Solidity: function approve(bytes32 _proposalID) returns() +func (_ExecutorTransactor *ExecutorTransactor) Approve(_proposalID [32]byte, vetValue ...*big.Int) (*transactions.Visitor, error) { + var val *big.Int + if len(vetValue) > 0 { + val = vetValue[0] + } else { + val = big.NewInt(0) + } + return _ExecutorTransactor.Transact(val, "approve", _proposalID) +} + +// ApproveAsClause is a transaction clause generator 0xa53a1adf. +// +// Solidity: function approve(bytes32 _proposalID) returns() +func (_Executor *Executor) ApproveAsClause(_proposalID [32]byte, vetValue ...*big.Int) (*tx.Clause, error) { + var val *big.Int + if len(vetValue) > 0 { + val = vetValue[0] + } else { + val = big.NewInt(0) + } + return _Executor.contract.AsClauseWithVET(val, "approve", _proposalID) +} + +// AttachVotingContract is a paid mutator transaction binding the contract method 0xa1fb668f. +// +// Solidity: function attachVotingContract(address _contract) returns() +func (_ExecutorTransactor *ExecutorTransactor) AttachVotingContract(_contract common.Address, vetValue ...*big.Int) (*transactions.Visitor, error) { + var val *big.Int + if len(vetValue) > 0 { + val = vetValue[0] + } else { + val = big.NewInt(0) + } + return _ExecutorTransactor.Transact(val, "attachVotingContract", _contract) +} + +// AttachVotingContractAsClause is a transaction clause generator 0xa1fb668f. +// +// Solidity: function attachVotingContract(address _contract) returns() +func (_Executor *Executor) AttachVotingContractAsClause(_contract common.Address, vetValue ...*big.Int) (*tx.Clause, error) { + var val *big.Int + if len(vetValue) > 0 { + val = vetValue[0] + } else { + val = big.NewInt(0) + } + return _Executor.contract.AsClauseWithVET(val, "attachVotingContract", _contract) +} + +// DetachVotingContract is a paid mutator transaction binding the contract method 0xa83b3bd8. +// +// Solidity: function detachVotingContract(address _contract) returns() +func (_ExecutorTransactor *ExecutorTransactor) DetachVotingContract(_contract common.Address, vetValue ...*big.Int) (*transactions.Visitor, error) { + var val *big.Int + if len(vetValue) > 0 { + val = vetValue[0] + } else { + val = big.NewInt(0) + } + return _ExecutorTransactor.Transact(val, "detachVotingContract", _contract) +} + +// DetachVotingContractAsClause is a transaction clause generator 0xa83b3bd8. +// +// Solidity: function detachVotingContract(address _contract) returns() +func (_Executor *Executor) DetachVotingContractAsClause(_contract common.Address, vetValue ...*big.Int) (*tx.Clause, error) { + var val *big.Int + if len(vetValue) > 0 { + val = vetValue[0] + } else { + val = big.NewInt(0) + } + return _Executor.contract.AsClauseWithVET(val, "detachVotingContract", _contract) +} + +// Execute is a paid mutator transaction binding the contract method 0xe751f271. +// +// Solidity: function execute(bytes32 _proposalID) returns() +func (_ExecutorTransactor *ExecutorTransactor) Execute(_proposalID [32]byte, vetValue ...*big.Int) (*transactions.Visitor, error) { + var val *big.Int + if len(vetValue) > 0 { + val = vetValue[0] + } else { + val = big.NewInt(0) + } + return _ExecutorTransactor.Transact(val, "execute", _proposalID) +} + +// ExecuteAsClause is a transaction clause generator 0xe751f271. +// +// Solidity: function execute(bytes32 _proposalID) returns() +func (_Executor *Executor) ExecuteAsClause(_proposalID [32]byte, vetValue ...*big.Int) (*tx.Clause, error) { + var val *big.Int + if len(vetValue) > 0 { + val = vetValue[0] + } else { + val = big.NewInt(0) + } + return _Executor.contract.AsClauseWithVET(val, "execute", _proposalID) +} + +// Propose is a paid mutator transaction binding the contract method 0x9d481848. +// +// Solidity: function propose(address _target, bytes _data) returns(bytes32) +func (_ExecutorTransactor *ExecutorTransactor) Propose(_target common.Address, _data []byte, vetValue ...*big.Int) (*transactions.Visitor, error) { + var val *big.Int + if len(vetValue) > 0 { + val = vetValue[0] + } else { + val = big.NewInt(0) + } + return _ExecutorTransactor.Transact(val, "propose", _target, _data) +} + +// ProposeAsClause is a transaction clause generator 0x9d481848. +// +// Solidity: function propose(address _target, bytes _data) returns(bytes32) +func (_Executor *Executor) ProposeAsClause(_target common.Address, _data []byte, vetValue ...*big.Int) (*tx.Clause, error) { + var val *big.Int + if len(vetValue) > 0 { + val = vetValue[0] + } else { + val = big.NewInt(0) + } + return _Executor.contract.AsClauseWithVET(val, "propose", _target, _data) +} + +// RevokeApprover is a paid mutator transaction binding the contract method 0x18d13ef7. +// +// Solidity: function revokeApprover(address _approver) returns() +func (_ExecutorTransactor *ExecutorTransactor) RevokeApprover(_approver common.Address, vetValue ...*big.Int) (*transactions.Visitor, error) { + var val *big.Int + if len(vetValue) > 0 { + val = vetValue[0] + } else { + val = big.NewInt(0) + } + return _ExecutorTransactor.Transact(val, "revokeApprover", _approver) +} + +// RevokeApproverAsClause is a transaction clause generator 0x18d13ef7. +// +// Solidity: function revokeApprover(address _approver) returns() +func (_Executor *Executor) RevokeApproverAsClause(_approver common.Address, vetValue ...*big.Int) (*tx.Clause, error) { + var val *big.Int + if len(vetValue) > 0 { + val = vetValue[0] + } else { + val = big.NewInt(0) + } + return _Executor.contract.AsClauseWithVET(val, "revokeApprover", _approver) +} + +// ExecutorApprover represents a Approver event raised by the Executor contract. +type ExecutorApprover struct { + Approver common.Address + Action [32]byte + Log client.EventLog +} + +type ExecutorApproverCriteria struct { + Approver *common.Address `abi:"approver"` +} + +// FilterApprover is a free log retrieval operation binding the contract event 0x770115cde75e60f17b265d7e0c5e39c57abf243bc316c7e5c2f8d851771da6ac. +// +// Solidity: event Approver(address indexed approver, bytes32 action) +func (_Executor *Executor) FilterApprover(criteria []ExecutorApproverCriteria, opts *client.FilterOptions, rang *client.FilterRange) ([]ExecutorApprover, error) { + topicHash := _Executor.contract.ABI.Events["Approver"].ID + + criteriaSet := make([]client.EventCriteria, len(criteria)) + for i, c := range criteria { + crteria := client.EventCriteria{ + Address: &_Executor.contract.Address, + Topic0: &topicHash, + } + if c.Approver != nil { + matcher := *c.Approver + topics, err := abi.MakeTopics([]interface{}{matcher}) + if err != nil { + return nil, err + } + crteria.Topic1 = &topics[0][0] + } + + criteriaSet[i] = crteria + } + + if len(criteriaSet) == 0 { + criteriaSet = append(criteriaSet, client.EventCriteria{ + Address: &_Executor.contract.Address, + Topic0: &topicHash, // Add Topic0 here + }) + } + + filter := &client.EventFilter{ + Range: rang, + Options: opts, + Criteria: &criteriaSet, + } + + logs, err := _Executor.thor.Client.FilterEvents(filter) + if err != nil { + return nil, err + } + + inputs := _Executor.contract.ABI.Events["Approver"].Inputs + var indexed abi.Arguments + for _, arg := range inputs { + if arg.Indexed { + indexed = append(indexed, arg) + } + } + + events := make([]ExecutorApprover, len(logs)) + for i, log := range logs { + event := new(ExecutorApprover) + if err := _Executor.contract.UnpackLog(event, "Approver", log); err != nil { + return nil, err + } + event.Log = log + events[i] = *event + } + + return events, nil +} + +// WatchApprover listens for on chain events binding the contract event 0x770115cde75e60f17b265d7e0c5e39c57abf243bc316c7e5c2f8d851771da6ac. +// +// Solidity: event Approver(address indexed approver, bytes32 action) +func (_Executor *Executor) WatchApprover(criteria []ExecutorApproverCriteria, ctx context.Context) (chan *ExecutorApprover, error) { + topicHash := _Executor.contract.ABI.Events["Approver"].ID + + criteriaSet := make([]client.EventCriteria, len(criteria)) + for i, c := range criteria { + crteria := client.EventCriteria{ + Address: &_Executor.contract.Address, + Topic0: &topicHash, + } + if c.Approver != nil { + matcher := *c.Approver + topics, err := abi.MakeTopics([]interface{}{matcher}) + if err != nil { + return nil, err + } + crteria.Topic1 = &topics[0][0] + } + + criteriaSet[i] = crteria + } + + eventChan := make(chan *ExecutorApprover, 100) + blockSub := _Executor.thor.Blocks.Subscribe(ctx) + + go func() { + defer close(eventChan) + + for { + select { + case block := <-blockSub: + // for range in block txs + for _, tx := range block.Transactions { + for index, outputs := range tx.Outputs { + for _, event := range outputs.Events { + if event.Address != _Executor.contract.Address { + continue + } + if topicHash != event.Topics[0] { + continue + } + for _, c := range criteriaSet { + if c.Topic1 != nil && *c.Topic1 != event.Topics[1] { + continue + } + if c.Topic2 != nil && *c.Topic2 != event.Topics[2] { + continue + } + if c.Topic3 != nil && *c.Topic3 != event.Topics[3] { + continue + } + if c.Topic4 != nil && *c.Topic4 != event.Topics[4] { + continue + } + } + + log := client.EventLog{ + Address: &_Executor.contract.Address, + Topics: event.Topics, + Data: event.Data, + Meta: client.LogMeta{ + BlockID: block.ID, + BlockNumber: block.Number, + BlockTime: block.Timestamp, + TxID: tx.ID, + TxOrigin: tx.Origin, + ClauseIndex: int64(index), + }, + } + + ev := new(ExecutorApprover) + if err := _Executor.contract.UnpackLog(ev, "Approver", log); err != nil { + continue + } + ev.Log = log + eventChan <- ev + } + } + } + case <-ctx.Done(): + return + } + } + }() + + return eventChan, nil +} + +// ExecutorProposal represents a Proposal event raised by the Executor contract. +type ExecutorProposal struct { + ProposalID [32]byte + Action [32]byte + Log client.EventLog +} + +type ExecutorProposalCriteria struct { + ProposalID *[32]byte `abi:"proposalID"` +} + +// FilterProposal is a free log retrieval operation binding the contract event 0x7d9bcf5c6cdade398a64a03053a982851ccea20dc827dbc130754b9e78c7c31a. +// +// Solidity: event Proposal(bytes32 indexed proposalID, bytes32 action) +func (_Executor *Executor) FilterProposal(criteria []ExecutorProposalCriteria, opts *client.FilterOptions, rang *client.FilterRange) ([]ExecutorProposal, error) { + topicHash := _Executor.contract.ABI.Events["Proposal"].ID + + criteriaSet := make([]client.EventCriteria, len(criteria)) + for i, c := range criteria { + crteria := client.EventCriteria{ + Address: &_Executor.contract.Address, + Topic0: &topicHash, + } + if c.ProposalID != nil { + matcher := *c.ProposalID + topics, err := abi.MakeTopics([]interface{}{matcher}) + if err != nil { + return nil, err + } + crteria.Topic1 = &topics[0][0] + } + + criteriaSet[i] = crteria + } + + if len(criteriaSet) == 0 { + criteriaSet = append(criteriaSet, client.EventCriteria{ + Address: &_Executor.contract.Address, + Topic0: &topicHash, // Add Topic0 here + }) + } + + filter := &client.EventFilter{ + Range: rang, + Options: opts, + Criteria: &criteriaSet, + } + + logs, err := _Executor.thor.Client.FilterEvents(filter) + if err != nil { + return nil, err + } + + inputs := _Executor.contract.ABI.Events["Proposal"].Inputs + var indexed abi.Arguments + for _, arg := range inputs { + if arg.Indexed { + indexed = append(indexed, arg) + } + } + + events := make([]ExecutorProposal, len(logs)) + for i, log := range logs { + event := new(ExecutorProposal) + if err := _Executor.contract.UnpackLog(event, "Proposal", log); err != nil { + return nil, err + } + event.Log = log + events[i] = *event + } + + return events, nil +} + +// WatchProposal listens for on chain events binding the contract event 0x7d9bcf5c6cdade398a64a03053a982851ccea20dc827dbc130754b9e78c7c31a. +// +// Solidity: event Proposal(bytes32 indexed proposalID, bytes32 action) +func (_Executor *Executor) WatchProposal(criteria []ExecutorProposalCriteria, ctx context.Context) (chan *ExecutorProposal, error) { + topicHash := _Executor.contract.ABI.Events["Proposal"].ID + + criteriaSet := make([]client.EventCriteria, len(criteria)) + for i, c := range criteria { + crteria := client.EventCriteria{ + Address: &_Executor.contract.Address, + Topic0: &topicHash, + } + if c.ProposalID != nil { + matcher := *c.ProposalID + topics, err := abi.MakeTopics([]interface{}{matcher}) + if err != nil { + return nil, err + } + crteria.Topic1 = &topics[0][0] + } + + criteriaSet[i] = crteria + } + + eventChan := make(chan *ExecutorProposal, 100) + blockSub := _Executor.thor.Blocks.Subscribe(ctx) + + go func() { + defer close(eventChan) + + for { + select { + case block := <-blockSub: + // for range in block txs + for _, tx := range block.Transactions { + for index, outputs := range tx.Outputs { + for _, event := range outputs.Events { + if event.Address != _Executor.contract.Address { + continue + } + if topicHash != event.Topics[0] { + continue + } + for _, c := range criteriaSet { + if c.Topic1 != nil && *c.Topic1 != event.Topics[1] { + continue + } + if c.Topic2 != nil && *c.Topic2 != event.Topics[2] { + continue + } + if c.Topic3 != nil && *c.Topic3 != event.Topics[3] { + continue + } + if c.Topic4 != nil && *c.Topic4 != event.Topics[4] { + continue + } + } + + log := client.EventLog{ + Address: &_Executor.contract.Address, + Topics: event.Topics, + Data: event.Data, + Meta: client.LogMeta{ + BlockID: block.ID, + BlockNumber: block.Number, + BlockTime: block.Timestamp, + TxID: tx.ID, + TxOrigin: tx.Origin, + ClauseIndex: int64(index), + }, + } + + ev := new(ExecutorProposal) + if err := _Executor.contract.UnpackLog(ev, "Proposal", log); err != nil { + continue + } + ev.Log = log + eventChan <- ev + } + } + } + case <-ctx.Done(): + return + } + } + }() + + return eventChan, nil +} + +// ExecutorVotingContract represents a VotingContract event raised by the Executor contract. +type ExecutorVotingContract struct { + ContractAddr common.Address + Action [32]byte + Log client.EventLog +} + +type ExecutorVotingContractCriteria struct { + ContractAddr *common.Address `abi:"contractAddr"` +} + +// FilterVotingContract is a free log retrieval operation binding the contract event 0xf4cb5443be666f872bc8a75293e99e2204a6573e5eb3d2d485d866f2e13c7ea4. +// +// Solidity: event VotingContract(address indexed contractAddr, bytes32 action) +func (_Executor *Executor) FilterVotingContract(criteria []ExecutorVotingContractCriteria, opts *client.FilterOptions, rang *client.FilterRange) ([]ExecutorVotingContract, error) { + topicHash := _Executor.contract.ABI.Events["VotingContract"].ID + + criteriaSet := make([]client.EventCriteria, len(criteria)) + for i, c := range criteria { + crteria := client.EventCriteria{ + Address: &_Executor.contract.Address, + Topic0: &topicHash, + } + if c.ContractAddr != nil { + matcher := *c.ContractAddr + topics, err := abi.MakeTopics([]interface{}{matcher}) + if err != nil { + return nil, err + } + crteria.Topic1 = &topics[0][0] + } + + criteriaSet[i] = crteria + } + + if len(criteriaSet) == 0 { + criteriaSet = append(criteriaSet, client.EventCriteria{ + Address: &_Executor.contract.Address, + Topic0: &topicHash, // Add Topic0 here + }) + } + + filter := &client.EventFilter{ + Range: rang, + Options: opts, + Criteria: &criteriaSet, + } + + logs, err := _Executor.thor.Client.FilterEvents(filter) + if err != nil { + return nil, err + } + + inputs := _Executor.contract.ABI.Events["VotingContract"].Inputs + var indexed abi.Arguments + for _, arg := range inputs { + if arg.Indexed { + indexed = append(indexed, arg) + } + } + + events := make([]ExecutorVotingContract, len(logs)) + for i, log := range logs { + event := new(ExecutorVotingContract) + if err := _Executor.contract.UnpackLog(event, "VotingContract", log); err != nil { + return nil, err + } + event.Log = log + events[i] = *event + } + + return events, nil +} + +// WatchVotingContract listens for on chain events binding the contract event 0xf4cb5443be666f872bc8a75293e99e2204a6573e5eb3d2d485d866f2e13c7ea4. +// +// Solidity: event VotingContract(address indexed contractAddr, bytes32 action) +func (_Executor *Executor) WatchVotingContract(criteria []ExecutorVotingContractCriteria, ctx context.Context) (chan *ExecutorVotingContract, error) { + topicHash := _Executor.contract.ABI.Events["VotingContract"].ID + + criteriaSet := make([]client.EventCriteria, len(criteria)) + for i, c := range criteria { + crteria := client.EventCriteria{ + Address: &_Executor.contract.Address, + Topic0: &topicHash, + } + if c.ContractAddr != nil { + matcher := *c.ContractAddr + topics, err := abi.MakeTopics([]interface{}{matcher}) + if err != nil { + return nil, err + } + crteria.Topic1 = &topics[0][0] + } + + criteriaSet[i] = crteria + } + + eventChan := make(chan *ExecutorVotingContract, 100) + blockSub := _Executor.thor.Blocks.Subscribe(ctx) + + go func() { + defer close(eventChan) + + for { + select { + case block := <-blockSub: + // for range in block txs + for _, tx := range block.Transactions { + for index, outputs := range tx.Outputs { + for _, event := range outputs.Events { + if event.Address != _Executor.contract.Address { + continue + } + if topicHash != event.Topics[0] { + continue + } + for _, c := range criteriaSet { + if c.Topic1 != nil && *c.Topic1 != event.Topics[1] { + continue + } + if c.Topic2 != nil && *c.Topic2 != event.Topics[2] { + continue + } + if c.Topic3 != nil && *c.Topic3 != event.Topics[3] { + continue + } + if c.Topic4 != nil && *c.Topic4 != event.Topics[4] { + continue + } + } + + log := client.EventLog{ + Address: &_Executor.contract.Address, + Topics: event.Topics, + Data: event.Data, + Meta: client.LogMeta{ + BlockID: block.ID, + BlockNumber: block.Number, + BlockTime: block.Timestamp, + TxID: tx.ID, + TxOrigin: tx.Origin, + ClauseIndex: int64(index), + }, + } + + ev := new(ExecutorVotingContract) + if err := _Executor.contract.UnpackLog(ev, "VotingContract", log); err != nil { + continue + } + ev.Log = log + eventChan <- ev + } + } + } + case <-ctx.Done(): + return + } + } + }() + + return eventChan, nil +} diff --git a/builtins/extension.go b/builtins/extension.go new file mode 100644 index 0000000..226419f --- /dev/null +++ b/builtins/extension.go @@ -0,0 +1,726 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package builtins + +import ( + "context" + "errors" + "math/big" + "strings" + + "github.com/darrenvechain/thorgo" + "github.com/darrenvechain/thorgo/accounts" + "github.com/darrenvechain/thorgo/client" + "github.com/darrenvechain/thorgo/crypto/tx" + "github.com/darrenvechain/thorgo/transactions" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/hexutil" +) + +// Reference imports to suppress errors if they are not otherwise used. +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = bind.Bind + _ = common.Big1 + _ = abi.ConvertType + _ = hexutil.MustDecode + _ = context.Background + _ = tx.NewClause +) + +// ExtensionMetaData contains all meta data concerning the Extension contract. +var ExtensionMetaData = &bind.MetaData{ + ABI: "[{\"constant\":true,\"inputs\":[],\"name\":\"name\",\"outputs\":[{\"name\":\"\",\"type\":\"string\"}],\"payable\":false,\"stateMutability\":\"pure\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_spender\",\"type\":\"address\"},{\"name\":\"_value\",\"type\":\"uint256\"}],\"name\":\"approve\",\"outputs\":[{\"name\":\"success\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"totalSupply\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_from\",\"type\":\"address\"},{\"name\":\"_to\",\"type\":\"address\"},{\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"transferFrom\",\"outputs\":[{\"name\":\"success\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"decimals\",\"outputs\":[{\"name\":\"\",\"type\":\"uint8\"}],\"payable\":false,\"stateMutability\":\"pure\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"_owner\",\"type\":\"address\"}],\"name\":\"balanceOf\",\"outputs\":[{\"name\":\"balance\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"symbol\",\"outputs\":[{\"name\":\"\",\"type\":\"string\"}],\"payable\":false,\"stateMutability\":\"pure\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_to\",\"type\":\"address\"},{\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"transfer\",\"outputs\":[{\"name\":\"success\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_from\",\"type\":\"address\"},{\"name\":\"_to\",\"type\":\"address\"},{\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"move\",\"outputs\":[{\"name\":\"success\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"totalBurned\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"_owner\",\"type\":\"address\"},{\"name\":\"_spender\",\"type\":\"address\"}],\"name\":\"allowance\",\"outputs\":[{\"name\":\"remaining\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"name\":\"_from\",\"type\":\"address\"},{\"indexed\":true,\"name\":\"_to\",\"type\":\"address\"},{\"indexed\":false,\"name\":\"_value\",\"type\":\"uint256\"}],\"name\":\"Transfer\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"name\":\"_owner\",\"type\":\"address\"},{\"indexed\":true,\"name\":\"_spender\",\"type\":\"address\"},{\"indexed\":false,\"name\":\"_value\",\"type\":\"uint256\"}],\"name\":\"Approval\",\"type\":\"event\"}]", +} + +// Extension is an auto generated Go binding around an Ethereum contract, allowing you to query and create clauses. +type Extension struct { + thor *thorgo.Thor // Thor connection to use + contract *accounts.Contract // Generic contract wrapper for the low level calls +} + +// ExtensionTransactor is an auto generated Go binding around an Ethereum, allowing you to transact with the contract. +type ExtensionTransactor struct { + Extension + thor *thorgo.Thor // Thor connection to use + contract *accounts.Contract // Generic contract wrapper for the low level calls + manager accounts.TxManager // TxManager to use +} + +// NewExtension creates a new instance of Extension, bound to a specific deployed contract. +func NewExtension(thor *thorgo.Thor) (*Extension, error) { + parsed, err := ExtensionMetaData.GetAbi() + if err != nil { + return nil, err + } + contract := thor.Account(common.HexToAddress("0x0000000000000000000000457874656e73696f6e")).Contract(parsed) + if err != nil { + return nil, err + } + return &Extension{thor: thor, contract: contract}, nil +} + +// NewExtensionTransactor creates a new instance of ExtensionTransactor, bound to a specific deployed contract. +func NewExtensionTransactor(thor *thorgo.Thor, manager accounts.TxManager) (*ExtensionTransactor, error) { + parsed, err := ExtensionMetaData.GetAbi() + if err != nil { + return nil, err + } + contract := thor.Account(common.HexToAddress("0x0000000000000000000000457874656e73696f6e")).Contract(parsed) + if err != nil { + return nil, err + } + return &ExtensionTransactor{Extension{thor: thor, contract: contract}, thor, contract, manager}, nil +} + +// Address returns the address of the contract. +func (_Extension *Extension) Address() common.Address { + return _Extension.contract.Address +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_Extension *Extension) Call(revision client.Revision, result *[]interface{}, method string, params ...interface{}) error { + return _Extension.contract.Call(method, result, params...) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_ExtensionTransactor *ExtensionTransactor) Transact(vetValue *big.Int, method string, params ...interface{}) (*transactions.Visitor, error) { + return _ExtensionTransactor.contract.SendWithVET(_ExtensionTransactor.manager, vetValue, method, params...) +} + +// Allowance is a free data retrieval call binding the contract method 0xdd62ed3e. +// +// Solidity: function allowance(address _owner, address _spender) view returns(uint256 remaining) +func (_Extension *Extension) Allowance(_owner common.Address, _spender common.Address, revision ...client.Revision) (*big.Int, error) { + var rev client.Revision + if len(revision) > 0 { + rev = revision[0] + } else { + rev = client.RevisionBest() + } + + var out []interface{} + err := _Extension.Call(rev, &out, "allowance", _owner, _spender) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err +} + +// BalanceOf is a free data retrieval call binding the contract method 0x70a08231. +// +// Solidity: function balanceOf(address _owner) view returns(uint256 balance) +func (_Extension *Extension) BalanceOf(_owner common.Address, revision ...client.Revision) (*big.Int, error) { + var rev client.Revision + if len(revision) > 0 { + rev = revision[0] + } else { + rev = client.RevisionBest() + } + + var out []interface{} + err := _Extension.Call(rev, &out, "balanceOf", _owner) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err +} + +// Decimals is a free data retrieval call binding the contract method 0x313ce567. +// +// Solidity: function decimals() pure returns(uint8) +func (_Extension *Extension) Decimals(revision ...client.Revision) (uint8, error) { + var rev client.Revision + if len(revision) > 0 { + rev = revision[0] + } else { + rev = client.RevisionBest() + } + + var out []interface{} + err := _Extension.Call(rev, &out, "decimals") + + if err != nil { + return *new(uint8), err + } + + out0 := *abi.ConvertType(out[0], new(uint8)).(*uint8) + + return out0, err +} + +// Name is a free data retrieval call binding the contract method 0x06fdde03. +// +// Solidity: function name() pure returns(string) +func (_Extension *Extension) Name(revision ...client.Revision) (string, error) { + var rev client.Revision + if len(revision) > 0 { + rev = revision[0] + } else { + rev = client.RevisionBest() + } + + var out []interface{} + err := _Extension.Call(rev, &out, "name") + + if err != nil { + return *new(string), err + } + + out0 := *abi.ConvertType(out[0], new(string)).(*string) + + return out0, err +} + +// Symbol is a free data retrieval call binding the contract method 0x95d89b41. +// +// Solidity: function symbol() pure returns(string) +func (_Extension *Extension) Symbol(revision ...client.Revision) (string, error) { + var rev client.Revision + if len(revision) > 0 { + rev = revision[0] + } else { + rev = client.RevisionBest() + } + + var out []interface{} + err := _Extension.Call(rev, &out, "symbol") + + if err != nil { + return *new(string), err + } + + out0 := *abi.ConvertType(out[0], new(string)).(*string) + + return out0, err +} + +// TotalBurned is a free data retrieval call binding the contract method 0xd89135cd. +// +// Solidity: function totalBurned() view returns(uint256) +func (_Extension *Extension) TotalBurned(revision ...client.Revision) (*big.Int, error) { + var rev client.Revision + if len(revision) > 0 { + rev = revision[0] + } else { + rev = client.RevisionBest() + } + + var out []interface{} + err := _Extension.Call(rev, &out, "totalBurned") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err +} + +// TotalSupply is a free data retrieval call binding the contract method 0x18160ddd. +// +// Solidity: function totalSupply() view returns(uint256) +func (_Extension *Extension) TotalSupply(revision ...client.Revision) (*big.Int, error) { + var rev client.Revision + if len(revision) > 0 { + rev = revision[0] + } else { + rev = client.RevisionBest() + } + + var out []interface{} + err := _Extension.Call(rev, &out, "totalSupply") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err +} + +// Approve is a paid mutator transaction binding the contract method 0x095ea7b3. +// +// Solidity: function approve(address _spender, uint256 _value) returns(bool success) +func (_ExtensionTransactor *ExtensionTransactor) Approve(_spender common.Address, _value *big.Int, vetValue ...*big.Int) (*transactions.Visitor, error) { + var val *big.Int + if len(vetValue) > 0 { + val = vetValue[0] + } else { + val = big.NewInt(0) + } + return _ExtensionTransactor.Transact(val, "approve", _spender, _value) +} + +// ApproveAsClause is a transaction clause generator 0x095ea7b3. +// +// Solidity: function approve(address _spender, uint256 _value) returns(bool success) +func (_Extension *Extension) ApproveAsClause(_spender common.Address, _value *big.Int, vetValue ...*big.Int) (*tx.Clause, error) { + var val *big.Int + if len(vetValue) > 0 { + val = vetValue[0] + } else { + val = big.NewInt(0) + } + return _Extension.contract.AsClauseWithVET(val, "approve", _spender, _value) +} + +// Move is a paid mutator transaction binding the contract method 0xbb35783b. +// +// Solidity: function move(address _from, address _to, uint256 _amount) returns(bool success) +func (_ExtensionTransactor *ExtensionTransactor) Move(_from common.Address, _to common.Address, _amount *big.Int, vetValue ...*big.Int) (*transactions.Visitor, error) { + var val *big.Int + if len(vetValue) > 0 { + val = vetValue[0] + } else { + val = big.NewInt(0) + } + return _ExtensionTransactor.Transact(val, "move", _from, _to, _amount) +} + +// MoveAsClause is a transaction clause generator 0xbb35783b. +// +// Solidity: function move(address _from, address _to, uint256 _amount) returns(bool success) +func (_Extension *Extension) MoveAsClause(_from common.Address, _to common.Address, _amount *big.Int, vetValue ...*big.Int) (*tx.Clause, error) { + var val *big.Int + if len(vetValue) > 0 { + val = vetValue[0] + } else { + val = big.NewInt(0) + } + return _Extension.contract.AsClauseWithVET(val, "move", _from, _to, _amount) +} + +// Transfer is a paid mutator transaction binding the contract method 0xa9059cbb. +// +// Solidity: function transfer(address _to, uint256 _amount) returns(bool success) +func (_ExtensionTransactor *ExtensionTransactor) Transfer(_to common.Address, _amount *big.Int, vetValue ...*big.Int) (*transactions.Visitor, error) { + var val *big.Int + if len(vetValue) > 0 { + val = vetValue[0] + } else { + val = big.NewInt(0) + } + return _ExtensionTransactor.Transact(val, "transfer", _to, _amount) +} + +// TransferAsClause is a transaction clause generator 0xa9059cbb. +// +// Solidity: function transfer(address _to, uint256 _amount) returns(bool success) +func (_Extension *Extension) TransferAsClause(_to common.Address, _amount *big.Int, vetValue ...*big.Int) (*tx.Clause, error) { + var val *big.Int + if len(vetValue) > 0 { + val = vetValue[0] + } else { + val = big.NewInt(0) + } + return _Extension.contract.AsClauseWithVET(val, "transfer", _to, _amount) +} + +// TransferFrom is a paid mutator transaction binding the contract method 0x23b872dd. +// +// Solidity: function transferFrom(address _from, address _to, uint256 _amount) returns(bool success) +func (_ExtensionTransactor *ExtensionTransactor) TransferFrom(_from common.Address, _to common.Address, _amount *big.Int, vetValue ...*big.Int) (*transactions.Visitor, error) { + var val *big.Int + if len(vetValue) > 0 { + val = vetValue[0] + } else { + val = big.NewInt(0) + } + return _ExtensionTransactor.Transact(val, "transferFrom", _from, _to, _amount) +} + +// TransferFromAsClause is a transaction clause generator 0x23b872dd. +// +// Solidity: function transferFrom(address _from, address _to, uint256 _amount) returns(bool success) +func (_Extension *Extension) TransferFromAsClause(_from common.Address, _to common.Address, _amount *big.Int, vetValue ...*big.Int) (*tx.Clause, error) { + var val *big.Int + if len(vetValue) > 0 { + val = vetValue[0] + } else { + val = big.NewInt(0) + } + return _Extension.contract.AsClauseWithVET(val, "transferFrom", _from, _to, _amount) +} + +// ExtensionApproval represents a Approval event raised by the Extension contract. +type ExtensionApproval struct { + Owner common.Address + Spender common.Address + Value *big.Int + Log client.EventLog +} + +type ExtensionApprovalCriteria struct { + Owner *common.Address `abi:"_owner"` + Spender *common.Address `abi:"_spender"` +} + +// FilterApproval is a free log retrieval operation binding the contract event 0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925. +// +// Solidity: event Approval(address indexed _owner, address indexed _spender, uint256 _value) +func (_Extension *Extension) FilterApproval(criteria []ExtensionApprovalCriteria, opts *client.FilterOptions, rang *client.FilterRange) ([]ExtensionApproval, error) { + topicHash := _Extension.contract.ABI.Events["Approval"].ID + + criteriaSet := make([]client.EventCriteria, len(criteria)) + for i, c := range criteria { + crteria := client.EventCriteria{ + Address: &_Extension.contract.Address, + Topic0: &topicHash, + } + if c.Owner != nil { + matcher := *c.Owner + topics, err := abi.MakeTopics([]interface{}{matcher}) + if err != nil { + return nil, err + } + crteria.Topic1 = &topics[0][0] + } + if c.Spender != nil { + matcher := *c.Spender + topics, err := abi.MakeTopics([]interface{}{matcher}) + if err != nil { + return nil, err + } + crteria.Topic2 = &topics[0][0] + } + + criteriaSet[i] = crteria + } + + if len(criteriaSet) == 0 { + criteriaSet = append(criteriaSet, client.EventCriteria{ + Address: &_Extension.contract.Address, + Topic0: &topicHash, // Add Topic0 here + }) + } + + filter := &client.EventFilter{ + Range: rang, + Options: opts, + Criteria: &criteriaSet, + } + + logs, err := _Extension.thor.Client.FilterEvents(filter) + if err != nil { + return nil, err + } + + inputs := _Extension.contract.ABI.Events["Approval"].Inputs + var indexed abi.Arguments + for _, arg := range inputs { + if arg.Indexed { + indexed = append(indexed, arg) + } + } + + events := make([]ExtensionApproval, len(logs)) + for i, log := range logs { + event := new(ExtensionApproval) + if err := _Extension.contract.UnpackLog(event, "Approval", log); err != nil { + return nil, err + } + event.Log = log + events[i] = *event + } + + return events, nil +} + +// WatchApproval listens for on chain events binding the contract event 0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925. +// +// Solidity: event Approval(address indexed _owner, address indexed _spender, uint256 _value) +func (_Extension *Extension) WatchApproval(criteria []ExtensionApprovalCriteria, ctx context.Context) (chan *ExtensionApproval, error) { + topicHash := _Extension.contract.ABI.Events["Approval"].ID + + criteriaSet := make([]client.EventCriteria, len(criteria)) + for i, c := range criteria { + crteria := client.EventCriteria{ + Address: &_Extension.contract.Address, + Topic0: &topicHash, + } + if c.Owner != nil { + matcher := *c.Owner + topics, err := abi.MakeTopics([]interface{}{matcher}) + if err != nil { + return nil, err + } + crteria.Topic1 = &topics[0][0] + } + if c.Spender != nil { + matcher := *c.Spender + topics, err := abi.MakeTopics([]interface{}{matcher}) + if err != nil { + return nil, err + } + crteria.Topic2 = &topics[0][0] + } + + criteriaSet[i] = crteria + } + + eventChan := make(chan *ExtensionApproval, 100) + blockSub := _Extension.thor.Blocks.Subscribe(ctx) + + go func() { + defer close(eventChan) + + for { + select { + case block := <-blockSub: + // for range in block txs + for _, tx := range block.Transactions { + for index, outputs := range tx.Outputs { + for _, event := range outputs.Events { + if event.Address != _Extension.contract.Address { + continue + } + if topicHash != event.Topics[0] { + continue + } + for _, c := range criteriaSet { + if c.Topic1 != nil && *c.Topic1 != event.Topics[1] { + continue + } + if c.Topic2 != nil && *c.Topic2 != event.Topics[2] { + continue + } + if c.Topic3 != nil && *c.Topic3 != event.Topics[3] { + continue + } + if c.Topic4 != nil && *c.Topic4 != event.Topics[4] { + continue + } + } + + log := client.EventLog{ + Address: &_Extension.contract.Address, + Topics: event.Topics, + Data: event.Data, + Meta: client.LogMeta{ + BlockID: block.ID, + BlockNumber: block.Number, + BlockTime: block.Timestamp, + TxID: tx.ID, + TxOrigin: tx.Origin, + ClauseIndex: int64(index), + }, + } + + ev := new(ExtensionApproval) + if err := _Extension.contract.UnpackLog(ev, "Approval", log); err != nil { + continue + } + ev.Log = log + eventChan <- ev + } + } + } + case <-ctx.Done(): + return + } + } + }() + + return eventChan, nil +} + +// ExtensionTransfer represents a Transfer event raised by the Extension contract. +type ExtensionTransfer struct { + From common.Address + To common.Address + Value *big.Int + Log client.EventLog +} + +type ExtensionTransferCriteria struct { + From *common.Address `abi:"_from"` + To *common.Address `abi:"_to"` +} + +// FilterTransfer is a free log retrieval operation binding the contract event 0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef. +// +// Solidity: event Transfer(address indexed _from, address indexed _to, uint256 _value) +func (_Extension *Extension) FilterTransfer(criteria []ExtensionTransferCriteria, opts *client.FilterOptions, rang *client.FilterRange) ([]ExtensionTransfer, error) { + topicHash := _Extension.contract.ABI.Events["Transfer"].ID + + criteriaSet := make([]client.EventCriteria, len(criteria)) + for i, c := range criteria { + crteria := client.EventCriteria{ + Address: &_Extension.contract.Address, + Topic0: &topicHash, + } + if c.From != nil { + matcher := *c.From + topics, err := abi.MakeTopics([]interface{}{matcher}) + if err != nil { + return nil, err + } + crteria.Topic1 = &topics[0][0] + } + if c.To != nil { + matcher := *c.To + topics, err := abi.MakeTopics([]interface{}{matcher}) + if err != nil { + return nil, err + } + crteria.Topic2 = &topics[0][0] + } + + criteriaSet[i] = crteria + } + + if len(criteriaSet) == 0 { + criteriaSet = append(criteriaSet, client.EventCriteria{ + Address: &_Extension.contract.Address, + Topic0: &topicHash, // Add Topic0 here + }) + } + + filter := &client.EventFilter{ + Range: rang, + Options: opts, + Criteria: &criteriaSet, + } + + logs, err := _Extension.thor.Client.FilterEvents(filter) + if err != nil { + return nil, err + } + + inputs := _Extension.contract.ABI.Events["Transfer"].Inputs + var indexed abi.Arguments + for _, arg := range inputs { + if arg.Indexed { + indexed = append(indexed, arg) + } + } + + events := make([]ExtensionTransfer, len(logs)) + for i, log := range logs { + event := new(ExtensionTransfer) + if err := _Extension.contract.UnpackLog(event, "Transfer", log); err != nil { + return nil, err + } + event.Log = log + events[i] = *event + } + + return events, nil +} + +// WatchTransfer listens for on chain events binding the contract event 0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef. +// +// Solidity: event Transfer(address indexed _from, address indexed _to, uint256 _value) +func (_Extension *Extension) WatchTransfer(criteria []ExtensionTransferCriteria, ctx context.Context) (chan *ExtensionTransfer, error) { + topicHash := _Extension.contract.ABI.Events["Transfer"].ID + + criteriaSet := make([]client.EventCriteria, len(criteria)) + for i, c := range criteria { + crteria := client.EventCriteria{ + Address: &_Extension.contract.Address, + Topic0: &topicHash, + } + if c.From != nil { + matcher := *c.From + topics, err := abi.MakeTopics([]interface{}{matcher}) + if err != nil { + return nil, err + } + crteria.Topic1 = &topics[0][0] + } + if c.To != nil { + matcher := *c.To + topics, err := abi.MakeTopics([]interface{}{matcher}) + if err != nil { + return nil, err + } + crteria.Topic2 = &topics[0][0] + } + + criteriaSet[i] = crteria + } + + eventChan := make(chan *ExtensionTransfer, 100) + blockSub := _Extension.thor.Blocks.Subscribe(ctx) + + go func() { + defer close(eventChan) + + for { + select { + case block := <-blockSub: + // for range in block txs + for _, tx := range block.Transactions { + for index, outputs := range tx.Outputs { + for _, event := range outputs.Events { + if event.Address != _Extension.contract.Address { + continue + } + if topicHash != event.Topics[0] { + continue + } + for _, c := range criteriaSet { + if c.Topic1 != nil && *c.Topic1 != event.Topics[1] { + continue + } + if c.Topic2 != nil && *c.Topic2 != event.Topics[2] { + continue + } + if c.Topic3 != nil && *c.Topic3 != event.Topics[3] { + continue + } + if c.Topic4 != nil && *c.Topic4 != event.Topics[4] { + continue + } + } + + log := client.EventLog{ + Address: &_Extension.contract.Address, + Topics: event.Topics, + Data: event.Data, + Meta: client.LogMeta{ + BlockID: block.ID, + BlockNumber: block.Number, + BlockTime: block.Timestamp, + TxID: tx.ID, + TxOrigin: tx.Origin, + ClauseIndex: int64(index), + }, + } + + ev := new(ExtensionTransfer) + if err := _Extension.contract.UnpackLog(ev, "Transfer", log); err != nil { + continue + } + ev.Log = log + eventChan <- ev + } + } + } + case <-ctx.Done(): + return + } + } + }() + + return eventChan, nil +} diff --git a/builtins/params.go b/builtins/params.go new file mode 100644 index 0000000..48b86a9 --- /dev/null +++ b/builtins/params.go @@ -0,0 +1,333 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package builtins + +import ( + "context" + "errors" + "math/big" + "strings" + + "github.com/darrenvechain/thorgo" + "github.com/darrenvechain/thorgo/accounts" + "github.com/darrenvechain/thorgo/client" + "github.com/darrenvechain/thorgo/crypto/tx" + "github.com/darrenvechain/thorgo/transactions" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/hexutil" +) + +// Reference imports to suppress errors if they are not otherwise used. +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = bind.Bind + _ = common.Big1 + _ = abi.ConvertType + _ = hexutil.MustDecode + _ = context.Background + _ = tx.NewClause +) + +// ParamsMetaData contains all meta data concerning the Params contract. +var ParamsMetaData = &bind.MetaData{ + ABI: "[{\"constant\":false,\"inputs\":[{\"name\":\"_key\",\"type\":\"bytes32\"},{\"name\":\"_value\",\"type\":\"uint256\"}],\"name\":\"set\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"_key\",\"type\":\"bytes32\"}],\"name\":\"get\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"executor\",\"outputs\":[{\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"name\":\"key\",\"type\":\"bytes32\"},{\"indexed\":false,\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Set\",\"type\":\"event\"}]", +} + +// Params is an auto generated Go binding around an Ethereum contract, allowing you to query and create clauses. +type Params struct { + thor *thorgo.Thor // Thor connection to use + contract *accounts.Contract // Generic contract wrapper for the low level calls +} + +// ParamsTransactor is an auto generated Go binding around an Ethereum, allowing you to transact with the contract. +type ParamsTransactor struct { + Params + thor *thorgo.Thor // Thor connection to use + contract *accounts.Contract // Generic contract wrapper for the low level calls + manager accounts.TxManager // TxManager to use +} + +// NewParams creates a new instance of Params, bound to a specific deployed contract. +func NewParams(thor *thorgo.Thor) (*Params, error) { + parsed, err := ParamsMetaData.GetAbi() + if err != nil { + return nil, err + } + contract := thor.Account(common.HexToAddress("0x0000000000000000000000000000506172616d73")).Contract(parsed) + if err != nil { + return nil, err + } + return &Params{thor: thor, contract: contract}, nil +} + +// NewParamsTransactor creates a new instance of ParamsTransactor, bound to a specific deployed contract. +func NewParamsTransactor(thor *thorgo.Thor, manager accounts.TxManager) (*ParamsTransactor, error) { + parsed, err := ParamsMetaData.GetAbi() + if err != nil { + return nil, err + } + contract := thor.Account(common.HexToAddress("0x0000000000000000000000000000506172616d73")).Contract(parsed) + if err != nil { + return nil, err + } + return &ParamsTransactor{Params{thor: thor, contract: contract}, thor, contract, manager}, nil +} + +// Address returns the address of the contract. +func (_Params *Params) Address() common.Address { + return _Params.contract.Address +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_Params *Params) Call(revision client.Revision, result *[]interface{}, method string, params ...interface{}) error { + return _Params.contract.Call(method, result, params...) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_ParamsTransactor *ParamsTransactor) Transact(vetValue *big.Int, method string, params ...interface{}) (*transactions.Visitor, error) { + return _ParamsTransactor.contract.SendWithVET(_ParamsTransactor.manager, vetValue, method, params...) +} + +// Executor is a free data retrieval call binding the contract method 0xc34c08e5. +// +// Solidity: function executor() view returns(address) +func (_Params *Params) Executor(revision ...client.Revision) (common.Address, error) { + var rev client.Revision + if len(revision) > 0 { + rev = revision[0] + } else { + rev = client.RevisionBest() + } + + var out []interface{} + err := _Params.Call(rev, &out, "executor") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err +} + +// Get is a free data retrieval call binding the contract method 0x8eaa6ac0. +// +// Solidity: function get(bytes32 _key) view returns(uint256) +func (_Params *Params) Get(_key [32]byte, revision ...client.Revision) (*big.Int, error) { + var rev client.Revision + if len(revision) > 0 { + rev = revision[0] + } else { + rev = client.RevisionBest() + } + + var out []interface{} + err := _Params.Call(rev, &out, "get", _key) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err +} + +// Set is a paid mutator transaction binding the contract method 0x273f4940. +// +// Solidity: function set(bytes32 _key, uint256 _value) returns() +func (_ParamsTransactor *ParamsTransactor) Set(_key [32]byte, _value *big.Int, vetValue ...*big.Int) (*transactions.Visitor, error) { + var val *big.Int + if len(vetValue) > 0 { + val = vetValue[0] + } else { + val = big.NewInt(0) + } + return _ParamsTransactor.Transact(val, "set", _key, _value) +} + +// SetAsClause is a transaction clause generator 0x273f4940. +// +// Solidity: function set(bytes32 _key, uint256 _value) returns() +func (_Params *Params) SetAsClause(_key [32]byte, _value *big.Int, vetValue ...*big.Int) (*tx.Clause, error) { + var val *big.Int + if len(vetValue) > 0 { + val = vetValue[0] + } else { + val = big.NewInt(0) + } + return _Params.contract.AsClauseWithVET(val, "set", _key, _value) +} + +// ParamsSet represents a Set event raised by the Params contract. +type ParamsSet struct { + Key [32]byte + Value *big.Int + Log client.EventLog +} + +type ParamsSetCriteria struct { + Key *[32]byte `abi:"key"` +} + +// FilterSet is a free log retrieval operation binding the contract event 0x28e3246f80515f5c1ed987b133ef2f193439b25acba6a5e69f219e896fc9d179. +// +// Solidity: event Set(bytes32 indexed key, uint256 value) +func (_Params *Params) FilterSet(criteria []ParamsSetCriteria, opts *client.FilterOptions, rang *client.FilterRange) ([]ParamsSet, error) { + topicHash := _Params.contract.ABI.Events["Set"].ID + + criteriaSet := make([]client.EventCriteria, len(criteria)) + for i, c := range criteria { + crteria := client.EventCriteria{ + Address: &_Params.contract.Address, + Topic0: &topicHash, + } + if c.Key != nil { + matcher := *c.Key + topics, err := abi.MakeTopics([]interface{}{matcher}) + if err != nil { + return nil, err + } + crteria.Topic1 = &topics[0][0] + } + + criteriaSet[i] = crteria + } + + if len(criteriaSet) == 0 { + criteriaSet = append(criteriaSet, client.EventCriteria{ + Address: &_Params.contract.Address, + Topic0: &topicHash, // Add Topic0 here + }) + } + + filter := &client.EventFilter{ + Range: rang, + Options: opts, + Criteria: &criteriaSet, + } + + logs, err := _Params.thor.Client.FilterEvents(filter) + if err != nil { + return nil, err + } + + inputs := _Params.contract.ABI.Events["Set"].Inputs + var indexed abi.Arguments + for _, arg := range inputs { + if arg.Indexed { + indexed = append(indexed, arg) + } + } + + events := make([]ParamsSet, len(logs)) + for i, log := range logs { + event := new(ParamsSet) + if err := _Params.contract.UnpackLog(event, "Set", log); err != nil { + return nil, err + } + event.Log = log + events[i] = *event + } + + return events, nil +} + +// WatchSet listens for on chain events binding the contract event 0x28e3246f80515f5c1ed987b133ef2f193439b25acba6a5e69f219e896fc9d179. +// +// Solidity: event Set(bytes32 indexed key, uint256 value) +func (_Params *Params) WatchSet(criteria []ParamsSetCriteria, ctx context.Context) (chan *ParamsSet, error) { + topicHash := _Params.contract.ABI.Events["Set"].ID + + criteriaSet := make([]client.EventCriteria, len(criteria)) + for i, c := range criteria { + crteria := client.EventCriteria{ + Address: &_Params.contract.Address, + Topic0: &topicHash, + } + if c.Key != nil { + matcher := *c.Key + topics, err := abi.MakeTopics([]interface{}{matcher}) + if err != nil { + return nil, err + } + crteria.Topic1 = &topics[0][0] + } + + criteriaSet[i] = crteria + } + + eventChan := make(chan *ParamsSet, 100) + blockSub := _Params.thor.Blocks.Subscribe(ctx) + + go func() { + defer close(eventChan) + + for { + select { + case block := <-blockSub: + // for range in block txs + for _, tx := range block.Transactions { + for index, outputs := range tx.Outputs { + for _, event := range outputs.Events { + if event.Address != _Params.contract.Address { + continue + } + if topicHash != event.Topics[0] { + continue + } + for _, c := range criteriaSet { + if c.Topic1 != nil && *c.Topic1 != event.Topics[1] { + continue + } + if c.Topic2 != nil && *c.Topic2 != event.Topics[2] { + continue + } + if c.Topic3 != nil && *c.Topic3 != event.Topics[3] { + continue + } + if c.Topic4 != nil && *c.Topic4 != event.Topics[4] { + continue + } + } + + log := client.EventLog{ + Address: &_Params.contract.Address, + Topics: event.Topics, + Data: event.Data, + Meta: client.LogMeta{ + BlockID: block.ID, + BlockNumber: block.Number, + BlockTime: block.Timestamp, + TxID: tx.ID, + TxOrigin: tx.Origin, + ClauseIndex: int64(index), + }, + } + + ev := new(ParamsSet) + if err := _Params.contract.UnpackLog(ev, "Set", log); err != nil { + continue + } + ev.Log = log + eventChan <- ev + } + } + } + case <-ctx.Done(): + return + } + } + }() + + return eventChan, nil +} diff --git a/builtins/prototype.go b/builtins/prototype.go new file mode 100644 index 0000000..9ab4341 --- /dev/null +++ b/builtins/prototype.go @@ -0,0 +1,518 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package builtins + +import ( + "context" + "errors" + "math/big" + "strings" + + "github.com/darrenvechain/thorgo" + "github.com/darrenvechain/thorgo/accounts" + "github.com/darrenvechain/thorgo/client" + "github.com/darrenvechain/thorgo/crypto/tx" + "github.com/darrenvechain/thorgo/transactions" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/hexutil" +) + +// Reference imports to suppress errors if they are not otherwise used. +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = bind.Bind + _ = common.Big1 + _ = abi.ConvertType + _ = hexutil.MustDecode + _ = context.Background + _ = tx.NewClause +) + +// PrototypeMetaData contains all meta data concerning the Prototype contract. +var PrototypeMetaData = &bind.MetaData{ + ABI: "[{\"constant\":false,\"inputs\":[{\"name\":\"_self\",\"type\":\"address\"},{\"name\":\"_newMaster\",\"type\":\"address\"}],\"name\":\"setMaster\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"_self\",\"type\":\"address\"},{\"name\":\"_user\",\"type\":\"address\"}],\"name\":\"isUser\",\"outputs\":[{\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"_self\",\"type\":\"address\"},{\"name\":\"_key\",\"type\":\"bytes32\"}],\"name\":\"storageFor\",\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"_self\",\"type\":\"address\"},{\"name\":\"_blockNumber\",\"type\":\"uint256\"}],\"name\":\"energy\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_self\",\"type\":\"address\"},{\"name\":\"_user\",\"type\":\"address\"}],\"name\":\"removeUser\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"_self\",\"type\":\"address\"}],\"name\":\"currentSponsor\",\"outputs\":[{\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_self\",\"type\":\"address\"},{\"name\":\"_credit\",\"type\":\"uint256\"},{\"name\":\"_recoveryRate\",\"type\":\"uint256\"}],\"name\":\"setCreditPlan\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_self\",\"type\":\"address\"},{\"name\":\"_sponsor\",\"type\":\"address\"}],\"name\":\"selectSponsor\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"_self\",\"type\":\"address\"},{\"name\":\"_blockNumber\",\"type\":\"uint256\"}],\"name\":\"balance\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_self\",\"type\":\"address\"}],\"name\":\"sponsor\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"_self\",\"type\":\"address\"}],\"name\":\"creditPlan\",\"outputs\":[{\"name\":\"credit\",\"type\":\"uint256\"},{\"name\":\"recoveryRate\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_self\",\"type\":\"address\"},{\"name\":\"_user\",\"type\":\"address\"}],\"name\":\"addUser\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"_self\",\"type\":\"address\"}],\"name\":\"hasCode\",\"outputs\":[{\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"_self\",\"type\":\"address\"}],\"name\":\"master\",\"outputs\":[{\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"_self\",\"type\":\"address\"},{\"name\":\"_user\",\"type\":\"address\"}],\"name\":\"userCredit\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_self\",\"type\":\"address\"}],\"name\":\"unsponsor\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"_self\",\"type\":\"address\"},{\"name\":\"_sponsor\",\"type\":\"address\"}],\"name\":\"isSponsor\",\"outputs\":[{\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"}]", +} + +// Prototype is an auto generated Go binding around an Ethereum contract, allowing you to query and create clauses. +type Prototype struct { + thor *thorgo.Thor // Thor connection to use + contract *accounts.Contract // Generic contract wrapper for the low level calls +} + +// PrototypeTransactor is an auto generated Go binding around an Ethereum, allowing you to transact with the contract. +type PrototypeTransactor struct { + Prototype + thor *thorgo.Thor // Thor connection to use + contract *accounts.Contract // Generic contract wrapper for the low level calls + manager accounts.TxManager // TxManager to use +} + +// NewPrototype creates a new instance of Prototype, bound to a specific deployed contract. +func NewPrototype(thor *thorgo.Thor) (*Prototype, error) { + parsed, err := PrototypeMetaData.GetAbi() + if err != nil { + return nil, err + } + contract := thor.Account(common.HexToAddress("0x000000000000000000000050726f746f74797065")).Contract(parsed) + if err != nil { + return nil, err + } + return &Prototype{thor: thor, contract: contract}, nil +} + +// NewPrototypeTransactor creates a new instance of PrototypeTransactor, bound to a specific deployed contract. +func NewPrototypeTransactor(thor *thorgo.Thor, manager accounts.TxManager) (*PrototypeTransactor, error) { + parsed, err := PrototypeMetaData.GetAbi() + if err != nil { + return nil, err + } + contract := thor.Account(common.HexToAddress("0x000000000000000000000050726f746f74797065")).Contract(parsed) + if err != nil { + return nil, err + } + return &PrototypeTransactor{Prototype{thor: thor, contract: contract}, thor, contract, manager}, nil +} + +// Address returns the address of the contract. +func (_Prototype *Prototype) Address() common.Address { + return _Prototype.contract.Address +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_Prototype *Prototype) Call(revision client.Revision, result *[]interface{}, method string, params ...interface{}) error { + return _Prototype.contract.Call(method, result, params...) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_PrototypeTransactor *PrototypeTransactor) Transact(vetValue *big.Int, method string, params ...interface{}) (*transactions.Visitor, error) { + return _PrototypeTransactor.contract.SendWithVET(_PrototypeTransactor.manager, vetValue, method, params...) +} + +// Balance is a free data retrieval call binding the contract method 0x6d8c859a. +// +// Solidity: function balance(address _self, uint256 _blockNumber) view returns(uint256) +func (_Prototype *Prototype) Balance(_self common.Address, _blockNumber *big.Int, revision ...client.Revision) (*big.Int, error) { + var rev client.Revision + if len(revision) > 0 { + rev = revision[0] + } else { + rev = client.RevisionBest() + } + + var out []interface{} + err := _Prototype.Call(rev, &out, "balance", _self, _blockNumber) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err +} + +// CreditPlan is a free data retrieval call binding the contract method 0x80df45b4. +// +// Solidity: function creditPlan(address _self) view returns(uint256 credit, uint256 recoveryRate) +func (_Prototype *Prototype) CreditPlan(_self common.Address, revision ...client.Revision) (struct { + Credit *big.Int + RecoveryRate *big.Int +}, error) { + var rev client.Revision + if len(revision) > 0 { + rev = revision[0] + } else { + rev = client.RevisionBest() + } + + var out []interface{} + err := _Prototype.Call(rev, &out, "creditPlan", _self) + + outstruct := new(struct { + Credit *big.Int + RecoveryRate *big.Int + }) + if err != nil { + return *outstruct, err + } + + outstruct.Credit = *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + outstruct.RecoveryRate = *abi.ConvertType(out[1], new(*big.Int)).(**big.Int) + + return *outstruct, err + +} + +// CurrentSponsor is a free data retrieval call binding the contract method 0x23d8c7db. +// +// Solidity: function currentSponsor(address _self) view returns(address) +func (_Prototype *Prototype) CurrentSponsor(_self common.Address, revision ...client.Revision) (common.Address, error) { + var rev client.Revision + if len(revision) > 0 { + rev = revision[0] + } else { + rev = client.RevisionBest() + } + + var out []interface{} + err := _Prototype.Call(rev, &out, "currentSponsor", _self) + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err +} + +// Energy is a free data retrieval call binding the contract method 0x1e95be45. +// +// Solidity: function energy(address _self, uint256 _blockNumber) view returns(uint256) +func (_Prototype *Prototype) Energy(_self common.Address, _blockNumber *big.Int, revision ...client.Revision) (*big.Int, error) { + var rev client.Revision + if len(revision) > 0 { + rev = revision[0] + } else { + rev = client.RevisionBest() + } + + var out []interface{} + err := _Prototype.Call(rev, &out, "energy", _self, _blockNumber) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err +} + +// HasCode is a free data retrieval call binding the contract method 0x9538c4b3. +// +// Solidity: function hasCode(address _self) view returns(bool) +func (_Prototype *Prototype) HasCode(_self common.Address, revision ...client.Revision) (bool, error) { + var rev client.Revision + if len(revision) > 0 { + rev = revision[0] + } else { + rev = client.RevisionBest() + } + + var out []interface{} + err := _Prototype.Call(rev, &out, "hasCode", _self) + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err +} + +// IsSponsor is a free data retrieval call binding the contract method 0xd87333ac. +// +// Solidity: function isSponsor(address _self, address _sponsor) view returns(bool) +func (_Prototype *Prototype) IsSponsor(_self common.Address, _sponsor common.Address, revision ...client.Revision) (bool, error) { + var rev client.Revision + if len(revision) > 0 { + rev = revision[0] + } else { + rev = client.RevisionBest() + } + + var out []interface{} + err := _Prototype.Call(rev, &out, "isSponsor", _self, _sponsor) + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err +} + +// IsUser is a free data retrieval call binding the contract method 0x02d43dc8. +// +// Solidity: function isUser(address _self, address _user) view returns(bool) +func (_Prototype *Prototype) IsUser(_self common.Address, _user common.Address, revision ...client.Revision) (bool, error) { + var rev client.Revision + if len(revision) > 0 { + rev = revision[0] + } else { + rev = client.RevisionBest() + } + + var out []interface{} + err := _Prototype.Call(rev, &out, "isUser", _self, _user) + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err +} + +// Master is a free data retrieval call binding the contract method 0x9ed153c0. +// +// Solidity: function master(address _self) view returns(address) +func (_Prototype *Prototype) Master(_self common.Address, revision ...client.Revision) (common.Address, error) { + var rev client.Revision + if len(revision) > 0 { + rev = revision[0] + } else { + rev = client.RevisionBest() + } + + var out []interface{} + err := _Prototype.Call(rev, &out, "master", _self) + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err +} + +// StorageFor is a free data retrieval call binding the contract method 0x04e7a457. +// +// Solidity: function storageFor(address _self, bytes32 _key) view returns(bytes32) +func (_Prototype *Prototype) StorageFor(_self common.Address, _key [32]byte, revision ...client.Revision) ([32]byte, error) { + var rev client.Revision + if len(revision) > 0 { + rev = revision[0] + } else { + rev = client.RevisionBest() + } + + var out []interface{} + err := _Prototype.Call(rev, &out, "storageFor", _self, _key) + + if err != nil { + return *new([32]byte), err + } + + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + + return out0, err +} + +// UserCredit is a free data retrieval call binding the contract method 0xc9c4fc41. +// +// Solidity: function userCredit(address _self, address _user) view returns(uint256) +func (_Prototype *Prototype) UserCredit(_self common.Address, _user common.Address, revision ...client.Revision) (*big.Int, error) { + var rev client.Revision + if len(revision) > 0 { + rev = revision[0] + } else { + rev = client.RevisionBest() + } + + var out []interface{} + err := _Prototype.Call(rev, &out, "userCredit", _self, _user) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err +} + +// AddUser is a paid mutator transaction binding the contract method 0x8ca3b448. +// +// Solidity: function addUser(address _self, address _user) returns() +func (_PrototypeTransactor *PrototypeTransactor) AddUser(_self common.Address, _user common.Address, vetValue ...*big.Int) (*transactions.Visitor, error) { + var val *big.Int + if len(vetValue) > 0 { + val = vetValue[0] + } else { + val = big.NewInt(0) + } + return _PrototypeTransactor.Transact(val, "addUser", _self, _user) +} + +// AddUserAsClause is a transaction clause generator 0x8ca3b448. +// +// Solidity: function addUser(address _self, address _user) returns() +func (_Prototype *Prototype) AddUserAsClause(_self common.Address, _user common.Address, vetValue ...*big.Int) (*tx.Clause, error) { + var val *big.Int + if len(vetValue) > 0 { + val = vetValue[0] + } else { + val = big.NewInt(0) + } + return _Prototype.contract.AsClauseWithVET(val, "addUser", _self, _user) +} + +// RemoveUser is a paid mutator transaction binding the contract method 0x22928d6b. +// +// Solidity: function removeUser(address _self, address _user) returns() +func (_PrototypeTransactor *PrototypeTransactor) RemoveUser(_self common.Address, _user common.Address, vetValue ...*big.Int) (*transactions.Visitor, error) { + var val *big.Int + if len(vetValue) > 0 { + val = vetValue[0] + } else { + val = big.NewInt(0) + } + return _PrototypeTransactor.Transact(val, "removeUser", _self, _user) +} + +// RemoveUserAsClause is a transaction clause generator 0x22928d6b. +// +// Solidity: function removeUser(address _self, address _user) returns() +func (_Prototype *Prototype) RemoveUserAsClause(_self common.Address, _user common.Address, vetValue ...*big.Int) (*tx.Clause, error) { + var val *big.Int + if len(vetValue) > 0 { + val = vetValue[0] + } else { + val = big.NewInt(0) + } + return _Prototype.contract.AsClauseWithVET(val, "removeUser", _self, _user) +} + +// SelectSponsor is a paid mutator transaction binding the contract method 0x3871a9fb. +// +// Solidity: function selectSponsor(address _self, address _sponsor) returns() +func (_PrototypeTransactor *PrototypeTransactor) SelectSponsor(_self common.Address, _sponsor common.Address, vetValue ...*big.Int) (*transactions.Visitor, error) { + var val *big.Int + if len(vetValue) > 0 { + val = vetValue[0] + } else { + val = big.NewInt(0) + } + return _PrototypeTransactor.Transact(val, "selectSponsor", _self, _sponsor) +} + +// SelectSponsorAsClause is a transaction clause generator 0x3871a9fb. +// +// Solidity: function selectSponsor(address _self, address _sponsor) returns() +func (_Prototype *Prototype) SelectSponsorAsClause(_self common.Address, _sponsor common.Address, vetValue ...*big.Int) (*tx.Clause, error) { + var val *big.Int + if len(vetValue) > 0 { + val = vetValue[0] + } else { + val = big.NewInt(0) + } + return _Prototype.contract.AsClauseWithVET(val, "selectSponsor", _self, _sponsor) +} + +// SetCreditPlan is a paid mutator transaction binding the contract method 0x3659f8ed. +// +// Solidity: function setCreditPlan(address _self, uint256 _credit, uint256 _recoveryRate) returns() +func (_PrototypeTransactor *PrototypeTransactor) SetCreditPlan(_self common.Address, _credit *big.Int, _recoveryRate *big.Int, vetValue ...*big.Int) (*transactions.Visitor, error) { + var val *big.Int + if len(vetValue) > 0 { + val = vetValue[0] + } else { + val = big.NewInt(0) + } + return _PrototypeTransactor.Transact(val, "setCreditPlan", _self, _credit, _recoveryRate) +} + +// SetCreditPlanAsClause is a transaction clause generator 0x3659f8ed. +// +// Solidity: function setCreditPlan(address _self, uint256 _credit, uint256 _recoveryRate) returns() +func (_Prototype *Prototype) SetCreditPlanAsClause(_self common.Address, _credit *big.Int, _recoveryRate *big.Int, vetValue ...*big.Int) (*tx.Clause, error) { + var val *big.Int + if len(vetValue) > 0 { + val = vetValue[0] + } else { + val = big.NewInt(0) + } + return _Prototype.contract.AsClauseWithVET(val, "setCreditPlan", _self, _credit, _recoveryRate) +} + +// SetMaster is a paid mutator transaction binding the contract method 0x01378b58. +// +// Solidity: function setMaster(address _self, address _newMaster) returns() +func (_PrototypeTransactor *PrototypeTransactor) SetMaster(_self common.Address, _newMaster common.Address, vetValue ...*big.Int) (*transactions.Visitor, error) { + var val *big.Int + if len(vetValue) > 0 { + val = vetValue[0] + } else { + val = big.NewInt(0) + } + return _PrototypeTransactor.Transact(val, "setMaster", _self, _newMaster) +} + +// SetMasterAsClause is a transaction clause generator 0x01378b58. +// +// Solidity: function setMaster(address _self, address _newMaster) returns() +func (_Prototype *Prototype) SetMasterAsClause(_self common.Address, _newMaster common.Address, vetValue ...*big.Int) (*tx.Clause, error) { + var val *big.Int + if len(vetValue) > 0 { + val = vetValue[0] + } else { + val = big.NewInt(0) + } + return _Prototype.contract.AsClauseWithVET(val, "setMaster", _self, _newMaster) +} + +// Sponsor is a paid mutator transaction binding the contract method 0x766c4f37. +// +// Solidity: function sponsor(address _self) returns() +func (_PrototypeTransactor *PrototypeTransactor) Sponsor(_self common.Address, vetValue ...*big.Int) (*transactions.Visitor, error) { + var val *big.Int + if len(vetValue) > 0 { + val = vetValue[0] + } else { + val = big.NewInt(0) + } + return _PrototypeTransactor.Transact(val, "sponsor", _self) +} + +// SponsorAsClause is a transaction clause generator 0x766c4f37. +// +// Solidity: function sponsor(address _self) returns() +func (_Prototype *Prototype) SponsorAsClause(_self common.Address, vetValue ...*big.Int) (*tx.Clause, error) { + var val *big.Int + if len(vetValue) > 0 { + val = vetValue[0] + } else { + val = big.NewInt(0) + } + return _Prototype.contract.AsClauseWithVET(val, "sponsor", _self) +} + +// Unsponsor is a paid mutator transaction binding the contract method 0xcdd2a99f. +// +// Solidity: function unsponsor(address _self) returns() +func (_PrototypeTransactor *PrototypeTransactor) Unsponsor(_self common.Address, vetValue ...*big.Int) (*transactions.Visitor, error) { + var val *big.Int + if len(vetValue) > 0 { + val = vetValue[0] + } else { + val = big.NewInt(0) + } + return _PrototypeTransactor.Transact(val, "unsponsor", _self) +} + +// UnsponsorAsClause is a transaction clause generator 0xcdd2a99f. +// +// Solidity: function unsponsor(address _self) returns() +func (_Prototype *Prototype) UnsponsorAsClause(_self common.Address, vetValue ...*big.Int) (*tx.Clause, error) { + var val *big.Int + if len(vetValue) > 0 { + val = vetValue[0] + } else { + val = big.NewInt(0) + } + return _Prototype.contract.AsClauseWithVET(val, "unsponsor", _self) +} diff --git a/client/accounts_test.go b/client/accounts_test.go index 9b26a93..58c421e 100644 --- a/client/accounts_test.go +++ b/client/accounts_test.go @@ -4,6 +4,7 @@ import ( "strings" "testing" + "github.com/darrenvechain/thorgo/client" "github.com/darrenvechain/thorgo/solo" "github.com/ethereum/go-ethereum/common" "github.com/stretchr/testify/assert" @@ -21,7 +22,7 @@ func TestClient_Account(t *testing.T) { func TestClient_AccountAt(t *testing.T) { acc, err := thorClient.AccountAt( common.HexToAddress("0xd1d37b8913563fC25BC5bB2E669eB3dBC6b87762"), - solo.GenesisID(), + client.RevisionID(solo.GenesisID()), ) assert.NoError(t, err) @@ -39,7 +40,7 @@ func TestClient_AccountCode(t *testing.T) { func TestClient_AccountCodeAt(t *testing.T) { res, err := thorClient.AccountCodeAt( common.HexToAddress("0x0000000000000000000000000000456E65726779"), - solo.GenesisID(), + client.RevisionID(solo.GenesisID()), ) assert.NoError(t, err) assert.Greater(t, len(res.Code), 2) @@ -59,7 +60,7 @@ func TestClient_AccountStorageAt(t *testing.T) { res, err := thorClient.AccountStorageAt( common.HexToAddress("0x0000000000000000000000000000456E65726779"), common.HexToHash(strings.Repeat("0", 64)), - solo.GenesisID(), + client.RevisionID(solo.GenesisID()), ) assert.NoError(t, err) diff --git a/client/blocks_test.go b/client/blocks_test.go index 2ce493c..9388feb 100644 --- a/client/blocks_test.go +++ b/client/blocks_test.go @@ -21,7 +21,8 @@ func TestClient_BestBlock(t *testing.T) { } func TestClient_GenesisBlock(t *testing.T) { - block := thorClient.GenesisBlock() + block, err := thorClient.GenesisBlock() + assert.NoError(t, err) assert.NotNil(t, block) } @@ -32,8 +33,7 @@ func TestClient_ExpandedBlock(t *testing.T) { } func TestClient_ExpandedBlockWithTxs(t *testing.T) { - c, err := client.NewFromURL("https://mainnet.vechain.org") - assert.NoError(t, err) + c := client.NewFromURL("https://mainnet.vechain.org") blk, err := c.ExpandedBlock("0x0125fb07988ff3c36b261b5f7227688c1c0473c4873825ac299bc256ea991b0f") assert.NoError(t, err) @@ -44,7 +44,8 @@ func TestClient_ExpandedBlockWithTxs(t *testing.T) { } func TestClient_ChainTag(t *testing.T) { - chainTag := thorClient.ChainTag() + chainTag, err := thorClient.ChainTag() + assert.NoError(t, err) assert.Equal(t, solo.ChainTag(), chainTag) } diff --git a/client/client.go b/client/client.go index f0ed433..829fe98 100644 --- a/client/client.go +++ b/client/client.go @@ -17,29 +17,21 @@ type Client struct { genesisBlock *Block } -func New(url string, client *http.Client) (*Client, error) { +func New(url string, client *http.Client) *Client { return newClient(url, client) } -func NewFromURL(url string) (*Client, error) { +func NewFromURL(url string) *Client { return New(url, &http.Client{}) } -func newClient(url string, client *http.Client) (*Client, error) { +func newClient(url string, client *http.Client) *Client { url = strings.TrimSuffix(url, "/") - c := &Client{ + return &Client{ client: client, url: url, } - - block, err := c.Block("0") - if err != nil { - return nil, err - } - c.genesisBlock = block - - return c, nil } // Account fetches the account information for the given address. @@ -49,8 +41,8 @@ func (c *Client) Account(addr common.Address) (*Account, error) { } // AccountAt fetches the account information for an address at the given revision. -func (c *Client) AccountAt(addr common.Address, revision common.Hash) (*Account, error) { - url := "/accounts/" + addr.Hex() + "?revision=" + revision.Hex() +func (c *Client) AccountAt(addr common.Address, revision Revision) (*Account, error) { + url := "/accounts/" + addr.Hex() + "?revision=" + revision.value return httpGet(c, url, &Account{}) } @@ -69,8 +61,8 @@ func (c *Client) Inspect(body InspectRequest) ([]InspectResponse, error) { } // InspectAt will send an array of clauses to the node to simulate the execution of the clauses at the given revision. -func (c *Client) InspectAt(body InspectRequest, revision common.Hash) ([]InspectResponse, error) { - url := "/accounts/*?revision=" + revision.Hex() +func (c *Client) InspectAt(body InspectRequest, revision Revision) ([]InspectResponse, error) { + url := "/accounts/*?revision=" + revision.value response := make([]InspectResponse, 0) _, err := httpPost(c, url, body, &response) if err != nil { @@ -86,8 +78,8 @@ func (c *Client) AccountCode(addr common.Address) (*AccountCode, error) { } // AccountCodeAt fetches the code for the account at the given address and revision. -func (c *Client) AccountCodeAt(addr common.Address, revision common.Hash) (*AccountCode, error) { - url := "/accounts/" + addr.Hex() + "/code?revision=" + revision.Hex() +func (c *Client) AccountCodeAt(addr common.Address, revision Revision) (*AccountCode, error) { + url := "/accounts/" + addr.Hex() + "/code?revision=" + revision.value return httpGet(c, url, &AccountCode{}) } @@ -101,9 +93,9 @@ func (c *Client) AccountStorage(addr common.Address, key common.Hash) (*AccountS func (c *Client) AccountStorageAt( addr common.Address, key common.Hash, - revision common.Hash, + revision Revision, ) (*AccountStorage, error) { - url := "/accounts/" + addr.Hex() + "/storage/" + key.Hex() + "?revision=" + revision.Hex() + url := "/accounts/" + addr.Hex() + "/storage/" + key.Hex() + "?revision=" + revision.value return httpGet(c, url, &AccountStorage{}) } @@ -119,8 +111,15 @@ func (c *Client) BestBlock() (*Block, error) { } // GenesisBlock returns the genesis block. -func (c *Client) GenesisBlock() *Block { - return c.genesisBlock +func (c *Client) GenesisBlock() (*Block, error) { + if c.genesisBlock == nil { + block, err := c.Block("0") + if err != nil { + return nil, err + } + c.genesisBlock = block + } + return c.genesisBlock, nil } // ExpandedBlock fetches the block at the given revision with all the transactions expanded. @@ -130,8 +129,12 @@ func (c *Client) ExpandedBlock(revision string) (*ExpandedBlock, error) { } // ChainTag returns the chain tag of the genesis block. -func (c *Client) ChainTag() byte { - return c.genesisBlock.ChainTag() +func (c *Client) ChainTag() (byte, error) { + gen, err := c.GenesisBlock() + if err != nil { + return 0, err + } + return gen.ChainTag(), nil } // SendTransaction sends a transaction to the node. diff --git a/client/revision.go b/client/revision.go new file mode 100644 index 0000000..cd1d43c --- /dev/null +++ b/client/revision.go @@ -0,0 +1,31 @@ +package client + +import ( + "strconv" + + "github.com/ethereum/go-ethereum/common" +) + +type Revision struct { + value string +} + +func RevisionID(hash common.Hash) Revision { + return Revision{value: hash.Hex()} +} + +func RevisionNumber(number int) Revision { + return Revision{value: strconv.Itoa(number)} +} + +func RevisionBest() Revision { + return Revision{value: "best"} +} + +func RevisionFinalized() Revision { + return Revision{value: "finalized"} +} + +func RevisionJustified() Revision { + return Revision{value: "justified"} +} diff --git a/client/transactions_test.go b/client/transactions_test.go index 7720898..55ec157 100644 --- a/client/transactions_test.go +++ b/client/transactions_test.go @@ -18,10 +18,13 @@ func TestClient_SendTransaction(t *testing.T) { vetClause := tx.NewClause(&account2Addr). WithValue(big.NewInt(1000)) + tag, err := thorClient.ChainTag() + assert.NoError(t, err) + txBody := new(tx.Builder). Gas(3_000_000). GasPriceCoef(255). - ChainTag(thorClient.ChainTag()). + ChainTag(tag). Expiration(100000000). BlockRef(tx.NewBlockRef(0)). Nonce(tx.Nonce()). diff --git a/cmd/thorgen/bind/bind.go b/cmd/thorgen/bind.go similarity index 99% rename from cmd/thorgen/bind/bind.go rename to cmd/thorgen/bind.go index b200fff..c69a4d8 100644 --- a/cmd/thorgen/bind/bind.go +++ b/cmd/thorgen/bind.go @@ -18,7 +18,7 @@ // // Detailed usage document and tutorial available on the go-ethereum Wiki page: // https://github.com/ethereum/go-ethereum/wiki/Native-DApps:-Go-bindings-to-Ethereum-contracts -package bind +package main import ( "bytes" diff --git a/cmd/thorgen/main.go b/cmd/thorgen/main.go index 4619843..44c9e92 100644 --- a/cmd/thorgen/main.go +++ b/cmd/thorgen/main.go @@ -25,7 +25,6 @@ import ( "regexp" "strings" - "github.com/darrenvechain/thorgo/cmd/thorgen/bind" "github.com/ethereum/go-ethereum/cmd/utils" "github.com/ethereum/go-ethereum/common/compiler" "github.com/ethereum/go-ethereum/crypto" @@ -101,10 +100,10 @@ func thorgen(c *cli.Context) error { if c.String(pkgFlag.Name) == "" { utils.Fatalf("No destination package specified (--pkg)") } - var lang bind.Lang + var lang Lang switch c.String(langFlag.Name) { case "go": - lang = bind.LangGo + lang = LangGo default: utils.Fatalf("Unsupported destination language \"%s\" (--lang)", c.String(langFlag.Name)) } @@ -228,7 +227,7 @@ func thorgen(c *cli.Context) error { } } // Generate the contract binding - code, err := bind.Bind(types, abis, bins, sigs, c.String(pkgFlag.Name), lang, libs, aliases) + code, err := Bind(types, abis, bins, sigs, c.String(pkgFlag.Name), lang, libs, aliases) if err != nil { utils.Fatalf("failed to generate ABI binding: %v", err) } diff --git a/cmd/thorgen/bind/source.go.tpl b/cmd/thorgen/source.go.tpl similarity index 70% rename from cmd/thorgen/bind/source.go.tpl rename to cmd/thorgen/source.go.tpl index 6beb405..09e0550 100644 --- a/cmd/thorgen/bind/source.go.tpl +++ b/cmd/thorgen/source.go.tpl @@ -29,6 +29,8 @@ var ( _ = common.Big1 _ = abi.ConvertType _ = hexutil.MustDecode + _ = context.Background + _ = tx.NewClause ) {{$structs := .Structs}} @@ -55,21 +57,8 @@ var ( Bin: "0x{{.InputBin}}", {{end}} } - // {{.Type}}ABI is the input ABI used to generate the binding from. - // Deprecated: Use {{.Type}}MetaData.ABI instead. - var {{.Type}}ABI = {{.Type}}MetaData.ABI - - {{if $contract.FuncSigs}} - // Deprecated: Use {{.Type}}MetaData.Sigs instead. - // {{.Type}}FuncSigs maps the 4-byte function signature to its string representation. - var {{.Type}}FuncSigs = {{.Type}}MetaData.Sigs - {{end}} {{if .InputBin}} - // {{.Type}}Bin is the compiled bytecode used for deploying new contracts. - // Deprecated: Use {{.Type}}MetaData.Bin instead. - var {{.Type}}Bin = {{.Type}}MetaData.Bin - // Deploy{{.Type}} deploys a new Ethereum contract, binding an instance of {{.Type}} to it. func Deploy{{.Type}}(thor *thorgo.Thor, sender accounts.TxManager{{range .Constructor.Inputs}}, {{.Name}} {{bindtype .Type $structs}}{{end}}) (common.Hash, *{{.Type}}, error) { parsed, err := {{.Type}}MetaData.GetAbi() @@ -82,7 +71,7 @@ var ( {{range $pattern, $name := .Libraries}} {{decapitalise $name}}Addr, _, _, _ := Deploy{{capitalise $name}}(auth, backend) - {{$contract.Type}}Bin = strings.ReplaceAll({{$contract.Type}}Bin, "__${{$pattern}}$__", {{decapitalise $name}}Addr.String()[2:]) + {{$contract.Type}}MetaData.Bin = strings.ReplaceAll({{$contract.Type}}Bin, "__${{$pattern}}$__", {{decapitalise $name}}Addr.String()[2:]) {{end}} bytes, err := hexutil.Decode({{.Type}}MetaData.Bin) @@ -103,12 +92,21 @@ var ( } {{end}} - // {{.Type}} is an auto generated Go binding around an Ethereum contract. + // {{.Type}} is an auto generated Go binding around an Ethereum contract, allowing you to query and create clauses. type {{.Type}} struct { thor *thorgo.Thor // Thor connection to use contract *accounts.Contract // Generic contract wrapper for the low level calls } + // {{.Type}}Transactor is an auto generated Go binding around an Ethereum, allowing you to transact with the contract. + type {{.Type}}Transactor struct { + {{.Type}} + thor *thorgo.Thor // Thor connection to use + contract *accounts.Contract // Generic contract wrapper for the low level calls + manager accounts.TxManager // TxManager to use + } + + // New{{.Type}} creates a new instance of {{.Type}}, bound to a specific deployed contract. func New{{.Type}}(address common.Address, thor *thorgo.Thor) (*{{.Type}}, error) { parsed, err := {{.Type}}MetaData.GetAbi() @@ -122,26 +120,51 @@ var ( return &{{.Type}}{ thor: thor, contract: contract }, nil } + // New{{.Type}}Transactor creates a new instance of {{.Type}}Transactor, bound to a specific deployed contract. + func New{{.Type}}Transactor(address common.Address, thor *thorgo.Thor, manager accounts.TxManager) (*{{.Type}}Transactor, error) { + parsed, err := {{.Type}}MetaData.GetAbi() + if err != nil { + return nil, err + } + contract := thor.Account(address).Contract(parsed) + if err != nil { + return nil, err + } + return &{{.Type}}Transactor{ {{.Type}}{ thor: thor, contract: contract }, thor, contract, manager }, nil + } + + // Address returns the address of the contract. + func (_{{$contract.Type}} *{{$contract.Type}}) Address() common.Address { + return _{{$contract.Type}}.contract.Address + } + // Call invokes the (constant) contract method with params as input values and // sets the output to result. The result type might be a single field for simple // returns, a slice of interfaces for anonymous returns and a struct for named // returns. - func (_{{$contract.Type}} *{{$contract.Type}}) Call(result *[]interface{}, method string, params ...interface{}) error { - return _{{$contract.Type}}.contract.Call(method, result, params) + func (_{{$contract.Type}} *{{$contract.Type}}) Call(revision client.Revision, result *[]interface{}, method string, params ...interface{}) error { + return _{{$contract.Type}}.contract.Call(method, result, params...) } // Transact invokes the (paid) contract method with params as input values. - func (_{{$contract.Type}} *{{$contract.Type}}) Transact(sender accounts.TxManager, method string, params ...interface{}) (*transactions.Visitor, error) { - return _{{$contract.Type}}.contract.Send(sender, method, params) + func (_{{$contract.Type}}Transactor *{{$contract.Type}}Transactor) Transact(vetValue *big.Int, method string, params ...interface{}) (*transactions.Visitor, error) { + return _{{$contract.Type}}Transactor.contract.SendWithVET(_{{$contract.Type}}Transactor.manager, vetValue, method, params...) } {{range .Calls}} // {{.Normalized.Name}} is a free data retrieval call binding the contract method 0x{{printf "%x" .Original.ID}}. // // Solidity: {{.Original.String}} - func (_{{$contract.Type}} *{{$contract.Type}}) {{.Normalized.Name}}({{range .Normalized.Inputs}} {{.Name}} {{bindtype .Type $structs}}, {{end}}) ({{if .Structured}}struct{ {{range .Normalized.Outputs}}{{.Name}} {{bindtype .Type $structs}};{{end}} },{{else}}{{range .Normalized.Outputs}}{{bindtype .Type $structs}},{{end}}{{end}} error) { + func (_{{$contract.Type}} *{{$contract.Type}}) {{.Normalized.Name}}({{range .Normalized.Inputs}} {{.Name}} {{bindtype .Type $structs}}, {{end}} revision ...client.Revision) ({{if .Structured}}struct{ {{range .Normalized.Outputs}}{{.Name}} {{bindtype .Type $structs}};{{end}} },{{else}}{{range .Normalized.Outputs}}{{bindtype .Type $structs}},{{end}}{{end}} error) { + var rev client.Revision + if len(revision) > 0 { + rev = revision[0] + } else { + rev = client.RevisionBest() + } + var out []interface{} - err := _{{$contract.Type}}.Call(&out, "{{.Original.Name}}" {{range .Normalized.Inputs}}, {{.Name}}{{end}}) + err := _{{$contract.Type}}.Call(rev, &out, "{{.Original.Name}}" {{range .Normalized.Inputs}}, {{.Name}}{{end}}) {{if .Structured}} outstruct := new(struct{ {{range .Normalized.Outputs}} {{.Name}} {{bindtype .Type $structs}}; {{end}} }) if err != nil { @@ -166,15 +189,27 @@ var ( // {{.Normalized.Name}} is a paid mutator transaction binding the contract method 0x{{printf "%x" .Original.ID}}. // // Solidity: {{.Original.String}} - func (_{{$contract.Type}} *{{$contract.Type}}) {{.Normalized.Name}}(sender accounts.TxManager {{range .Normalized.Inputs}}, {{.Name}} {{bindtype .Type $structs}} {{end}}) (*transactions.Visitor, error) { - return _{{$contract.Type}}.contract.Send(sender, "{{.Original.Name}}" {{range .Normalized.Inputs}}, {{.Name}}{{end}}) + func (_{{$contract.Type}}Transactor *{{$contract.Type}}Transactor) {{.Normalized.Name}}({{range .Normalized.Inputs}} {{.Name}} {{bindtype .Type $structs}}, {{end}} vetValue ... *big.Int) (*transactions.Visitor, error) { + var val *big.Int + if len(vetValue) > 0 { + val = vetValue[0] + } else { + val = big.NewInt(0) + } + return _{{$contract.Type}}Transactor.Transact( val, "{{.Original.Name}}" {{range .Normalized.Inputs}}, {{.Name}}{{end}}) } // {{.Normalized.Name}}AsClause is a transaction clause generator 0x{{printf "%x" .Original.ID}}. // // Solidity: {{.Original.String}} - func (_{{$contract.Type}} *{{$contract.Type}}) {{.Normalized.Name}}AsClause({{range .Normalized.Inputs}}{{.Name}} {{bindtype .Type $structs}}, {{end}}) (*tx.Clause, error) { - return _{{$contract.Type}}.contract.AsClause("{{.Original.Name}}" {{range .Normalized.Inputs}}, {{.Name}}{{end}}) + func (_{{$contract.Type}} *{{$contract.Type}}) {{.Normalized.Name}}AsClause({{range .Normalized.Inputs}}{{.Name}} {{bindtype .Type $structs}}, {{end}} vetValue ... *big.Int) (*tx.Clause, error) { + var val *big.Int + if len(vetValue) > 0 { + val = vetValue[0] + } else { + val = big.NewInt(0) + } + return _{{$contract.Type}}.contract.AsClauseWithVET(val, "{{.Original.Name}}" {{range .Normalized.Inputs}}, {{.Name}}{{end}}) } {{end}} @@ -304,7 +339,13 @@ var ( topicHash := _{{$contract.Type}}.contract.ABI.Events["{{.Normalized.Name}}"].ID {{ if gt $indexedArgCount 0 }} - criteriaSet := make([]client.EventCriteria, len(criteria)) + criteriaSet := make([]client.EventCriteria, len(criteria)) + {{ else }} + criteriaSet := make([]client.EventCriteria, 0) + {{ end }} + + {{ if gt $indexedArgCount 0 }} + for i, c := range criteria { crteria := client.EventCriteria{ Address: &_{{$contract.Type}}.contract.Address, @@ -342,20 +383,6 @@ var ( criteriaSet[i] = crteria } - - if len(criteriaSet) == 0 { - criteriaSet = append(criteriaSet, client.EventCriteria{ - Address: &_{{$contract.Type}}.contract.Address, - Topic0: &topicHash, // Add Topic0 here - }) - } - {{ else }} - criteriaSet := []client.EventCriteria{ - client.EventCriteria{ - Address: &_{{$contract.Type}}.contract.Address, - Topic0: &topicHash, - }, - } {{ end }} eventChan := make(chan *{{$contract.Type}}{{.Normalized.Name}}, 100) @@ -371,48 +398,47 @@ var ( for _, tx := range block.Transactions { for index, outputs := range tx.Outputs { for _, event := range outputs.Events { - if event.Address == _B3tr.contract.Address { - if event.Topics[0] == topicHash { - for _, c := range criteriaSet { - matches := true - if c.Topic1 != nil && *c.Topic1 != event.Topics[1] { - matches = false - } - if c.Topic2 != nil && *c.Topic2 != event.Topics[2] { - matches = false - } - if c.Topic3 != nil && *c.Topic3 != event.Topics[3] { - matches = false - } - if c.Topic4 != nil && *c.Topic4 != event.Topics[4] { - matches = false - } - - if matches { - log := client.EventLog{ - Address: &_B3tr.contract.Address, - Topics: event.Topics, - Data: event.Data, - Meta: client.LogMeta{ - BlockID: block.ID, - BlockNumber: block.Number, - BlockTime: block.Timestamp, - TxID: tx.ID, - TxOrigin: tx.Origin, - ClauseIndex: int64(index), - }, - } - - ev := new({{$contract.Type}}{{.Normalized.Name}}) - if err := _{{$contract.Type}}.contract.UnpackLog(ev, "{{.Normalized.Name}}", log); err != nil { - continue - } - ev.Log = log - eventChan <- ev - } - } + if event.Address != _{{$contract.Type}}.contract.Address { + continue + } + if topicHash != event.Topics[0] { + continue + } + for _, c := range criteriaSet { + if c.Topic1 != nil && *c.Topic1 != event.Topics[1] { + continue + } + if c.Topic2 != nil && *c.Topic2 != event.Topics[2] { + continue + } + if c.Topic3 != nil && *c.Topic3 != event.Topics[3] { + continue } + if c.Topic4 != nil && *c.Topic4 != event.Topics[4] { + continue + } + } + + log := client.EventLog{ + Address: &_{{$contract.Type}}.contract.Address, + Topics: event.Topics, + Data: event.Data, + Meta: client.LogMeta{ + BlockID: block.ID, + BlockNumber: block.Number, + BlockTime: block.Timestamp, + TxID: tx.ID, + TxOrigin: tx.Origin, + ClauseIndex: int64(index), + }, + } + + ev := new({{$contract.Type}}{{.Normalized.Name}}) + if err := _{{$contract.Type}}.contract.UnpackLog(ev, "{{.Normalized.Name}}", log); err != nil { + continue } + ev.Log = log + eventChan <- ev } } } diff --git a/cmd/thorgen/bind/template.go b/cmd/thorgen/template.go similarity index 99% rename from cmd/thorgen/bind/template.go rename to cmd/thorgen/template.go index 4a0062a..e9970ea 100644 --- a/cmd/thorgen/bind/template.go +++ b/cmd/thorgen/template.go @@ -14,7 +14,7 @@ // You should have received a copy of the GNU Lesser General Public License // along with the go-ethereum library. If not, see . -package bind +package main import ( _ "embed" diff --git a/internal/testcontainer/testcontainer.go b/internal/testcontainer/testcontainer.go index 6987c23..1efd303 100644 --- a/internal/testcontainer/testcontainer.go +++ b/internal/testcontainer/testcontainer.go @@ -42,11 +42,5 @@ func NewSolo() (*client.Client, func()) { os.Exit(1) } - clt, err := client.NewFromURL("http://" + endpoint) - if err != nil { - slog.Error("failed to create thor client", "error", err) - os.Exit(1) - } - - return clt, cancel + return client.NewFromURL("http://" + endpoint), cancel } diff --git a/thorgo.go b/thorgo.go index 2e972c4..241fc90 100644 --- a/thorgo.go +++ b/thorgo.go @@ -17,13 +17,9 @@ type Thor struct { Client *client.Client } -func NewFromURL(url string) (*Thor, error) { - c, err := client.NewFromURL(url) - if err != nil { - return nil, err - } - - return &Thor{Client: c, Blocks: blocks.New(c)}, nil +func New(url string) *Thor { + c := client.NewFromURL(url) + return &Thor{Client: c, Blocks: blocks.New(c)} } func NewFromClient(c *client.Client) *Thor { @@ -41,7 +37,7 @@ func (t *Thor) Transaction(hash common.Hash) *transactions.Visitor { return transactions.New(t.Client, hash) } -// Transactor creates a new transaction builder which makes it easier to build, simulate, build and send transactions. +// Transactor creates a new transaction builder which makes it easier to build, simulate and send transactions. func (t *Thor) Transactor(clauses []*tx.Clause) *transactions.Transactor { return transactions.NewTransactor(t.Client, clauses) } diff --git a/thorgo_test.go b/thorgo_test.go index 2e79beb..0e3686f 100644 --- a/thorgo_test.go +++ b/thorgo_test.go @@ -20,15 +20,12 @@ func TestMain(t *testing.M) { t.Run() } -func TestBadURL(t *testing.T) { - _, err := NewFromURL("http://localhost:80") - assert.Error(t, err) -} - func TestFromClient(t *testing.T) { thor := NewFromClient(thor.Client) assert.NotNil(t, thor) - assert.Equal(t, solo.ChainTag(), thor.Client.ChainTag()) + tag, err := thor.Client.ChainTag() + assert.NoError(t, err) + assert.Equal(t, solo.ChainTag(), tag) } func TestBlock(t *testing.T) { diff --git a/transactions/transactor.go b/transactions/transactor.go index bdd78ae..d4819a9 100644 --- a/transactions/transactor.go +++ b/transactions/transactor.go @@ -118,7 +118,10 @@ func (t *Transactor) Simulate(caller common.Address) (Simulation, error) { // Build constructs the transaction, applying defaults where necessary. func (t *Transactor) Build(caller common.Address) (*tx.Transaction, error) { initial := t.builder.Build() - chainTag := t.client.ChainTag() + chainTag, err := t.client.ChainTag() + if err != nil && initial.ChainTag() == 0 { + return nil, fmt.Errorf("failed to get chain tag: %w", err) + } builder := new(tx.Builder). GasPriceCoef(initial.GasPriceCoef()). diff --git a/txmanager/delegator_test.go b/txmanager/delegator_test.go index 547118f..e06b977 100644 --- a/txmanager/delegator_test.go +++ b/txmanager/delegator_test.go @@ -125,9 +125,9 @@ func TestNewDelegatedManager(t *testing.T) { gasPayer := txmanager.NewDelegator(solo.Keys()[1]) manager := txmanager.NewDelegatedManager(thor, origin, gasPayer) - contract := builtins.VTHO.Load(thor) + contract, _ := builtins.NewEnergyTransactor(thor, manager) - tx, err := contract.Send(manager, "transfer", common.Address{100}, big.NewInt(1000)) + tx, err := contract.Transfer(common.Address{100}, big.NewInt(1000)) assert.NoError(t, err) receipt, err := tx.Wait()