From 3dc0cb23a750fe63409c8c6b8c21ddcf4f973c82 Mon Sep 17 00:00:00 2001 From: Subway2023 <147013944+Subway2023@users.noreply.github.com> Date: Tue, 10 Oct 2023 14:09:10 +0800 Subject: [PATCH] rebuild crud, consensus, config (#237) Co-authored-by: sbw <954075159@qq.com> --- cmd/commandline/kvTable.go | 30 +- precompiled/config/system_config.go | 74 +- precompiled/config/system_config_service.go | 21 +- .../config/system_config_service_test.go | 73 +- precompiled/consensus/consensus.go | 162 ++++- precompiled/consensus/consensus_service.go | 26 +- .../consensus/consensus_service_test.go | 27 +- precompiled/crud/CRUD.sol | 22 - precompiled/crud/KVTable.go | 238 +++++++ precompiled/crud/crud_service.go | 277 -------- precompiled/crud/crud_service_test.go | 343 ---------- precompiled/crud/table.go | 150 ++-- precompiled/crud/tableManager.go | 80 ++- precompiled/crud/tableManager_service.go | 382 +++++++++++ precompiled/crud/tableManager_service_test.go | 646 ++++++++++++++++++ precompiled/solidity/auth/Account.sol | 23 + precompiled/solidity/auth/BasicAuth.sol | 29 + precompiled/solidity/auth/Committee.sol | 113 +++ .../solidity/auth/CommitteeManager.sol | 471 +++++++++++++ .../solidity/auth/ConsensusPrecompiled.sol | 12 + .../solidity/auth/ContractAuthPrecompiled.sol | 28 + precompiled/solidity/auth/ProposalManager.sol | 267 ++++++++ precompiled/solidity/auth/README.md | 1 + .../solidity/auth/SystemConfigPrecompiled.sol | 15 + .../solidity/auth/VoteComputerTemplate.sol | 47 ++ precompiled/solidity/bfs/BfsPrecompiled.sol | 28 + precompiled/{ => solidity}/cns/CNS.sol | 0 .../{ => solidity}/config/SystemConfig.sol | 0 .../{ => solidity}/consensus/Consensus.sol | 2 +- precompiled/solidity/crud/Cast.sol | 17 + precompiled/solidity/crud/EntryWrapper.sol | 101 +++ precompiled/solidity/crud/Table.sol | 85 +++ .../solidity/sharding/ShardingPrecompiled.sol | 9 + 33 files changed, 2955 insertions(+), 844 deletions(-) delete mode 100644 precompiled/crud/CRUD.sol create mode 100644 precompiled/crud/KVTable.go delete mode 100644 precompiled/crud/crud_service.go delete mode 100644 precompiled/crud/crud_service_test.go create mode 100644 precompiled/crud/tableManager_service.go create mode 100644 precompiled/crud/tableManager_service_test.go create mode 100644 precompiled/solidity/auth/Account.sol create mode 100644 precompiled/solidity/auth/BasicAuth.sol create mode 100644 precompiled/solidity/auth/Committee.sol create mode 100644 precompiled/solidity/auth/CommitteeManager.sol create mode 100644 precompiled/solidity/auth/ConsensusPrecompiled.sol create mode 100644 precompiled/solidity/auth/ContractAuthPrecompiled.sol create mode 100644 precompiled/solidity/auth/ProposalManager.sol create mode 100644 precompiled/solidity/auth/README.md create mode 100644 precompiled/solidity/auth/SystemConfigPrecompiled.sol create mode 100644 precompiled/solidity/auth/VoteComputerTemplate.sol create mode 100644 precompiled/solidity/bfs/BfsPrecompiled.sol rename precompiled/{ => solidity}/cns/CNS.sol (100%) rename precompiled/{ => solidity}/config/SystemConfig.sol (100%) rename precompiled/{ => solidity}/consensus/Consensus.sol (90%) create mode 100644 precompiled/solidity/crud/Cast.sol create mode 100644 precompiled/solidity/crud/EntryWrapper.sol create mode 100644 precompiled/solidity/crud/Table.sol create mode 100644 precompiled/solidity/sharding/ShardingPrecompiled.sol diff --git a/cmd/commandline/kvTable.go b/cmd/commandline/kvTable.go index d58c0cb1..a666c3d7 100644 --- a/cmd/commandline/kvTable.go +++ b/cmd/commandline/kvTable.go @@ -30,14 +30,14 @@ For more information please refer: value := args[2] var valueFields = []string{} valueFields = append(valueFields, value) - crudService, err := crud.NewCRUDService(RPC) + tableManagerService, err := crud.NewTableManagerService(RPC) if err != nil { - fmt.Printf("set failed, crud.NewCRUDService err: %v\n", err) + fmt.Printf("set failed, crud.NewTableManagerService err: %v\n", err) return } - result, err := crudService.CreateTable(tableName, key, valueFields) + result, err := tableManagerService.CreateTable(tableName, key, valueFields) if err != nil { - fmt.Printf("set failed, crudService.CreateTable err: %v\n", err) + fmt.Printf("set failed, tableManagerService.CreateTable err: %v\n", err) return } if result != 0 { @@ -76,19 +76,14 @@ For more information please refer: Key: key, Fields: valueFields, } - crudService, err := crud.NewCRUDService(RPC) + tableManagerService, err := crud.NewTableManagerService(RPC) if err != nil { - fmt.Printf("set failed, crud.NewCRUDService err: %v\n", err) + fmt.Printf("set failed, crud.NewTableManagerService err: %v\n", err) return } - _, err = crudService.OpenTable(tableName) + result, err := tableManagerService.Insert(tableName, entry) if err != nil { - fmt.Printf("set failed,crudService.OpenTable err: %v\n", err) - return - } - result, err := crudService.Insert(&entry) - if err != nil { - fmt.Printf("set failed, crudService.Insert err: %v\n", err) + fmt.Printf("set failed, tableManagerService.Insert err: %v\n", err) return } if result != 1 { @@ -118,17 +113,12 @@ For more information please refer: Run: func(cmd *cobra.Command, args []string) { tableName := args[0] key := args[1] - crudService, err := crud.NewCRUDService(RPC) + tableManagerService, err := crud.NewTableManagerService(RPC) if err != nil { fmt.Printf("get failed, consensus.NewConsensusService err: %v\n", err) return } - _, err = crudService.OpenTable(tableName) - if err != nil { - fmt.Printf("get failed,crudService.OpenTable err: %v\n", err) - return - } - result, err := crudService.Select(key) + result, err := tableManagerService.Select0(tableName, key) if err != nil { fmt.Printf("get failed, consensusService.AddObserver err: %v\n", err) return diff --git a/precompiled/config/system_config.go b/precompiled/config/system_config.go index 3ca12750..3605051c 100644 --- a/precompiled/config/system_config.go +++ b/precompiled/config/system_config.go @@ -25,7 +25,10 @@ var ( ) // ConfigABI is the input ABI used to generate the binding from. -const ConfigABI = "[{\"constant\":false,\"inputs\":[{\"name\":\"key\",\"type\":\"string\"},{\"name\":\"value\",\"type\":\"string\"}],\"name\":\"setValueByKey\",\"outputs\":[{\"name\":\"\",\"type\":\"int256\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]" +const ConfigABI = "[{\"inputs\":[{\"internalType\":\"string\",\"name\":\"key\",\"type\":\"string\"}],\"name\":\"getValueByKey\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"},{\"internalType\":\"int256\",\"name\":\"\",\"type\":\"int256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"key\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"value\",\"type\":\"string\"}],\"name\":\"setValueByKey\",\"outputs\":[{\"internalType\":\"int32\",\"name\":\"\",\"type\":\"int32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]" + +// ConfigBin is the compiled bytecode used for deploying new contracts. +var ConfigBin = "0x608060405234801561001057600080fd5b50610406806100206000396000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c80631258a93a1461003b578063bd291aef1461006c575b600080fd5b61005560048036038101906100509190610207565b61009c565b6040516100639291906102f1565b60405180910390f35b61008660048036038101906100819190610321565b6100a5565b60405161009391906103b5565b60405180910390f35b60606000915091565b600092915050565b6000604051905090565b600080fd5b600080fd5b600080fd5b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b610114826100cb565b810181811067ffffffffffffffff82111715610133576101326100dc565b5b80604052505050565b60006101466100ad565b9050610152828261010b565b919050565b600067ffffffffffffffff821115610172576101716100dc565b5b61017b826100cb565b9050602081019050919050565b82818337600083830152505050565b60006101aa6101a584610157565b61013c565b9050828152602081018484840111156101c6576101c56100c6565b5b6101d1848285610188565b509392505050565b600082601f8301126101ee576101ed6100c1565b5b81356101fe848260208601610197565b91505092915050565b60006020828403121561021d5761021c6100b7565b5b600082013567ffffffffffffffff81111561023b5761023a6100bc565b5b610247848285016101d9565b91505092915050565b600081519050919050565b600082825260208201905092915050565b60005b8381101561028a57808201518184015260208101905061026f565b83811115610299576000848401525b50505050565b60006102aa82610250565b6102b4818561025b565b93506102c481856020860161026c565b6102cd816100cb565b840191505092915050565b6000819050919050565b6102eb816102d8565b82525050565b6000604082019050818103600083015261030b818561029f565b905061031a60208301846102e2565b9392505050565b60008060408385031215610338576103376100b7565b5b600083013567ffffffffffffffff811115610356576103556100bc565b5b610362858286016101d9565b925050602083013567ffffffffffffffff811115610383576103826100bc565b5b61038f858286016101d9565b9150509250929050565b60008160030b9050919050565b6103af81610399565b82525050565b60006020820190506103ca60008301846103a6565b9291505056fea26469706673582212207bb572c2d45fbfc66c4f7051acb78da418cfff1f4aaf059601a3c6d758a1c22c64736f6c634300080b0033" // Config is an auto generated Go binding around a Solidity contract. type Config struct { @@ -146,8 +149,8 @@ func (_Config *ConfigRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, } // Transact invokes the (paid) contract method with params as input values. -func (_Config *ConfigRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, *types.Receipt, error) { - return _Config.Contract.ConfigTransactor.contract.Transact(opts, method, params...) +func (_Config *ConfigRaw) TransactWithResult(opts *bind.TransactOpts, result interface{}, method string, params ...interface{}) (*types.Transaction, *types.Receipt, error) { + return _Config.Contract.ConfigTransactor.contract.TransactWithResult(opts, result, method, params...) } // Call invokes the (constant) contract method with params as input values and @@ -165,27 +168,74 @@ func (_Config *ConfigTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Tr } // Transact invokes the (paid) contract method with params as input values. -func (_Config *ConfigTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, *types.Receipt, error) { - return _Config.Contract.contract.Transact(opts, method, params...) +func (_Config *ConfigTransactorRaw) TransactWithResult(opts *bind.TransactOpts, result interface{}, method string, params ...interface{}) (*types.Transaction, *types.Receipt, error) { + return _Config.Contract.contract.TransactWithResult(opts, result, method, params...) +} + +// GetValueByKey is a free data retrieval call binding the contract method 0x1258a93a. +// +// Solidity: function getValueByKey(string key) constant returns(string, int256) +func (_Config *ConfigCaller) GetValueByKey(opts *bind.CallOpts, key string) (string, *big.Int, error) { + var ( + ret0 = new(string) + ret1 = new(*big.Int) + ) + out := &[]interface{}{ + ret0, + ret1, + } + err := _Config.contract.Call(opts, out, "getValueByKey", key) + return *ret0, *ret1, err +} + +// GetValueByKey is a free data retrieval call binding the contract method 0x1258a93a. +// +// Solidity: function getValueByKey(string key) constant returns(string, int256) +func (_Config *ConfigSession) GetValueByKey(key string) (string, *big.Int, error) { + return _Config.Contract.GetValueByKey(&_Config.CallOpts, key) +} + +// GetValueByKey is a free data retrieval call binding the contract method 0x1258a93a. +// +// Solidity: function getValueByKey(string key) constant returns(string, int256) +func (_Config *ConfigCallerSession) GetValueByKey(key string) (string, *big.Int, error) { + return _Config.Contract.GetValueByKey(&_Config.CallOpts, key) } // SetValueByKey is a paid mutator transaction binding the contract method 0xbd291aef. // -// Solidity: function setValueByKey(string key, string value) returns(int256) -func (_Config *ConfigTransactor) SetValueByKey(opts *bind.TransactOpts, key string, value string) (*types.Transaction, *types.Receipt, error) { - return _Config.contract.Transact(opts, "setValueByKey", key, value) +// Solidity: function setValueByKey(string key, string value) returns(int32) +func (_Config *ConfigTransactor) SetValueByKey(opts *bind.TransactOpts, key string, value string) (int32, *types.Transaction, *types.Receipt, error) { + var ( + ret0 = new(int32) + ) + out := ret0 + transaction, receipt, err := _Config.contract.TransactWithResult(opts, out, "setValueByKey", key, value) + return *ret0, transaction, receipt, err +} + +func (_Config *ConfigTransactor) AsyncSetValueByKey(handler func(*types.Receipt, error), opts *bind.TransactOpts, key string, value string) (*types.Transaction, error) { + return _Config.contract.AsyncTransact(opts, handler, "setValueByKey", key, value) } // SetValueByKey is a paid mutator transaction binding the contract method 0xbd291aef. // -// Solidity: function setValueByKey(string key, string value) returns(int256) -func (_Config *ConfigSession) SetValueByKey(key string, value string) (*types.Transaction, *types.Receipt, error) { +// Solidity: function setValueByKey(string key, string value) returns(int32) +func (_Config *ConfigSession) SetValueByKey(key string, value string) (int32, *types.Transaction, *types.Receipt, error) { return _Config.Contract.SetValueByKey(&_Config.TransactOpts, key, value) } +func (_Config *ConfigSession) AsyncSetValueByKey(handler func(*types.Receipt, error), key string, value string) (*types.Transaction, error) { + return _Config.Contract.AsyncSetValueByKey(handler, &_Config.TransactOpts, key, value) +} + // SetValueByKey is a paid mutator transaction binding the contract method 0xbd291aef. // -// Solidity: function setValueByKey(string key, string value) returns(int256) -func (_Config *ConfigTransactorSession) SetValueByKey(key string, value string) (*types.Transaction, *types.Receipt, error) { +// Solidity: function setValueByKey(string key, string value) returns(int32) +func (_Config *ConfigTransactorSession) SetValueByKey(key string, value string) (int32, *types.Transaction, *types.Receipt, error) { return _Config.Contract.SetValueByKey(&_Config.TransactOpts, key, value) } + +func (_Config *ConfigTransactorSession) AsyncSetValueByKey(handler func(*types.Receipt, error), key string, value string) (*types.Transaction, error) { + return _Config.Contract.AsyncSetValueByKey(handler, &_Config.TransactOpts, key, value) +} diff --git a/precompiled/config/system_config_service.go b/precompiled/config/system_config_service.go index b7f9a692..6e179e21 100644 --- a/precompiled/config/system_config_service.go +++ b/precompiled/config/system_config_service.go @@ -7,12 +7,14 @@ import ( "github.com/FISCO-BCOS/go-sdk/core/types" "github.com/FISCO-BCOS/go-sdk/precompiled" "github.com/ethereum/go-ethereum/common" + "github.com/FISCO-BCOS/go-sdk/abi/bind" ) // SystemConfigService is a precompile contract service. type SystemConfigService struct { - systemConfig *Config - client *client.Client + systemConfig *Config + systemConfigAuth *bind.TransactOpts + client *client.Client } // systemConfig precompiled contract error code @@ -55,12 +57,13 @@ func NewSystemConfigService(client *client.Client) (*SystemConfigService, error) if err != nil { return nil, fmt.Errorf("construct SystemConfigService failed: %+v", err) } - return &SystemConfigService{systemConfig: instance, client: client}, nil + auth := client.GetTransactOpts() + return &SystemConfigService{systemConfig: instance, systemConfigAuth:auth, client: client}, nil } // SetValueByKey returns nil if there is no error occurred. func (s *SystemConfigService) SetValueByKey(key string, value string) (int64, error) { - _, receipt, err := s.systemConfig.SetValueByKey(s.client.GetTransactOpts(), key, value) + _, _, receipt, err := s.systemConfig.SetValueByKey(s.client.GetTransactOpts(), key, value) if err != nil { return types.PrecompiledError, fmt.Errorf("client.WaitMined failed, err: %v", err) } @@ -78,3 +81,13 @@ func (s *SystemConfigService) SetValueByKey(key string, value string) (int64, er } return errorCode, errorCodeToError(errorCode) } + +func (s *SystemConfigService) GetValueByKey(key string) (string, int64, error) { + opts := &bind.CallOpts{From: s.systemConfigAuth.From} + fmt.Println("opts",opts) + ret0, ret1, err := s.systemConfig.GetValueByKey(opts, key) + if err != nil { + return "", precompiled.DefaultErrorCode, fmt.Errorf("systemConfigService getValueByKey failed: %+v", err) + } + return ret0, ret1.Int64(), nil +} diff --git a/precompiled/config/system_config_service_test.go b/precompiled/config/system_config_service_test.go index 94ea2293..0e2b8969 100644 --- a/precompiled/config/system_config_service_test.go +++ b/precompiled/config/system_config_service_test.go @@ -4,52 +4,65 @@ import ( "context" "encoding/hex" "testing" + "os" "github.com/FISCO-BCOS/go-sdk/client" ) -func testSetValueByKey(t *testing.T, key string, value string) { - privateKey, _ := hex.DecodeString("b89d42f12290070f235fb8fb61dcf96e3b11516c5d4f6333f26e49bb955f8b62") +const ( + standardOutput = 0 + key = "tx_count_limit" + value = "30000000" +) + +func getClient(t *testing.T) *client.Client { + privateKey, _ := hex.DecodeString("145e247e170ba3afd6ae97e88f00dbc976c2345d511b0f6713355d19d8b80b58") config := &client.Config{IsSMCrypto: false, GroupID: "group0", PrivateKey: privateKey, Host: "127.0.0.1", Port: 20200, TLSCaFile: "./ca.crt", TLSKeyFile: "./sdk.key", TLSCertFile: "./sdk.crt"} c, err := client.DialContext(context.Background(), config) if err != nil { - t.Fatalf("init client failed: %+v", err) + t.Fatalf("Dial to %s:%d failed of %v", config.Host, config.Port, err) } - service, err := NewSystemConfigService(c) + return c +} + +func getService(t *testing.T) { + c := getClient(t) + newService, err := NewSystemConfigService(c) if err != nil { - t.Fatalf("init SystemConfigService failed: %+v", err) + t.Fatalf("init CnsService failed: %+v", err) } + service = newService +} + +var ( + service *SystemConfigService +) + +func TestMain(m *testing.M) { + getService(&testing.T{}) + exitCode := m.Run() + os.Exit(exitCode) +} - num, err := service.SetValueByKey(key, value) +func TestSetValueByKey(t *testing.T) { + result, err := service.SetValueByKey(key, value) if err != nil { - t.Fatalf("SystemConfigService SetValueByKey failed: %+v", err) + t.Fatalf("Service RegisterCns failed: %+v\n", err) } - if num != 0 { - t.Fatalf("testSetValueByKey failed, the result %v is inconsistent with \"1\"", num) + if result != standardOutput { + t.Fatalf("TestRegisterCns failed, the result %v is inconsistent with \"%v\"", result, standardOutput) } + t.Logf("TestRegisterCns result: %v", result) +} - result, err := c.GetSystemConfigByKey(context.Background(), key) +func TestGetValueByKey(t *testing.T) { + ret0, _, err := service.GetValueByKey(key) if err != nil { - t.Fatalf("GetSystemConfigByKey failed: %v", err) + t.Fatalf("Service GetValueByKey failed: %+v\n", err) } - t.Logf("set %s value: %s, GetSystemConfigByKey: %s", key, value, result.GetValue()) - //t.Logf("set %s value: %s, GetSystemConfigByKey: %s", key, value, result[1:len(result)-1]) - if value != result.GetValue() { - t.Fatalf("SetValueByKey failed!") + if ret0 != value { + t.Fatalf("TestGetValueByKey failed, the ret0 %v is inconsistent with \"%v\"", ret0, value) } -} - -func TestSetValueByKey(t *testing.T) { - // test tx_count_limit - testSetValueByKey(t, "tx_count_limit", "30000000") - - // test tx_gas_limit - testSetValueByKey(t, "tx_gas_limit", "3000000000") - - // test rpbft_epoch_sealer_num - //testSetValueByKey(t, "rpbft_epoch_sealer_num", "20") - - // test rpbft_epoch_block_num - //testSetValueByKey(t, "rpbft_epoch_block_num", "100") -} + t.Logf("TestGetValueByKey ret0: %v", ret0) +} \ No newline at end of file diff --git a/precompiled/consensus/consensus.go b/precompiled/consensus/consensus.go index cd224e4b..c5d818f3 100644 --- a/precompiled/consensus/consensus.go +++ b/precompiled/consensus/consensus.go @@ -25,7 +25,10 @@ var ( ) // ConsensusABI is the input ABI used to generate the binding from. -const ConsensusABI = "[{\"constant\":false,\"inputs\":[{\"name\":\"\",\"type\":\"string\"}],\"name\":\"addObserver\",\"outputs\":[{\"name\":\"\",\"type\":\"int32\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"\",\"type\":\"string\"},{\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"addSealer\",\"outputs\":[{\"name\":\"\",\"type\":\"int32\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"\",\"type\":\"string\"}],\"name\":\"remove\",\"outputs\":[{\"name\":\"\",\"type\":\"int32\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"\",\"type\":\"string\"},{\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"setWeight\",\"outputs\":[{\"name\":\"\",\"type\":\"int32\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]" +const ConsensusABI = "[{\"inputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"name\":\"addObserver\",\"outputs\":[{\"internalType\":\"int32\",\"name\":\"\",\"type\":\"int32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"addSealer\",\"outputs\":[{\"internalType\":\"int32\",\"name\":\"\",\"type\":\"int32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"name\":\"remove\",\"outputs\":[{\"internalType\":\"int32\",\"name\":\"\",\"type\":\"int32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"setWeight\",\"outputs\":[{\"internalType\":\"int32\",\"name\":\"\",\"type\":\"int32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]" + +// ConsensusBin is the compiled bytecode used for deploying new contracts. +var ConsensusBin = "0x608060405234801561001057600080fd5b506103d1806100206000396000f3fe608060405234801561001057600080fd5b506004361061004c5760003560e01c80632800efc014610051578063359168561461008157806380599e4b146100b1578063ce6fa5c5146100e1575b600080fd5b61006b60048036038101906100669190610289565b610111565b60405161007891906102ee565b60405180910390f35b61009b6004803603810190610096919061033f565b610118565b6040516100a891906102ee565b60405180910390f35b6100cb60048036038101906100c69190610289565b610120565b6040516100d891906102ee565b60405180910390f35b6100fb60048036038101906100f6919061033f565b610127565b60405161010891906102ee565b60405180910390f35b6000919050565b600092915050565b6000919050565b600092915050565b6000604051905090565b600080fd5b600080fd5b600080fd5b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6101968261014d565b810181811067ffffffffffffffff821117156101b5576101b461015e565b5b80604052505050565b60006101c861012f565b90506101d4828261018d565b919050565b600067ffffffffffffffff8211156101f4576101f361015e565b5b6101fd8261014d565b9050602081019050919050565b82818337600083830152505050565b600061022c610227846101d9565b6101be565b90508281526020810184848401111561024857610247610148565b5b61025384828561020a565b509392505050565b600082601f8301126102705761026f610143565b5b8135610280848260208601610219565b91505092915050565b60006020828403121561029f5761029e610139565b5b600082013567ffffffffffffffff8111156102bd576102bc61013e565b5b6102c98482850161025b565b91505092915050565b60008160030b9050919050565b6102e8816102d2565b82525050565b600060208201905061030360008301846102df565b92915050565b6000819050919050565b61031c81610309565b811461032757600080fd5b50565b60008135905061033981610313565b92915050565b6000806040838503121561035657610355610139565b5b600083013567ffffffffffffffff8111156103745761037361013e565b5b6103808582860161025b565b92505060206103918582860161032a565b915050925092905056fea2646970667358221220f9bf1c92bf30c11b640bf87ec39377551d33a2375d32f144e87f2bc541dc28ab64736f6c634300080b0033" // Consensus is an auto generated Go binding around a Solidity contract. type Consensus struct { @@ -146,8 +149,8 @@ func (_Consensus *ConsensusRaw) Transfer(opts *bind.TransactOpts) (*types.Transa } // Transact invokes the (paid) contract method with params as input values. -func (_Consensus *ConsensusRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, *types.Receipt, error) { - return _Consensus.Contract.ConsensusTransactor.contract.Transact(opts, method, params...) +func (_Consensus *ConsensusRaw) TransactWithResult(opts *bind.TransactOpts, result interface{}, method string, params ...interface{}) (*types.Transaction, *types.Receipt, error) { + return _Consensus.Contract.ConsensusTransactor.contract.TransactWithResult(opts, result, method, params...) } // Call invokes the (constant) contract method with params as input values and @@ -165,69 +168,158 @@ func (_Consensus *ConsensusTransactorRaw) Transfer(opts *bind.TransactOpts) (*ty } // Transact invokes the (paid) contract method with params as input values. -func (_Consensus *ConsensusTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, *types.Receipt, error) { - return _Consensus.Contract.contract.Transact(opts, method, params...) +func (_Consensus *ConsensusTransactorRaw) TransactWithResult(opts *bind.TransactOpts, result interface{}, method string, params ...interface{}) (*types.Transaction, *types.Receipt, error) { + return _Consensus.Contract.contract.TransactWithResult(opts, result, method, params...) } // AddObserver is a paid mutator transaction binding the contract method 0x2800efc0. // -// Solidity: function addObserver(string nodeID) returns(int256) -func (_Consensus *ConsensusTransactor) AddObserver(opts *bind.TransactOpts, nodeID string) (*types.Transaction, *types.Receipt, error) { - return _Consensus.contract.Transact(opts, "addObserver", nodeID) +// Solidity: function addObserver(string ) returns(int32) +func (_Consensus *ConsensusTransactor) AddObserver(opts *bind.TransactOpts, arg0 string) (int32, *types.Transaction, *types.Receipt, error) { + var ( + ret0 = new(int32) + ) + out := ret0 + transaction, receipt, err := _Consensus.contract.TransactWithResult(opts, out, "addObserver", arg0) + return *ret0, transaction, receipt, err +} + +func (_Consensus *ConsensusTransactor) AsyncAddObserver(handler func(*types.Receipt, error), opts *bind.TransactOpts, arg0 string) (*types.Transaction, error) { + return _Consensus.contract.AsyncTransact(opts, handler, "addObserver", arg0) } // AddObserver is a paid mutator transaction binding the contract method 0x2800efc0. // -// Solidity: function addObserver(string nodeID) returns(int256) -func (_Consensus *ConsensusSession) AddObserver(nodeID string) (*types.Transaction, *types.Receipt, error) { - return _Consensus.Contract.AddObserver(&_Consensus.TransactOpts, nodeID) +// Solidity: function addObserver(string ) returns(int32) +func (_Consensus *ConsensusSession) AddObserver(arg0 string) (int32, *types.Transaction, *types.Receipt, error) { + return _Consensus.Contract.AddObserver(&_Consensus.TransactOpts, arg0) +} + +func (_Consensus *ConsensusSession) AsyncAddObserver(handler func(*types.Receipt, error), arg0 string) (*types.Transaction, error) { + return _Consensus.Contract.AsyncAddObserver(handler, &_Consensus.TransactOpts, arg0) } // AddObserver is a paid mutator transaction binding the contract method 0x2800efc0. // -// Solidity: function addObserver(string nodeID) returns(int256) -func (_Consensus *ConsensusTransactorSession) AddObserver(nodeID string) (*types.Transaction, *types.Receipt, error) { - return _Consensus.Contract.AddObserver(&_Consensus.TransactOpts, nodeID) +// Solidity: function addObserver(string ) returns(int32) +func (_Consensus *ConsensusTransactorSession) AddObserver(arg0 string) (int32, *types.Transaction, *types.Receipt, error) { + return _Consensus.Contract.AddObserver(&_Consensus.TransactOpts, arg0) } -// AddSealer is a paid mutator transaction binding the contract method 0x89152d1f. +func (_Consensus *ConsensusTransactorSession) AsyncAddObserver(handler func(*types.Receipt, error), arg0 string) (*types.Transaction, error) { + return _Consensus.Contract.AsyncAddObserver(handler, &_Consensus.TransactOpts, arg0) +} + +// AddSealer is a paid mutator transaction binding the contract method 0x35916856. // -// Solidity: function addSealer(string nodeID) returns(int256) -func (_Consensus *ConsensusTransactor) AddSealer(opts *bind.TransactOpts, nodeID string, weight *big.Int) (*types.Transaction, *types.Receipt, error) { - return _Consensus.contract.Transact(opts, "addSealer", nodeID, weight) +// Solidity: function addSealer(string , uint256 ) returns(int32) +func (_Consensus *ConsensusTransactor) AddSealer(opts *bind.TransactOpts, arg0 string, arg1 *big.Int) (int32, *types.Transaction, *types.Receipt, error) { + var ( + ret0 = new(int32) + ) + out := ret0 + transaction, receipt, err := _Consensus.contract.TransactWithResult(opts, out, "addSealer", arg0, arg1) + return *ret0, transaction, receipt, err +} + +func (_Consensus *ConsensusTransactor) AsyncAddSealer(handler func(*types.Receipt, error), opts *bind.TransactOpts, arg0 string, arg1 *big.Int) (*types.Transaction, error) { + return _Consensus.contract.AsyncTransact(opts, handler, "addSealer", arg0, arg1) } -// AddSealer is a paid mutator transaction binding the contract method 0x89152d1f. +// AddSealer is a paid mutator transaction binding the contract method 0x35916856. // -// Solidity: function addSealer(string nodeID) returns(int256) -func (_Consensus *ConsensusSession) AddSealer(nodeID string, weight *big.Int) (*types.Transaction, *types.Receipt, error) { - return _Consensus.Contract.AddSealer(&_Consensus.TransactOpts, nodeID, weight) +// Solidity: function addSealer(string , uint256 ) returns(int32) +func (_Consensus *ConsensusSession) AddSealer(arg0 string, arg1 *big.Int) (int32, *types.Transaction, *types.Receipt, error) { + return _Consensus.Contract.AddSealer(&_Consensus.TransactOpts, arg0, arg1) } -// AddSealer is a paid mutator transaction binding the contract method 0x89152d1f. +func (_Consensus *ConsensusSession) AsyncAddSealer(handler func(*types.Receipt, error), arg0 string, arg1 *big.Int) (*types.Transaction, error) { + return _Consensus.Contract.AsyncAddSealer(handler, &_Consensus.TransactOpts, arg0, arg1) +} + +// AddSealer is a paid mutator transaction binding the contract method 0x35916856. // -// Solidity: function addSealer(string nodeID) returns(int256) -func (_Consensus *ConsensusTransactorSession) AddSealer(nodeID string, weight *big.Int) (*types.Transaction, *types.Receipt, error) { - return _Consensus.Contract.AddSealer(&_Consensus.TransactOpts, nodeID, weight) +// Solidity: function addSealer(string , uint256 ) returns(int32) +func (_Consensus *ConsensusTransactorSession) AddSealer(arg0 string, arg1 *big.Int) (int32, *types.Transaction, *types.Receipt, error) { + return _Consensus.Contract.AddSealer(&_Consensus.TransactOpts, arg0, arg1) +} + +func (_Consensus *ConsensusTransactorSession) AsyncAddSealer(handler func(*types.Receipt, error), arg0 string, arg1 *big.Int) (*types.Transaction, error) { + return _Consensus.Contract.AsyncAddSealer(handler, &_Consensus.TransactOpts, arg0, arg1) } // Remove is a paid mutator transaction binding the contract method 0x80599e4b. // -// Solidity: function remove(string nodeID) returns(int256) -func (_Consensus *ConsensusTransactor) Remove(opts *bind.TransactOpts, nodeID string) (*types.Transaction, *types.Receipt, error) { - return _Consensus.contract.Transact(opts, "remove", nodeID) +// Solidity: function remove(string ) returns(int32) +func (_Consensus *ConsensusTransactor) Remove(opts *bind.TransactOpts, arg0 string) (int32, *types.Transaction, *types.Receipt, error) { + var ( + ret0 = new(int32) + ) + out := ret0 + transaction, receipt, err := _Consensus.contract.TransactWithResult(opts, out, "remove", arg0) + return *ret0, transaction, receipt, err +} + +func (_Consensus *ConsensusTransactor) AsyncRemove(handler func(*types.Receipt, error), opts *bind.TransactOpts, arg0 string) (*types.Transaction, error) { + return _Consensus.contract.AsyncTransact(opts, handler, "remove", arg0) } // Remove is a paid mutator transaction binding the contract method 0x80599e4b. // -// Solidity: function remove(string nodeID) returns(int256) -func (_Consensus *ConsensusSession) Remove(nodeID string) (*types.Transaction, *types.Receipt, error) { - return _Consensus.Contract.Remove(&_Consensus.TransactOpts, nodeID) +// Solidity: function remove(string ) returns(int32) +func (_Consensus *ConsensusSession) Remove(arg0 string) (int32, *types.Transaction, *types.Receipt, error) { + return _Consensus.Contract.Remove(&_Consensus.TransactOpts, arg0) +} + +func (_Consensus *ConsensusSession) AsyncRemove(handler func(*types.Receipt, error), arg0 string) (*types.Transaction, error) { + return _Consensus.Contract.AsyncRemove(handler, &_Consensus.TransactOpts, arg0) } // Remove is a paid mutator transaction binding the contract method 0x80599e4b. // -// Solidity: function remove(string nodeID) returns(int256) -func (_Consensus *ConsensusTransactorSession) Remove(nodeID string) (*types.Transaction, *types.Receipt, error) { - return _Consensus.Contract.Remove(&_Consensus.TransactOpts, nodeID) +// Solidity: function remove(string ) returns(int32) +func (_Consensus *ConsensusTransactorSession) Remove(arg0 string) (int32, *types.Transaction, *types.Receipt, error) { + return _Consensus.Contract.Remove(&_Consensus.TransactOpts, arg0) } + +func (_Consensus *ConsensusTransactorSession) AsyncRemove(handler func(*types.Receipt, error), arg0 string) (*types.Transaction, error) { + return _Consensus.Contract.AsyncRemove(handler, &_Consensus.TransactOpts, arg0) +} + +// SetWeight is a paid mutator transaction binding the contract method 0xce6fa5c5. +// +// Solidity: function setWeight(string , uint256 ) returns(int32) +func (_Consensus *ConsensusTransactor) SetWeight(opts *bind.TransactOpts, arg0 string, arg1 *big.Int) (int32, *types.Transaction, *types.Receipt, error) { + var ( + ret0 = new(int32) + ) + out := ret0 + transaction, receipt, err := _Consensus.contract.TransactWithResult(opts, out, "setWeight", arg0, arg1) + return *ret0, transaction, receipt, err +} + +func (_Consensus *ConsensusTransactor) AsyncSetWeight(handler func(*types.Receipt, error), opts *bind.TransactOpts, arg0 string, arg1 *big.Int) (*types.Transaction, error) { + return _Consensus.contract.AsyncTransact(opts, handler, "setWeight", arg0, arg1) +} + +// SetWeight is a paid mutator transaction binding the contract method 0xce6fa5c5. +// +// Solidity: function setWeight(string , uint256 ) returns(int32) +func (_Consensus *ConsensusSession) SetWeight(arg0 string, arg1 *big.Int) (int32, *types.Transaction, *types.Receipt, error) { + return _Consensus.Contract.SetWeight(&_Consensus.TransactOpts, arg0, arg1) +} + +func (_Consensus *ConsensusSession) AsyncSetWeight(handler func(*types.Receipt, error), arg0 string, arg1 *big.Int) (*types.Transaction, error) { + return _Consensus.Contract.AsyncSetWeight(handler, &_Consensus.TransactOpts, arg0, arg1) +} + +// SetWeight is a paid mutator transaction binding the contract method 0xce6fa5c5. +// +// Solidity: function setWeight(string , uint256 ) returns(int32) +func (_Consensus *ConsensusTransactorSession) SetWeight(arg0 string, arg1 *big.Int) (int32, *types.Transaction, *types.Receipt, error) { + return _Consensus.Contract.SetWeight(&_Consensus.TransactOpts, arg0, arg1) +} + +func (_Consensus *ConsensusTransactorSession) AsyncSetWeight(handler func(*types.Receipt, error), arg0 string, arg1 *big.Int) (*types.Transaction, error) { + return _Consensus.Contract.AsyncSetWeight(handler, &_Consensus.TransactOpts, arg0, arg1) +} \ No newline at end of file diff --git a/precompiled/consensus/consensus_service.go b/precompiled/consensus/consensus_service.go index 86bd5131..59df4223 100644 --- a/precompiled/consensus/consensus_service.go +++ b/precompiled/consensus/consensus_service.go @@ -98,7 +98,7 @@ func (service *Service) AddObserver(nodeID string) (int64, error) { return precompiled.DefaultErrorCode, fmt.Errorf("the node is already in the observer list") } } - _, receipt, err := service.consensus.AddObserver(service.consensusAuth, nodeID) + _, _, receipt, err := service.consensus.AddObserver(service.consensusAuth, nodeID) if err != nil { return precompiled.DefaultErrorCode, fmt.Errorf("ConsensusService addObserver failed: %+v", err) } @@ -132,11 +132,10 @@ func (service *Service) AddSealer(nodeID string, weight int64) (int64, error) { } } - tx, receipt, err := service.consensus.AddSealer(service.consensusAuth, nodeID, big.NewInt(weight)) + _, _, receipt, err := service.consensus.AddSealer(service.consensusAuth, nodeID, big.NewInt(weight)) if err != nil { return precompiled.DefaultErrorCode, fmt.Errorf("ConsensusService addSealer failed: %+v", err) } - _ = tx return parseReturnValue(receipt, "addSealer") } @@ -164,7 +163,7 @@ func (service *Service) RemoveNode(nodeID string) (int64, error) { return precompiled.DefaultErrorCode, fmt.Errorf("the node is not a group peer") } - _, receipt, err := service.consensus.Remove(service.consensusAuth, nodeID) + _, _, receipt, err := service.consensus.Remove(service.consensusAuth, nodeID) // maybe will occur something wrong // when request the receipt from the SDK since the connected node of SDK is removed //TODO: how to handle the problem that can't get the tx receipt when remove the connected node of SDK @@ -194,6 +193,25 @@ func (service *Service) isValidNodeID(nodeID string) (bool, error) { return flag, nil } +func (service *Service) SetWeight(nodeID string, weight int64) (int64, error) { + sealerRaw, err := service.client.GetSealerList(context.Background()) + if err != nil { + return precompiled.DefaultErrorCode, fmt.Errorf("get the sealer list failed: %v", err) + } + + var nodeIDs []nodeIdList + err = json.Unmarshal(sealerRaw, &nodeIDs) + if err != nil { + return precompiled.DefaultErrorCode, fmt.Errorf("unmarshal the sealer list failed: %v", err) + } + + _, _, receipt, err := service.consensus.SetWeight(service.consensusAuth, nodeID, big.NewInt(weight)) + if err != nil { + return precompiled.DefaultErrorCode, fmt.Errorf("ConsensusService setWeight failed: %+v", err) + } + return parseReturnValue(receipt, "setWeight") +} + func parseReturnValue(receipt *types.Receipt, name string) (int64, error) { errorMessage := receipt.GetErrorMessage() if errorMessage != "" { diff --git a/precompiled/consensus/consensus_service_test.go b/precompiled/consensus/consensus_service_test.go index 7f08049f..48854947 100644 --- a/precompiled/consensus/consensus_service_test.go +++ b/precompiled/consensus/consensus_service_test.go @@ -11,11 +11,12 @@ import ( ) const ( - standardOutput = 1 + standardOutput = 0 ) var ( nodeID = "" + weight = 100 service *Service ) @@ -41,7 +42,7 @@ func getService(t *testing.T) { func getNodeID(t *testing.T) { c := getClient(t) - sealerList, err := c.GetNodeIDList(context.Background()) + sealerList, err := c.GetSealerList(context.Background()) if err != nil { t.Fatalf("sealer list not found: %v", err) } @@ -125,3 +126,25 @@ func TestRemove(t *testing.T) { } t.Logf("Sealer list after excute RemoveNode: %s\n", observer) } + +func TestSetWeight(t *testing.T) { + observer, err := service.client.GetSealerList(context.Background()) + if err != nil { + t.Fatalf("ConsensusService GetSealerList failed: %+v\n", err) + } + t.Logf("Sealer list before excute RemoveNode: %s\n", observer) + + result, err := service.SetWeight(nodeID, int64(weight)) + if err != nil { + t.Fatalf("ConsensusService Remove failed: %+v\n", err) + } + if result != standardOutput { + t.Fatalf("TestSetWeight failed, the result \"%v\" is inconsistent with \"%v\"", result, standardOutput) + } + + observer, err = service.client.GetSealerList(context.Background()) + if err != nil { + t.Fatalf("ConsensusService invoke GetSealerList second time failed: %+v\n", err) + } + t.Logf("Sealer list after excute SetWeight: %s\n", observer) +} diff --git a/precompiled/crud/CRUD.sol b/precompiled/crud/CRUD.sol deleted file mode 100644 index 82cad244..00000000 --- a/precompiled/crud/CRUD.sol +++ /dev/null @@ -1,22 +0,0 @@ -pragma solidity ^0.4.24; - -contract CRUDPrecompiled { - function insert(string tableName, string key, string entry, string) - public - returns (int256); - function remove(string tableName, string key, string condition, string) - public - returns (int256); - function select(string tableName, string key, string condition, string) - public - view - returns (string); - function desc(string tableName) public view returns (string, string); - function update( - string tableName, - string key, - string entry, - string condition, - string - ) public returns (int256); -} diff --git a/precompiled/crud/KVTable.go b/precompiled/crud/KVTable.go new file mode 100644 index 00000000..df316b8c --- /dev/null +++ b/precompiled/crud/KVTable.go @@ -0,0 +1,238 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package crud + +import ( + "math/big" + "strings" + + "github.com/FISCO-BCOS/go-sdk/abi" + "github.com/FISCO-BCOS/go-sdk/abi/bind" + "github.com/FISCO-BCOS/go-sdk/core/types" + ethereum "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/common" +) + +// Reference imports to suppress errors if they are not otherwise used. +var ( + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = abi.U256 + _ = bind.Bind + _ = common.Big1 +) + +// KVTableABI is the input ABI used to generate the binding from. +const KVTableABI = "[{\"inputs\":[{\"internalType\":\"string\",\"name\":\"key\",\"type\":\"string\"}],\"name\":\"get\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"},{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"key\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"value\",\"type\":\"string\"}],\"name\":\"set\",\"outputs\":[{\"internalType\":\"int32\",\"name\":\"\",\"type\":\"int32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]" + +// KVTable is an auto generated Go binding around a Solidity contract. +type KVTable struct { + KVTableCaller // Read-only binding to the contract + KVTableTransactor // Write-only binding to the contract + KVTableFilterer // Log filterer for contract events +} + +// KVTableCaller is an auto generated read-only Go binding around a Solidity contract. +type KVTableCaller struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// KVTableTransactor is an auto generated write-only Go binding around a Solidity contract. +type KVTableTransactor struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// KVTableFilterer is an auto generated log filtering Go binding around a Solidity contract events. +type KVTableFilterer struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// KVTableSession is an auto generated Go binding around a Solidity contract, +// with pre-set call and transact options. +type KVTableSession struct { + Contract *KVTable // Generic contract binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// KVTableCallerSession is an auto generated read-only Go binding around a Solidity contract, +// with pre-set call options. +type KVTableCallerSession struct { + Contract *KVTableCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session +} + +// KVTableTransactorSession is an auto generated write-only Go binding around a Solidity contract, +// with pre-set transact options. +type KVTableTransactorSession struct { + Contract *KVTableTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// KVTableRaw is an auto generated low-level Go binding around a Solidity contract. +type KVTableRaw struct { + Contract *KVTable // Generic contract binding to access the raw methods on +} + +// KVTableCallerRaw is an auto generated low-level read-only Go binding around a Solidity contract. +type KVTableCallerRaw struct { + Contract *KVTableCaller // Generic read-only contract binding to access the raw methods on +} + +// KVTableTransactorRaw is an auto generated low-level write-only Go binding around a Solidity contract. +type KVTableTransactorRaw struct { + Contract *KVTableTransactor // Generic write-only contract binding to access the raw methods on +} + +// NewKVTable creates a new instance of KVTable, bound to a specific deployed contract. +func NewKVTable(address common.Address, backend bind.ContractBackend) (*KVTable, error) { + contract, err := bindKVTable(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &KVTable{KVTableCaller: KVTableCaller{contract: contract}, KVTableTransactor: KVTableTransactor{contract: contract}, KVTableFilterer: KVTableFilterer{contract: contract}}, nil +} + +// NewKVTableCaller creates a new read-only instance of KVTable, bound to a specific deployed contract. +func NewKVTableCaller(address common.Address, caller bind.ContractCaller) (*KVTableCaller, error) { + contract, err := bindKVTable(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &KVTableCaller{contract: contract}, nil +} + +// NewKVTableTransactor creates a new write-only instance of KVTable, bound to a specific deployed contract. +func NewKVTableTransactor(address common.Address, transactor bind.ContractTransactor) (*KVTableTransactor, error) { + contract, err := bindKVTable(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &KVTableTransactor{contract: contract}, nil +} + +// NewKVTableFilterer creates a new log filterer instance of KVTable, bound to a specific deployed contract. +func NewKVTableFilterer(address common.Address, filterer bind.ContractFilterer) (*KVTableFilterer, error) { + contract, err := bindKVTable(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &KVTableFilterer{contract: contract}, nil +} + +// bindKVTable binds a generic wrapper to an already deployed contract. +func bindKVTable(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := abi.JSON(strings.NewReader(KVTableABI)) + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, parsed, caller, transactor, filterer), nil +} + +// 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 (_KVTable *KVTableRaw) Call(opts *bind.CallOpts, result interface{}, method string, params ...interface{}) error { + return _KVTable.Contract.KVTableCaller.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_KVTable *KVTableRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, *types.Receipt, error) { + return _KVTable.Contract.KVTableTransactor.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_KVTable *KVTableRaw) TransactWithResult(opts *bind.TransactOpts, result interface{}, method string, params ...interface{}) (*types.Transaction, *types.Receipt, error) { + return _KVTable.Contract.KVTableTransactor.contract.TransactWithResult(opts, result, method, params...) +} + +// 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 (_KVTable *KVTableCallerRaw) Call(opts *bind.CallOpts, result interface{}, method string, params ...interface{}) error { + return _KVTable.Contract.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_KVTable *KVTableTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, *types.Receipt, error) { + return _KVTable.Contract.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_KVTable *KVTableTransactorRaw) TransactWithResult(opts *bind.TransactOpts, result interface{}, method string, params ...interface{}) (*types.Transaction, *types.Receipt, error) { + return _KVTable.Contract.contract.TransactWithResult(opts, result, method, params...) +} + +// Get is a free data retrieval call binding the contract method 0x693ec85e. +// +// Solidity: function get(string key) constant returns(bool, string) +func (_KVTable *KVTableCaller) Get(opts *bind.CallOpts, key string) (bool, string, error) { + var ( + ret0 = new(bool) + ret1 = new(string) + ) + out := &[]interface{}{ + ret0, + ret1, + } + err := _KVTable.contract.Call(opts, out, "get", key) + return *ret0, *ret1, err +} + +// Get is a free data retrieval call binding the contract method 0x693ec85e. +// +// Solidity: function get(string key) constant returns(bool, string) +func (_KVTable *KVTableSession) Get(key string) (bool, string, error) { + return _KVTable.Contract.Get(&_KVTable.CallOpts, key) +} + +// Get is a free data retrieval call binding the contract method 0x693ec85e. +// +// Solidity: function get(string key) constant returns(bool, string) +func (_KVTable *KVTableCallerSession) Get(key string) (bool, string, error) { + return _KVTable.Contract.Get(&_KVTable.CallOpts, key) +} + +// Set is a paid mutator transaction binding the contract method 0xe942b516. +// +// Solidity: function set(string key, string value) returns(int32) +func (_KVTable *KVTableTransactor) Set(opts *bind.TransactOpts, key string, value string) (int32, *types.Transaction, *types.Receipt, error) { + var ( + ret0 = new(int32) + ) + out := ret0 + transaction, receipt, err := _KVTable.contract.TransactWithResult(opts, out, "set", key, value) + return *ret0, transaction, receipt, err +} + +func (_KVTable *KVTableTransactor) AsyncSet(handler func(*types.Receipt, error), opts *bind.TransactOpts, key string, value string) (*types.Transaction, error) { + return _KVTable.contract.AsyncTransact(opts, handler, "set", key, value) +} + +// Set is a paid mutator transaction binding the contract method 0xe942b516. +// +// Solidity: function set(string key, string value) returns(int32) +func (_KVTable *KVTableSession) Set(key string, value string) (int32, *types.Transaction, *types.Receipt, error) { + return _KVTable.Contract.Set(&_KVTable.TransactOpts, key, value) +} + +func (_KVTable *KVTableSession) AsyncSet(handler func(*types.Receipt, error), key string, value string) (*types.Transaction, error) { + return _KVTable.Contract.AsyncSet(handler, &_KVTable.TransactOpts, key, value) +} + +// Set is a paid mutator transaction binding the contract method 0xe942b516. +// +// Solidity: function set(string key, string value) returns(int32) +func (_KVTable *KVTableTransactorSession) Set(key string, value string) (int32, *types.Transaction, *types.Receipt, error) { + return _KVTable.Contract.Set(&_KVTable.TransactOpts, key, value) +} + +func (_KVTable *KVTableTransactorSession) AsyncSet(handler func(*types.Receipt, error), key string, value string) (*types.Transaction, error) { + return _KVTable.Contract.AsyncSet(handler, &_KVTable.TransactOpts, key, value) +} diff --git a/precompiled/crud/crud_service.go b/precompiled/crud/crud_service.go deleted file mode 100644 index 3a33002d..00000000 --- a/precompiled/crud/crud_service.go +++ /dev/null @@ -1,277 +0,0 @@ -package crud - -import ( - //"encoding/json" - "fmt" - "math/big" - - "github.com/FISCO-BCOS/go-sdk/abi/bind" - "github.com/FISCO-BCOS/go-sdk/client" - "github.com/FISCO-BCOS/go-sdk/core/types" - "github.com/FISCO-BCOS/go-sdk/precompiled" - "github.com/ethereum/go-ethereum/common" -) - -const ( - TableKeyMaxLength int = 255 - - //crud precompiled contract error code - conditionOperationUndefined int64 = -51502 - parseConditionError int64 = -51501 - parseEntryError int64 = -51500 -) - -// getErrorMessage returns the message of error code -func getErrorMessage(errorCode int64) string { - var message string - switch errorCode { - case conditionOperationUndefined: - message = "condition operation undefined" - case parseConditionError: - message = "parse condition error" - case parseEntryError: - message = "parse entry error" - default: - message = "" - } - return message -} - -// errorCodeToError judges whether the error code represents an error -func errorCodeToError(errorCode int64) error { - var errorCodeMessage string - errorCodeMessage = precompiled.GetCommonErrorCodeMessage(errorCode) - if errorCodeMessage != "" { - return fmt.Errorf("error code: %v, error code message: %v", errorCode, errorCodeMessage) - } - errorCodeMessage = getErrorMessage(errorCode) - if errorCodeMessage != "" { - return fmt.Errorf("error code: %v, error code message: %v", errorCode, errorCodeMessage) - } - return nil -} - -// CRUDService is a precompile contract service. -type Service struct { - crud *Table - tableFactory *TableManager - crudAuth *bind.TransactOpts - CallOpts *bind.CallOpts - client *client.Client -} - -// TableFactoryPrecompileAddress is the contract address of TableFactory -var TableFactoryPrecompileAddress = common.HexToAddress("0x1002") - -// CRUDPrecompileAddress is the contract address of CRUD -var CRUDPrecompileAddress = common.HexToAddress("0x1002") - -// NewCRUDService returns ptr of CRUDService -func NewCRUDService(client *client.Client) (*Service, error) { - crudInstance, err := NewTable(CRUDPrecompileAddress, client) - if err != nil { - return nil, fmt.Errorf("construct CRUD failed: %+v", err) - } - tableInstance, err := NewTableManager(TableFactoryPrecompileAddress, client) - if err != nil { - return nil, fmt.Errorf("construct TableFactor failed: %+v", err) - } - auth := client.GetTransactOpts() - callOpts := client.GetCallOpts() - return &Service{crud: crudInstance, tableFactory: tableInstance, crudAuth: auth, CallOpts: callOpts, client: client}, nil -} - -func (service *Service) CreateTable(tableName string, key string, valueFields []string) (int64, error) { - tableInfo := TableInfo{ - KeyColumn: key, - ValueColumns: valueFields, - } - _, receipt, err := service.tableFactory.CreateTable(service.crudAuth, tableName, tableInfo) - if err != nil { - return precompiled.DefaultErrorCode, fmt.Errorf("CRUDService CreateTable failed: %v", err) - } - - address, err := service.tableFactory.OpenTable(service.CallOpts, tableName) - if err != nil { - return precompiled.DefaultErrorCode, fmt.Errorf("CRUDService OpenTable failed: %v", err) - } - fmt.Println("CreateTable address:", address) - crudInstance, err := NewTable(address, service.client) - if err != nil { - return precompiled.DefaultErrorCode, fmt.Errorf("construct TableFactor failed: %+v", err) - } - service.crud = crudInstance - return parseReturnValue(receipt, "createTable") -} - -func (service *Service) AsyncCreateTable(handler func(*types.Receipt, error), tableName string, key string, valueFields []string) (*types.Transaction, error) { - tableInfo := TableInfo{ - KeyColumn: key, - ValueColumns: valueFields, - } - return service.tableFactory.AsyncCreateTable(handler, service.crudAuth, tableName, tableInfo) -} - -func (service *Service) OpenTable(tableName string) (int64, error) { - address, err := service.tableFactory.OpenTable(service.CallOpts, tableName) - if err != nil { - return precompiled.DefaultErrorCode, fmt.Errorf("CRUDService OpenTable failed: %v", err) - } - fmt.Println("OpenTable address:", address) - crudInstance, err := NewTable(address, service.client) - if err != nil { - return precompiled.DefaultErrorCode, fmt.Errorf("construct TableFactor failed: %+v", err) - } - service.crud = crudInstance - return 0, nil -} - -// Insert entry -func (service *Service) Insert(entry *Entry) (int64, error) { - if len(entry.Key) > TableKeyMaxLength { - return -1, fmt.Errorf("the value of the table key exceeds the maximum limit( %d )", TableKeyMaxLength) - } - - _, receipt, err := service.crud.Insert(service.crudAuth, *entry) - if err != nil { - return -1, fmt.Errorf("CRUDService Insert failed: %v", err) - } - return parseReturnValue(receipt, "insert") -} - -// -//func (service *Service) AsyncInsert(handler func(*types.Receipt, error), tableName string, key string, entry *Entry) (*types.Transaction, error) { -// if len(key) > TableKeyMaxLength { -// return nil, fmt.Errorf("the value of the table key exceeds the maximum limit( %d )", TableKeyMaxLength) -// } -// // change to string -// entryJSON, err := json.MarshalIndent(entry.GetFields(), "", "\t") -// if err != nil { -// return nil, fmt.Errorf("change entry to json struct failed: %v", err) -// } -// return service.crud.AsyncInsert(handler, service.crudAuth, tableName, key, string(entryJSON[:]), "") -//} -// -//// Update entry -//func (service *Service) Update(tableName string, key string, entry *Entry, condition *Condition) (int64, error) { -// if len(key) > TableKeyMaxLength { -// return -1, fmt.Errorf("the value of the table key exceeds the maximum limit( %d )", TableKeyMaxLength) -// } -// // change to string -// entryJSON, err := json.MarshalIndent(entry.GetFields(), "", "\t") -// if err != nil { -// return -1, fmt.Errorf("change entry to json struct failed: %v", err) -// } -// conditionJSON, err := json.MarshalIndent(condition.GetConditions(), "", "\t") -// if err != nil { -// return -1, fmt.Errorf("change condition to json struct failed: %v", err) -// } -// -// _, receipt, err := service.crud.Update(service.crudAuth, tableName, key, string(entryJSON[:]), string(conditionJSON[:]), "") -// if err != nil { -// return -1, fmt.Errorf("CRUDService Update failed: %v", err) -// } -// return parseReturnValue(receipt, "update") -//} -// -//func (service *Service) AsyncUpdate(handler func(*types.Receipt, error), tableName string, key string, entry *Entry, condition *Condition) (*types.Transaction, error) { -// if len(key) > TableKeyMaxLength { -// return nil, fmt.Errorf("the value of the table key exceeds the maximum limit( %d )", TableKeyMaxLength) -// } -// // change to string -// entryJSON, err := json.MarshalIndent(entry.GetFields(), "", "\t") -// if err != nil { -// return nil, fmt.Errorf("change entry to json struct failed: %v", err) -// } -// conditionJSON, err := json.MarshalIndent(condition.GetConditions(), "", "\t") -// if err != nil { -// return nil, fmt.Errorf("change condition to json struct failed: %v", err) -// } -// -// return service.crud.AsyncUpdate(handler, service.crudAuth, tableName, key, string(entryJSON[:]), string(conditionJSON[:]), "") -// -//} -// -//func (service *Service) Remove(tableName string, key string, condition *Condition) (int64, error) { -// if len(key) > TableKeyMaxLength { -// return -1, fmt.Errorf("the value of the table key exceeds the maximum limit( %d )", TableKeyMaxLength) -// } -// conditionJSON, err := json.MarshalIndent(condition.GetConditions(), "", "\t") -// if err != nil { -// return -1, fmt.Errorf("change condition to json struct failed: %v", err) -// } -// -// _, receipt, err := service.crud.Remove(service.crudAuth, tableName, key, string(conditionJSON[:]), "") -// if err != nil { -// return -1, fmt.Errorf("CRUDService Remove failed: %v", err) -// } -// return parseReturnValue(receipt, "remove") -//} -// -//func (service *Service) AsyncRemove(handler func(*types.Receipt, error), tableName string, key string, condition *Condition) (*types.Transaction, error) { -// if len(key) > TableKeyMaxLength { -// return nil, fmt.Errorf("the value of the table key exceeds the maximum limit( %d )", TableKeyMaxLength) -// } -// conditionJSON, err := json.MarshalIndent(condition.GetConditions(), "", "\t") -// if err != nil { -// return nil, fmt.Errorf("change condition to json struct failed: %v", err) -// } -// -// return service.crud.AsyncRemove(handler, service.crudAuth, tableName, key, string(conditionJSON[:]), "") -//} - -// Select entry -func (service *Service) Select(key string) (*Entry, error) { - if len(key) > TableKeyMaxLength { - return nil, fmt.Errorf("the value of the table key exceeds the maximum limit( %d )", TableKeyMaxLength) - } - entry, err := service.crud.Select0(service.CallOpts, key) - if err != nil { - return nil, fmt.Errorf("CRUDService Select failed: %v", err) - } - return &entry, nil -} - -//// Desc is used for Table -//func (service *Service) Desc(userTableName string) (string, string, error) { -// opts := &bind.CallOpts{From: service.crudAuth.From} -// keyField, valueField, err := service.crud.desc(opts, userTableName) -// if err != nil { -// return "", "", fmt.Errorf("desc failed, select table error: %v", err) -// } -// return keyField, valueField, nil -//} - -func parseReturnValue(receipt *types.Receipt, name string) (int64, error) { - errorMessage := receipt.GetErrorMessage() - if errorMessage != "" { - return int64(receipt.GetStatus()), fmt.Errorf("receipt.Status err: %v", errorMessage) - } - var bigNum *big.Int - var err error - if name == "createTable" { - bigNum, err = precompiled.ParseBigIntFromOutput(receipt) - } else { - bigNum, err = precompiled.ParseBigIntFromOutput(receipt) - } - if err != nil { - return precompiled.DefaultErrorCode, fmt.Errorf("parseReturnValue failed, err: %v", err) - } - errorCode, err := precompiled.BigIntToInt64(bigNum) - if err != nil { - return precompiled.DefaultErrorCode, fmt.Errorf("parseReturnValue failed, err: %v", err) - } - return errorCode, errorCodeToError(errorCode) -} - -func (service *Service) AppendColumns(path string, newColumns []string) (int64, error) { - _, receipt, err := service.tableFactory.AppendColumns(service.crudAuth, path, newColumns) - if err != nil { - return precompiled.DefaultErrorCode, fmt.Errorf("CRUDService AppendColumns failed: %v", err) - } - return parseReturnValue(receipt, "createTable") -} - -func (service *Service) AsyncAppendColumns(handler func(*types.Receipt, error), path string, newColumns []string) (*types.Transaction, error) { - return service.tableFactory.AsyncAppendColumns(handler, service.crudAuth, path, newColumns) -} diff --git a/precompiled/crud/crud_service_test.go b/precompiled/crud/crud_service_test.go deleted file mode 100644 index 287e89d7..00000000 --- a/precompiled/crud/crud_service_test.go +++ /dev/null @@ -1,343 +0,0 @@ -package crud - -import ( - "context" - "encoding/hex" - "math/big" - "os" - "testing" - "time" - - "github.com/FISCO-BCOS/go-sdk/client" - "github.com/FISCO-BCOS/go-sdk/core/types" - "github.com/FISCO-BCOS/go-sdk/precompiled" -) - -const ( - tableName = "t_test9" - tableNameForAsync = "t_test_async9" - tablePath = "/tables/t_test9" - key = "name" - keyAsync = "name_async" - timeout = 1 * time.Second -) - -var valueFields = []string{"item_name"} -var valueFields_update = []string{"item_name_update"} - -var ( - service *Service - channel = make(chan int) -) - -func getClient(t *testing.T) *client.Client { - privateKey, _ := hex.DecodeString("145e247e170ba3afd6ae97e88f00dbc976c2345d511b0f6713355d19d8b80b58") - config := &client.Config{IsSMCrypto: false, GroupID: "group0", - PrivateKey: privateKey, Host: "127.0.0.1", Port: 20200, TLSCaFile: "./ca.crt", TLSKeyFile: "./sdk.key", TLSCertFile: "./sdk.crt"} - c, err := client.DialContext(context.Background(), config) - if err != nil { - t.Fatalf("Dial to %s:%d failed of %v", config.Host, config.Port, err) - } - return c -} - -func getService(t *testing.T) { - c := getClient(t) - newService, err := NewCRUDService(c) - if err != nil { - t.Fatalf("init CrudService failed: %+v", err) - } - service = newService -} - -func TestMain(m *testing.M) { - getService(&testing.T{}) - exitCode := m.Run() - os.Exit(exitCode) -} - -func TestCreateTable(t *testing.T) { - result, err := service.CreateTable(tableName, key, valueFields) - if err != nil { - t.Fatalf("create table failed: %v", err) - } - if result != 0 { - t.Fatalf("TestCreateTable failed, the result \"%v\" is inconsistent with \"0\"", result) - } - t.Logf("result: %d\n", result) -} - -func TestAsyncCreateTable(t *testing.T) { - handler := func(receipt *types.Receipt, err error) { - if err != nil { - t.Fatalf("receive receipt failed, %v\n", err) - } - var bigNum *big.Int - bigNum, err = precompiled.ParseBigIntFromOutput(receipt) - if err != nil { - t.Fatalf("parseReturnValue failed, err: %v\n", err) - } - result, err := precompiled.BigIntToInt64(bigNum) - if err != nil { - t.Fatalf("%v\n", err) - } - if result != 0 { - t.Fatalf("TestAsyncCreateTable failed, the result \"%v\" is inconsistent with \"0\"", result) - } - t.Logf("result: %d\n", result) - channel <- 0 - } - - _, err := service.AsyncCreateTable(handler, tableNameForAsync, key, valueFields) - if err != nil { - t.Fatalf("create table failed: %v", err) - } - select { - case <-channel: - return - case <-time.After(timeout): - t.Fatal("timeout") - } -} - -func TestInsert(t *testing.T) { - var insertResults int - entry := Entry{ - Key: key, - Fields: valueFields, - } - for i := 1; i <= 5; i++ { - _, receipt, err := service.crud.Insert(service.crudAuth, entry) - if err != nil { - t.Fatalf("insert table failed: %v", err) - } - insertResults += receipt.Status - } - if insertResults != 0 { - t.Fatalf("TestInsert failed, the insertResults \"%v\" is inconsistent with \"5\"", insertResults) - } - t.Logf("insertResults: %d\n", insertResults) -} - -func TestAsyncInsert(t *testing.T) { - handler := func(receipt *types.Receipt, err error) { - if err != nil { - t.Fatalf("receive receipt failed, %v\n", err) - } - var bigNum *big.Int - bigNum, err = precompiled.ParseBigIntFromOutput(receipt) - if err != nil { - t.Fatalf("parseReturnValue failed, err: %v\n", err) - } - result, err := precompiled.BigIntToInt64(bigNum) - if err != nil { - t.Fatalf("%v\n", err) - } - if result != 1 { - t.Fatalf("TestAsyncInsert failed, the result \"%v\" is inconsistent with \"1\"", result) - } - t.Logf("result: %d\n", result) - channel <- 0 - } - - entry := Entry{ - Key: keyAsync, - Fields: valueFields, - } - _, err := service.crud.AsyncInsert(handler, service.crudAuth, entry) - if err != nil { - t.Fatalf("insert table failed: %v", err) - } - select { - case <-channel: - return - case <-time.After(timeout): - t.Fatal("timeout") - } -} - -func TestSelect(t *testing.T) { - - resultSelect, err := service.crud.Select0(service.CallOpts, key) - if err != nil { - t.Fatalf("select table failed: %v", err) - } - if resultSelect.Fields[0] != valueFields[0] { - t.Fatalf("TestSelect failed, the result of resultSelect \"%v\" is not inconsistent", resultSelect.Fields[0]) - } - t.Logf("resultSelect :\n") - - for i := 0; i < len(resultSelect.Fields); i++ { - t.Logf("resultSelect[%d]'s item_name is:%s\n", i, resultSelect.Fields[i]) - } -} - -func TestUpdate(t *testing.T) { - updateField := UpdateField{ - ColumnName: valueFields[0], - Value: valueFields_update[0], - } - var updateFieldList []UpdateField - updateFieldList = append(updateFieldList, updateField) - _, receipt, err := service.crud.Update(service.crudAuth, key, updateFieldList) - if err != nil { - t.Fatalf("update table failed: %v", err) - } - if receipt.Status != 0 { - t.Fatalf("TestUpdate failed, the updateResult ") - } - resultSelect, err := service.crud.Select0(service.CallOpts, key) - if err != nil { - t.Fatalf("select table failed: %v", err) - } - if resultSelect.Fields[0] != valueFields_update[0] { - t.Fatalf("TestUpdate failed, the result of resultUpdate \"%v\" is not inconsistent", resultSelect.Fields[0]) - } - t.Logf("updateResult: %s", resultSelect.Fields[0]) -} - -func TestAsyncUpdate(t *testing.T) { - handler := func(receipt *types.Receipt, err error) { - if err != nil { - t.Fatalf("receive receipt failed, %v\n", err) - } - var bigNum *big.Int - bigNum, err = precompiled.ParseBigIntFromOutput(receipt) - if err != nil { - t.Fatalf("parseReturnValue failed, err: %v\n", err) - } - result, err := precompiled.BigIntToInt64(bigNum) - if err != nil { - t.Fatalf("%v\n", err) - } - if result != 1 { - t.Fatalf("TestAsyncUpdate failed, the result \"%v\" is inconsistent with \"1\"", result) - } - t.Logf("result: %d\n", result) - channel <- 0 - } - - updateField := UpdateField{ - ColumnName: valueFields[0], - Value: valueFields_update[0], - } - var updateFieldList []UpdateField - updateFieldList = append(updateFieldList, updateField) - _, err := service.crud.AsyncUpdate(handler, service.crudAuth, keyAsync, updateFieldList) - if err != nil { - t.Fatalf("update table failed: %v", err) - } - select { - case <-channel: - return - case <-time.After(timeout): - t.Fatal("timeout") - } -} - -func TestRemove(t *testing.T) { - _, receipt, err := service.crud.Remove0(service.crudAuth, key) - if err != nil { - t.Fatalf("remove table failed: %v", err) - } - if receipt.Status != 0 { - t.Fatalf("TestRemove failed, the removeResult \"%v\" is not inconsistent with \"0\"", receipt.Status) - } - t.Logf("removeResult: %d\n", receipt.Status) -} - -func TestAsyncRemove(t *testing.T) { - handler := func(receipt *types.Receipt, err error) { - if err != nil { - t.Fatalf("receive receipt failed, %v\n", err) - } - var bigNum *big.Int - bigNum, err = precompiled.ParseBigIntFromOutput(receipt) - if err != nil { - t.Fatalf("parseReturnValue failed, err: %v\n", err) - } - result, err := precompiled.BigIntToInt64(bigNum) - if err != nil { - t.Fatalf("%v\n", err) - } - if result != 1 { - t.Fatalf("TestAsyncRemove failed, the result \"%v\" is inconsistent with \"1\"", result) - } - t.Logf("result: %d\n", result) - channel <- 0 - } - - _, err := service.crud.AsyncRemove0(handler, service.crudAuth, keyAsync) - if err != nil { - t.Fatalf("remove data failed: %v", err) - } - select { - case <-channel: - return - case <-time.After(timeout): - t.Fatal("timeout") - } -} - -func TestDesc(t *testing.T) { - tableInfo, err := service.tableFactory.Desc(service.CallOpts, tableName) - if err != nil { - t.Fatalf("query table info by tableName failed: %v", err) - } - if tableInfo.KeyColumn != key { - t.Fatalf("TestDesc failed, the keyField \"%v\" is not inconsistent with \"name\"", tableInfo.KeyColumn) - } - if tableInfo.ValueColumns[0] != valueFields[0] { - t.Fatalf("TestDesc failed, the valueField \"%v\" is not inconsistent with \"item_id,item_name\"", tableInfo.ValueColumns[0]) - } - t.Logf("keyFiled is:%s\n", tableInfo.KeyColumn) - t.Logf("valueField is:%s\n", tableInfo.ValueColumns[0]) -} - -func TestAppendColumns(t *testing.T) { - newColumns := []string{"test0", "test1"} - - result, err := service.AppendColumns(tablePath, newColumns) - if err != nil { - t.Fatalf("create AppendColumns failed: %v", err) - } - if result != 0 { - t.Fatalf("TestAppendColumns failed, the result \"%v\" is inconsistent with \"0\"", result) - } - t.Logf("result: %d\n", result) -} - -func TestAsyncAppendColumns(t *testing.T) { - newColumns := []string{"test2", "test3"} - - handler := func(receipt *types.Receipt, err error) { - if err != nil { - t.Fatalf("receive receipt failed, %v\n", err) - } - var bigNum *big.Int - bigNum, err = precompiled.ParseBigIntFromOutput(receipt) - if err != nil { - t.Fatalf("parseReturnValue failed, err: %v\n", err) - } - result, err := precompiled.BigIntToInt64(bigNum) - if err != nil { - t.Fatalf("%v\n", err) - } - if result != 0 { - t.Fatalf("TestAsyncAppendColumns failed, the result \"%v\" is inconsistent with \"0\"", result) - } - t.Logf("result: %d\n", result) - channel <- 0 - } - - _, err := service.AsyncAppendColumns(handler, tablePath, newColumns) - if err != nil { - t.Fatalf("AsyncAppendColumns failed: %v", err) - } - select { - case <-channel: - return - case <-time.After(timeout): - t.Fatal("timeout") - } -} diff --git a/precompiled/crud/table.go b/precompiled/crud/table.go index 4e6c56b5..d323d70b 100644 --- a/precompiled/crud/table.go +++ b/precompiled/crud/table.go @@ -27,6 +27,7 @@ var ( // Condition is an auto generated low-level Go binding around an user-defined struct. type Condition struct { Op uint8 + Field string Value string } @@ -49,7 +50,7 @@ type UpdateField struct { } // TableABI is the input ABI used to generate the binding from. -const TableABI = "[{\"inputs\":[{\"components\":[{\"internalType\":\"enumConditionOP\",\"name\":\"op\",\"type\":\"uint8\"},{\"internalType\":\"string\",\"name\":\"value\",\"type\":\"string\"}],\"internalType\":\"structCondition[]\",\"name\":\"conditions\",\"type\":\"tuple[]\"}],\"name\":\"count\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"string\",\"name\":\"key\",\"type\":\"string\"},{\"internalType\":\"string[]\",\"name\":\"fields\",\"type\":\"string[]\"}],\"internalType\":\"structEntry\",\"name\":\"entry\",\"type\":\"tuple\"}],\"name\":\"insert\",\"outputs\":[{\"internalType\":\"int32\",\"name\":\"\",\"type\":\"int32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"enumConditionOP\",\"name\":\"op\",\"type\":\"uint8\"},{\"internalType\":\"string\",\"name\":\"value\",\"type\":\"string\"}],\"internalType\":\"structCondition[]\",\"name\":\"conditions\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"offset\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"count\",\"type\":\"uint32\"}],\"internalType\":\"structLimit\",\"name\":\"limit\",\"type\":\"tuple\"}],\"name\":\"remove\",\"outputs\":[{\"internalType\":\"int32\",\"name\":\"\",\"type\":\"int32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"key\",\"type\":\"string\"}],\"name\":\"remove\",\"outputs\":[{\"internalType\":\"int32\",\"name\":\"\",\"type\":\"int32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"enumConditionOP\",\"name\":\"op\",\"type\":\"uint8\"},{\"internalType\":\"string\",\"name\":\"value\",\"type\":\"string\"}],\"internalType\":\"structCondition[]\",\"name\":\"conditions\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"offset\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"count\",\"type\":\"uint32\"}],\"internalType\":\"structLimit\",\"name\":\"limit\",\"type\":\"tuple\"}],\"name\":\"select\",\"outputs\":[{\"components\":[{\"internalType\":\"string\",\"name\":\"key\",\"type\":\"string\"},{\"internalType\":\"string[]\",\"name\":\"fields\",\"type\":\"string[]\"}],\"internalType\":\"structEntry[]\",\"name\":\"\",\"type\":\"tuple[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"key\",\"type\":\"string\"}],\"name\":\"select\",\"outputs\":[{\"components\":[{\"internalType\":\"string\",\"name\":\"key\",\"type\":\"string\"},{\"internalType\":\"string[]\",\"name\":\"fields\",\"type\":\"string[]\"}],\"internalType\":\"structEntry\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"key\",\"type\":\"string\"},{\"components\":[{\"internalType\":\"string\",\"name\":\"columnName\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"value\",\"type\":\"string\"}],\"internalType\":\"structUpdateField[]\",\"name\":\"updateFields\",\"type\":\"tuple[]\"}],\"name\":\"update\",\"outputs\":[{\"internalType\":\"int32\",\"name\":\"\",\"type\":\"int32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"enumConditionOP\",\"name\":\"op\",\"type\":\"uint8\"},{\"internalType\":\"string\",\"name\":\"value\",\"type\":\"string\"}],\"internalType\":\"structCondition[]\",\"name\":\"conditions\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"offset\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"count\",\"type\":\"uint32\"}],\"internalType\":\"structLimit\",\"name\":\"limit\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"string\",\"name\":\"columnName\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"value\",\"type\":\"string\"}],\"internalType\":\"structUpdateField[]\",\"name\":\"updateFields\",\"type\":\"tuple[]\"}],\"name\":\"update\",\"outputs\":[{\"internalType\":\"int32\",\"name\":\"\",\"type\":\"int32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]" +const TableABI = "[{\"inputs\":[{\"components\":[{\"internalType\":\"enumConditionOP\",\"name\":\"op\",\"type\":\"uint8\"},{\"internalType\":\"string\",\"name\":\"field\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"value\",\"type\":\"string\"}],\"internalType\":\"structCondition[]\",\"name\":\"conditions\",\"type\":\"tuple[]\"}],\"name\":\"count\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"string\",\"name\":\"key\",\"type\":\"string\"},{\"internalType\":\"string[]\",\"name\":\"fields\",\"type\":\"string[]\"}],\"internalType\":\"structEntry\",\"name\":\"entry\",\"type\":\"tuple\"}],\"name\":\"insert\",\"outputs\":[{\"internalType\":\"int32\",\"name\":\"\",\"type\":\"int32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"key\",\"type\":\"string\"}],\"name\":\"remove\",\"outputs\":[{\"internalType\":\"int32\",\"name\":\"\",\"type\":\"int32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"enumConditionOP\",\"name\":\"op\",\"type\":\"uint8\"},{\"internalType\":\"string\",\"name\":\"field\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"value\",\"type\":\"string\"}],\"internalType\":\"structCondition[]\",\"name\":\"conditions\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"offset\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"count\",\"type\":\"uint32\"}],\"internalType\":\"structLimit\",\"name\":\"limit\",\"type\":\"tuple\"}],\"name\":\"remove\",\"outputs\":[{\"internalType\":\"int32\",\"name\":\"\",\"type\":\"int32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"enumConditionOP\",\"name\":\"op\",\"type\":\"uint8\"},{\"internalType\":\"string\",\"name\":\"field\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"value\",\"type\":\"string\"}],\"internalType\":\"structCondition[]\",\"name\":\"conditions\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"offset\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"count\",\"type\":\"uint32\"}],\"internalType\":\"structLimit\",\"name\":\"limit\",\"type\":\"tuple\"}],\"name\":\"select\",\"outputs\":[{\"components\":[{\"internalType\":\"string\",\"name\":\"key\",\"type\":\"string\"},{\"internalType\":\"string[]\",\"name\":\"fields\",\"type\":\"string[]\"}],\"internalType\":\"structEntry[]\",\"name\":\"\",\"type\":\"tuple[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"key\",\"type\":\"string\"}],\"name\":\"select\",\"outputs\":[{\"components\":[{\"internalType\":\"string\",\"name\":\"key\",\"type\":\"string\"},{\"internalType\":\"string[]\",\"name\":\"fields\",\"type\":\"string[]\"}],\"internalType\":\"structEntry\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"key\",\"type\":\"string\"},{\"components\":[{\"internalType\":\"string\",\"name\":\"columnName\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"value\",\"type\":\"string\"}],\"internalType\":\"structUpdateField[]\",\"name\":\"updateFields\",\"type\":\"tuple[]\"}],\"name\":\"update\",\"outputs\":[{\"internalType\":\"int32\",\"name\":\"\",\"type\":\"int32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"enumConditionOP\",\"name\":\"op\",\"type\":\"uint8\"},{\"internalType\":\"string\",\"name\":\"field\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"value\",\"type\":\"string\"}],\"internalType\":\"structCondition[]\",\"name\":\"conditions\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"offset\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"count\",\"type\":\"uint32\"}],\"internalType\":\"structLimit\",\"name\":\"limit\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"string\",\"name\":\"columnName\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"value\",\"type\":\"string\"}],\"internalType\":\"structUpdateField[]\",\"name\":\"updateFields\",\"type\":\"tuple[]\"}],\"name\":\"update\",\"outputs\":[{\"internalType\":\"int32\",\"name\":\"\",\"type\":\"int32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]" // Table is an auto generated Go binding around a Solidity contract. type Table struct { @@ -170,8 +171,8 @@ func (_Table *TableRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, * } // Transact invokes the (paid) contract method with params as input values. -func (_Table *TableRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, *types.Receipt, error) { - return _Table.Contract.TableTransactor.contract.Transact(opts, method, params...) +func (_Table *TableRaw) TransactWithResult(opts *bind.TransactOpts, result interface{}, method string, params ...interface{}) (*types.Transaction, *types.Receipt, error) { + return _Table.Contract.TableTransactor.contract.TransactWithResult(opts, result, method, params...) } // Call invokes the (constant) contract method with params as input values and @@ -189,11 +190,11 @@ func (_Table *TableTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Tran } // Transact invokes the (paid) contract method with params as input values. -func (_Table *TableTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, *types.Receipt, error) { - return _Table.Contract.contract.Transact(opts, method, params...) +func (_Table *TableTransactorRaw) TransactWithResult(opts *bind.TransactOpts, result interface{}, method string, params ...interface{}) (*types.Transaction, *types.Receipt, error) { + return _Table.Contract.contract.TransactWithResult(opts, result, method, params...) } -// Count is a free data retrieval call binding the contract method 0xd8169b27. +// Count is a free data retrieval call binding the contract method 0xda46335f. // // Solidity: function count([]Condition conditions) constant returns(uint32) func (_Table *TableCaller) Count(opts *bind.CallOpts, conditions []Condition) (uint32, error) { @@ -205,21 +206,21 @@ func (_Table *TableCaller) Count(opts *bind.CallOpts, conditions []Condition) (u return *ret0, err } -// Count is a free data retrieval call binding the contract method 0xd8169b27. +// Count is a free data retrieval call binding the contract method 0xda46335f. // // Solidity: function count([]Condition conditions) constant returns(uint32) func (_Table *TableSession) Count(conditions []Condition) (uint32, error) { return _Table.Contract.Count(&_Table.CallOpts, conditions) } -// Count is a free data retrieval call binding the contract method 0xd8169b27. +// Count is a free data retrieval call binding the contract method 0xda46335f. // // Solidity: function count([]Condition conditions) constant returns(uint32) func (_Table *TableCallerSession) Count(conditions []Condition) (uint32, error) { return _Table.Contract.Count(&_Table.CallOpts, conditions) } -// Select is a free data retrieval call binding the contract method 0x3cd5452e. +// Select is a free data retrieval call binding the contract method 0x2a922441. // // Solidity: function select([]Condition conditions, Limit limit) constant returns([]Entry) func (_Table *TableCaller) Select(opts *bind.CallOpts, conditions []Condition, limit Limit) ([]Entry, error) { @@ -231,14 +232,14 @@ func (_Table *TableCaller) Select(opts *bind.CallOpts, conditions []Condition, l return *ret0, err } -// Select is a free data retrieval call binding the contract method 0x3cd5452e. +// Select is a free data retrieval call binding the contract method 0x2a922441. // // Solidity: function select([]Condition conditions, Limit limit) constant returns([]Entry) func (_Table *TableSession) Select(conditions []Condition, limit Limit) ([]Entry, error) { return _Table.Contract.Select(&_Table.CallOpts, conditions, limit) } -// Select is a free data retrieval call binding the contract method 0x3cd5452e. +// Select is a free data retrieval call binding the contract method 0x2a922441. // // Solidity: function select([]Condition conditions, Limit limit) constant returns([]Entry) func (_Table *TableCallerSession) Select(conditions []Condition, limit Limit) ([]Entry, error) { @@ -274,8 +275,13 @@ func (_Table *TableCallerSession) Select0(key string) (Entry, error) { // Insert is a paid mutator transaction binding the contract method 0x5c6e105f. // // Solidity: function insert(Entry entry) returns(int32) -func (_Table *TableTransactor) Insert(opts *bind.TransactOpts, entry Entry) (*types.Transaction, *types.Receipt, error) { - return _Table.contract.Transact(opts, "insert", entry) +func (_Table *TableTransactor) Insert(opts *bind.TransactOpts, entry Entry) (int32, *types.Transaction, *types.Receipt, error) { + var ( + ret0 = new(int32) + ) + out := ret0 + transaction, receipt, err := _Table.contract.TransactWithResult(opts, out, "insert", entry) + return *ret0, transaction, receipt, err } func (_Table *TableTransactor) AsyncInsert(handler func(*types.Receipt, error), opts *bind.TransactOpts, entry Entry) (*types.Transaction, error) { @@ -285,7 +291,7 @@ func (_Table *TableTransactor) AsyncInsert(handler func(*types.Receipt, error), // Insert is a paid mutator transaction binding the contract method 0x5c6e105f. // // Solidity: function insert(Entry entry) returns(int32) -func (_Table *TableSession) Insert(entry Entry) (*types.Transaction, *types.Receipt, error) { +func (_Table *TableSession) Insert(entry Entry) (int32, *types.Transaction, *types.Receipt, error) { return _Table.Contract.Insert(&_Table.TransactOpts, entry) } @@ -296,7 +302,7 @@ func (_Table *TableSession) AsyncInsert(handler func(*types.Receipt, error), ent // Insert is a paid mutator transaction binding the contract method 0x5c6e105f. // // Solidity: function insert(Entry entry) returns(int32) -func (_Table *TableTransactorSession) Insert(entry Entry) (*types.Transaction, *types.Receipt, error) { +func (_Table *TableTransactorSession) Insert(entry Entry) (int32, *types.Transaction, *types.Receipt, error) { return _Table.Contract.Insert(&_Table.TransactOpts, entry) } @@ -304,77 +310,92 @@ func (_Table *TableTransactorSession) AsyncInsert(handler func(*types.Receipt, e return _Table.Contract.AsyncInsert(handler, &_Table.TransactOpts, entry) } -// Remove is a paid mutator transaction binding the contract method 0x686138ff. +// Remove is a paid mutator transaction binding the contract method 0x80599e4b. // -// Solidity: function remove([]Condition conditions, Limit limit) returns(int32) -func (_Table *TableTransactor) Remove(opts *bind.TransactOpts, conditions []Condition, limit Limit) (*types.Transaction, *types.Receipt, error) { - return _Table.contract.Transact(opts, "remove", conditions, limit) +// Solidity: function remove(string key) returns(int32) +func (_Table *TableTransactor) Remove(opts *bind.TransactOpts, key string) (int32, *types.Transaction, *types.Receipt, error) { + var ( + ret0 = new(int32) + ) + out := ret0 + transaction, receipt, err := _Table.contract.TransactWithResult(opts, out, "remove", key) + return *ret0, transaction, receipt, err } -func (_Table *TableTransactor) AsyncRemove(handler func(*types.Receipt, error), opts *bind.TransactOpts, conditions []Condition, limit Limit) (*types.Transaction, error) { - return _Table.contract.AsyncTransact(opts, handler, "remove", conditions, limit) +func (_Table *TableTransactor) AsyncRemove(handler func(*types.Receipt, error), opts *bind.TransactOpts, key string) (*types.Transaction, error) { + return _Table.contract.AsyncTransact(opts, handler, "remove", key) } -// Remove is a paid mutator transaction binding the contract method 0x686138ff. +// Remove is a paid mutator transaction binding the contract method 0x80599e4b. // -// Solidity: function remove([]Condition conditions, Limit limit) returns(int32) -func (_Table *TableSession) Remove(conditions []Condition, limit Limit) (*types.Transaction, *types.Receipt, error) { - return _Table.Contract.Remove(&_Table.TransactOpts, conditions, limit) +// Solidity: function remove(string key) returns(int32) +func (_Table *TableSession) Remove(key string) (int32, *types.Transaction, *types.Receipt, error) { + return _Table.Contract.Remove(&_Table.TransactOpts, key) } -func (_Table *TableSession) AsyncRemove(handler func(*types.Receipt, error), conditions []Condition, limit Limit) (*types.Transaction, error) { - return _Table.Contract.AsyncRemove(handler, &_Table.TransactOpts, conditions, limit) +func (_Table *TableSession) AsyncRemove(handler func(*types.Receipt, error), key string) (*types.Transaction, error) { + return _Table.Contract.AsyncRemove(handler, &_Table.TransactOpts, key) } -// Remove is a paid mutator transaction binding the contract method 0x686138ff. +// Remove is a paid mutator transaction binding the contract method 0x80599e4b. // -// Solidity: function remove([]Condition conditions, Limit limit) returns(int32) -func (_Table *TableTransactorSession) Remove(conditions []Condition, limit Limit) (*types.Transaction, *types.Receipt, error) { - return _Table.Contract.Remove(&_Table.TransactOpts, conditions, limit) +// Solidity: function remove(string key) returns(int32) +func (_Table *TableTransactorSession) Remove(key string) (int32, *types.Transaction, *types.Receipt, error) { + return _Table.Contract.Remove(&_Table.TransactOpts, key) } -func (_Table *TableTransactorSession) AsyncRemove(handler func(*types.Receipt, error), conditions []Condition, limit Limit) (*types.Transaction, error) { - return _Table.Contract.AsyncRemove(handler, &_Table.TransactOpts, conditions, limit) +func (_Table *TableTransactorSession) AsyncRemove(handler func(*types.Receipt, error), key string) (*types.Transaction, error) { + return _Table.Contract.AsyncRemove(handler, &_Table.TransactOpts, key) } -// Remove0 is a paid mutator transaction binding the contract method 0x80599e4b. +// Remove0 is a paid mutator transaction binding the contract method 0xa7260717. // -// Solidity: function remove(string key) returns(int32) -func (_Table *TableTransactor) Remove0(opts *bind.TransactOpts, key string) (*types.Transaction, *types.Receipt, error) { - return _Table.contract.Transact(opts, "remove0", key) +// Solidity: function remove([]Condition conditions, Limit limit) returns(int32) +func (_Table *TableTransactor) Remove0(opts *bind.TransactOpts, conditions []Condition, limit Limit) (int32, *types.Transaction, *types.Receipt, error) { + var ( + ret0 = new(int32) + ) + out := ret0 + transaction, receipt, err := _Table.contract.TransactWithResult(opts, out, "remove0", conditions, limit) + return *ret0, transaction, receipt, err } -func (_Table *TableTransactor) AsyncRemove0(handler func(*types.Receipt, error), opts *bind.TransactOpts, key string) (*types.Transaction, error) { - return _Table.contract.AsyncTransact(opts, handler, "remove0", key) +func (_Table *TableTransactor) AsyncRemove0(handler func(*types.Receipt, error), opts *bind.TransactOpts, conditions []Condition, limit Limit) (*types.Transaction, error) { + return _Table.contract.AsyncTransact(opts, handler, "remove0", conditions, limit) } -// Remove0 is a paid mutator transaction binding the contract method 0x80599e4b. +// Remove0 is a paid mutator transaction binding the contract method 0xa7260717. // -// Solidity: function remove(string key) returns(int32) -func (_Table *TableSession) Remove0(key string) (*types.Transaction, *types.Receipt, error) { - return _Table.Contract.Remove0(&_Table.TransactOpts, key) +// Solidity: function remove([]Condition conditions, Limit limit) returns(int32) +func (_Table *TableSession) Remove0(conditions []Condition, limit Limit) (int32, *types.Transaction, *types.Receipt, error) { + return _Table.Contract.Remove0(&_Table.TransactOpts, conditions, limit) } -func (_Table *TableSession) AsyncRemove0(handler func(*types.Receipt, error), key string) (*types.Transaction, error) { - return _Table.Contract.AsyncRemove0(handler, &_Table.TransactOpts, key) +func (_Table *TableSession) AsyncRemove0(handler func(*types.Receipt, error), conditions []Condition, limit Limit) (*types.Transaction, error) { + return _Table.Contract.AsyncRemove0(handler, &_Table.TransactOpts, conditions, limit) } -// Remove0 is a paid mutator transaction binding the contract method 0x80599e4b. +// Remove0 is a paid mutator transaction binding the contract method 0xa7260717. // -// Solidity: function remove(string key) returns(int32) -func (_Table *TableTransactorSession) Remove0(key string) (*types.Transaction, *types.Receipt, error) { - return _Table.Contract.Remove0(&_Table.TransactOpts, key) +// Solidity: function remove([]Condition conditions, Limit limit) returns(int32) +func (_Table *TableTransactorSession) Remove0(conditions []Condition, limit Limit) (int32, *types.Transaction, *types.Receipt, error) { + return _Table.Contract.Remove0(&_Table.TransactOpts, conditions, limit) } -func (_Table *TableTransactorSession) AsyncRemove0(handler func(*types.Receipt, error), key string) (*types.Transaction, error) { - return _Table.Contract.AsyncRemove0(handler, &_Table.TransactOpts, key) +func (_Table *TableTransactorSession) AsyncRemove0(handler func(*types.Receipt, error), conditions []Condition, limit Limit) (*types.Transaction, error) { + return _Table.Contract.AsyncRemove0(handler, &_Table.TransactOpts, conditions, limit) } // Update is a paid mutator transaction binding the contract method 0x41ffd75f. // // Solidity: function update(string key, []UpdateField updateFields) returns(int32) -func (_Table *TableTransactor) Update(opts *bind.TransactOpts, key string, updateFields []UpdateField) (*types.Transaction, *types.Receipt, error) { - return _Table.contract.Transact(opts, "update", key, updateFields) +func (_Table *TableTransactor) Update(opts *bind.TransactOpts, key string, updateFields []UpdateField) (int32, *types.Transaction, *types.Receipt, error) { + var ( + ret0 = new(int32) + ) + out := ret0 + transaction, receipt, err := _Table.contract.TransactWithResult(opts, out, "update", key, updateFields) + return *ret0, transaction, receipt, err } func (_Table *TableTransactor) AsyncUpdate(handler func(*types.Receipt, error), opts *bind.TransactOpts, key string, updateFields []UpdateField) (*types.Transaction, error) { @@ -384,7 +405,7 @@ func (_Table *TableTransactor) AsyncUpdate(handler func(*types.Receipt, error), // Update is a paid mutator transaction binding the contract method 0x41ffd75f. // // Solidity: function update(string key, []UpdateField updateFields) returns(int32) -func (_Table *TableSession) Update(key string, updateFields []UpdateField) (*types.Transaction, *types.Receipt, error) { +func (_Table *TableSession) Update(key string, updateFields []UpdateField) (int32, *types.Transaction, *types.Receipt, error) { return _Table.Contract.Update(&_Table.TransactOpts, key, updateFields) } @@ -395,7 +416,7 @@ func (_Table *TableSession) AsyncUpdate(handler func(*types.Receipt, error), key // Update is a paid mutator transaction binding the contract method 0x41ffd75f. // // Solidity: function update(string key, []UpdateField updateFields) returns(int32) -func (_Table *TableTransactorSession) Update(key string, updateFields []UpdateField) (*types.Transaction, *types.Receipt, error) { +func (_Table *TableTransactorSession) Update(key string, updateFields []UpdateField) (int32, *types.Transaction, *types.Receipt, error) { return _Table.Contract.Update(&_Table.TransactOpts, key, updateFields) } @@ -403,21 +424,26 @@ func (_Table *TableTransactorSession) AsyncUpdate(handler func(*types.Receipt, e return _Table.Contract.AsyncUpdate(handler, &_Table.TransactOpts, key, updateFields) } -// Update0 is a paid mutator transaction binding the contract method 0x9953df92. +// Update0 is a paid mutator transaction binding the contract method 0x9924c17e. // // Solidity: function update([]Condition conditions, Limit limit, []UpdateField updateFields) returns(int32) -func (_Table *TableTransactor) Update0(opts *bind.TransactOpts, conditions []Condition, limit Limit, updateFields []UpdateField) (*types.Transaction, *types.Receipt, error) { - return _Table.contract.Transact(opts, "update0", conditions, limit, updateFields) +func (_Table *TableTransactor) Update0(opts *bind.TransactOpts, conditions []Condition, limit Limit, updateFields []UpdateField) (int32, *types.Transaction, *types.Receipt, error) { + var ( + ret0 = new(int32) + ) + out := ret0 + transaction, receipt, err := _Table.contract.TransactWithResult(opts, out, "update0", conditions, limit, updateFields) + return *ret0, transaction, receipt, err } func (_Table *TableTransactor) AsyncUpdate0(handler func(*types.Receipt, error), opts *bind.TransactOpts, conditions []Condition, limit Limit, updateFields []UpdateField) (*types.Transaction, error) { return _Table.contract.AsyncTransact(opts, handler, "update0", conditions, limit, updateFields) } -// Update0 is a paid mutator transaction binding the contract method 0x9953df92. +// Update0 is a paid mutator transaction binding the contract method 0x9924c17e. // // Solidity: function update([]Condition conditions, Limit limit, []UpdateField updateFields) returns(int32) -func (_Table *TableSession) Update0(conditions []Condition, limit Limit, updateFields []UpdateField) (*types.Transaction, *types.Receipt, error) { +func (_Table *TableSession) Update0(conditions []Condition, limit Limit, updateFields []UpdateField) (int32, *types.Transaction, *types.Receipt, error) { return _Table.Contract.Update0(&_Table.TransactOpts, conditions, limit, updateFields) } @@ -425,10 +451,10 @@ func (_Table *TableSession) AsyncUpdate0(handler func(*types.Receipt, error), co return _Table.Contract.AsyncUpdate0(handler, &_Table.TransactOpts, conditions, limit, updateFields) } -// Update0 is a paid mutator transaction binding the contract method 0x9953df92. +// Update0 is a paid mutator transaction binding the contract method 0x9924c17e. // // Solidity: function update([]Condition conditions, Limit limit, []UpdateField updateFields) returns(int32) -func (_Table *TableTransactorSession) Update0(conditions []Condition, limit Limit, updateFields []UpdateField) (*types.Transaction, *types.Receipt, error) { +func (_Table *TableTransactorSession) Update0(conditions []Condition, limit Limit, updateFields []UpdateField) (int32, *types.Transaction, *types.Receipt, error) { return _Table.Contract.Update0(&_Table.TransactOpts, conditions, limit, updateFields) } diff --git a/precompiled/crud/tableManager.go b/precompiled/crud/tableManager.go index 9fb5d6c8..b96de145 100644 --- a/precompiled/crud/tableManager.go +++ b/precompiled/crud/tableManager.go @@ -26,12 +26,13 @@ var ( // TableInfo is an auto generated low-level Go binding around an user-defined struct. type TableInfo struct { + KeyOrder uint8 KeyColumn string ValueColumns []string } // TableManagerABI is the input ABI used to generate the binding from. -const TableManagerABI = "[{\"inputs\":[{\"internalType\":\"string\",\"name\":\"path\",\"type\":\"string\"},{\"internalType\":\"string[]\",\"name\":\"newColumns\",\"type\":\"string[]\"}],\"name\":\"appendColumns\",\"outputs\":[{\"internalType\":\"int32\",\"name\":\"\",\"type\":\"int32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"tableName\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"keyField\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"valueField\",\"type\":\"string\"}],\"name\":\"createKVTable\",\"outputs\":[{\"internalType\":\"int32\",\"name\":\"\",\"type\":\"int32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"path\",\"type\":\"string\"},{\"components\":[{\"internalType\":\"string\",\"name\":\"keyColumn\",\"type\":\"string\"},{\"internalType\":\"string[]\",\"name\":\"valueColumns\",\"type\":\"string[]\"}],\"internalType\":\"structTableInfo\",\"name\":\"tableInfo\",\"type\":\"tuple\"}],\"name\":\"createTable\",\"outputs\":[{\"internalType\":\"int32\",\"name\":\"\",\"type\":\"int32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"tableName\",\"type\":\"string\"}],\"name\":\"desc\",\"outputs\":[{\"components\":[{\"internalType\":\"string\",\"name\":\"keyColumn\",\"type\":\"string\"},{\"internalType\":\"string[]\",\"name\":\"valueColumns\",\"type\":\"string[]\"}],\"internalType\":\"structTableInfo\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"path\",\"type\":\"string\"}],\"name\":\"openTable\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]" +const TableManagerABI = "[{\"inputs\":[{\"internalType\":\"string\",\"name\":\"path\",\"type\":\"string\"},{\"internalType\":\"string[]\",\"name\":\"newColumns\",\"type\":\"string[]\"}],\"name\":\"appendColumns\",\"outputs\":[{\"internalType\":\"int32\",\"name\":\"\",\"type\":\"int32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"tableName\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"keyField\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"valueField\",\"type\":\"string\"}],\"name\":\"createKVTable\",\"outputs\":[{\"internalType\":\"int32\",\"name\":\"\",\"type\":\"int32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"path\",\"type\":\"string\"},{\"components\":[{\"internalType\":\"enumKeyOrder\",\"name\":\"keyOrder\",\"type\":\"uint8\"},{\"internalType\":\"string\",\"name\":\"keyColumn\",\"type\":\"string\"},{\"internalType\":\"string[]\",\"name\":\"valueColumns\",\"type\":\"string[]\"}],\"internalType\":\"structTableInfo\",\"name\":\"tableInfo\",\"type\":\"tuple\"}],\"name\":\"createTable\",\"outputs\":[{\"internalType\":\"int32\",\"name\":\"\",\"type\":\"int32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"tableName\",\"type\":\"string\"}],\"name\":\"descWithKeyOrder\",\"outputs\":[{\"components\":[{\"internalType\":\"enumKeyOrder\",\"name\":\"keyOrder\",\"type\":\"uint8\"},{\"internalType\":\"string\",\"name\":\"keyColumn\",\"type\":\"string\"},{\"internalType\":\"string[]\",\"name\":\"valueColumns\",\"type\":\"string[]\"}],\"internalType\":\"structTableInfo\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"path\",\"type\":\"string\"}],\"name\":\"openTable\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]" // TableManager is an auto generated Go binding around a Solidity contract. type TableManager struct { @@ -152,8 +153,8 @@ func (_TableManager *TableManagerRaw) Transfer(opts *bind.TransactOpts) (*types. } // Transact invokes the (paid) contract method with params as input values. -func (_TableManager *TableManagerRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, *types.Receipt, error) { - return _TableManager.Contract.TableManagerTransactor.contract.Transact(opts, method, params...) +func (_TableManager *TableManagerRaw) TransactWithResult(opts *bind.TransactOpts, result interface{}, method string, params ...interface{}) (*types.Transaction, *types.Receipt, error) { + return _TableManager.Contract.TableManagerTransactor.contract.TransactWithResult(opts, result, method, params...) } // Call invokes the (constant) contract method with params as input values and @@ -171,34 +172,34 @@ func (_TableManager *TableManagerTransactorRaw) Transfer(opts *bind.TransactOpts } // Transact invokes the (paid) contract method with params as input values. -func (_TableManager *TableManagerTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, *types.Receipt, error) { - return _TableManager.Contract.contract.Transact(opts, method, params...) +func (_TableManager *TableManagerTransactorRaw) TransactWithResult(opts *bind.TransactOpts, result interface{}, method string, params ...interface{}) (*types.Transaction, *types.Receipt, error) { + return _TableManager.Contract.contract.TransactWithResult(opts, result, method, params...) } -// Desc is a free data retrieval call binding the contract method 0x5d0d6d54. +// DescWithKeyOrder is a free data retrieval call binding the contract method 0xb8764d3f. // -// Solidity: function desc(string tableName) constant returns(TableInfo) -func (_TableManager *TableManagerCaller) Desc(opts *bind.CallOpts, tableName string) (TableInfo, error) { +// Solidity: function descWithKeyOrder(string tableName) constant returns(TableInfo) +func (_TableManager *TableManagerCaller) DescWithKeyOrder(opts *bind.CallOpts, tableName string) (TableInfo, error) { var ( ret0 = new(TableInfo) ) out := ret0 - err := _TableManager.contract.Call(opts, out, "desc", tableName) + err := _TableManager.contract.Call(opts, out, "descWithKeyOrder", tableName) return *ret0, err } -// Desc is a free data retrieval call binding the contract method 0x5d0d6d54. +// DescWithKeyOrder is a free data retrieval call binding the contract method 0xb8764d3f. // -// Solidity: function desc(string tableName) constant returns(TableInfo) -func (_TableManager *TableManagerSession) Desc(tableName string) (TableInfo, error) { - return _TableManager.Contract.Desc(&_TableManager.CallOpts, tableName) +// Solidity: function descWithKeyOrder(string tableName) constant returns(TableInfo) +func (_TableManager *TableManagerSession) DescWithKeyOrder(tableName string) (TableInfo, error) { + return _TableManager.Contract.DescWithKeyOrder(&_TableManager.CallOpts, tableName) } -// Desc is a free data retrieval call binding the contract method 0x5d0d6d54. +// DescWithKeyOrder is a free data retrieval call binding the contract method 0xb8764d3f. // -// Solidity: function desc(string tableName) constant returns(TableInfo) -func (_TableManager *TableManagerCallerSession) Desc(tableName string) (TableInfo, error) { - return _TableManager.Contract.Desc(&_TableManager.CallOpts, tableName) +// Solidity: function descWithKeyOrder(string tableName) constant returns(TableInfo) +func (_TableManager *TableManagerCallerSession) DescWithKeyOrder(tableName string) (TableInfo, error) { + return _TableManager.Contract.DescWithKeyOrder(&_TableManager.CallOpts, tableName) } // OpenTable is a free data retrieval call binding the contract method 0xf23f63c9. @@ -230,8 +231,13 @@ func (_TableManager *TableManagerCallerSession) OpenTable(path string) (common.A // AppendColumns is a paid mutator transaction binding the contract method 0x302baee0. // // Solidity: function appendColumns(string path, string[] newColumns) returns(int32) -func (_TableManager *TableManagerTransactor) AppendColumns(opts *bind.TransactOpts, path string, newColumns []string) (*types.Transaction, *types.Receipt, error) { - return _TableManager.contract.Transact(opts, "appendColumns", path, newColumns) +func (_TableManager *TableManagerTransactor) AppendColumns(opts *bind.TransactOpts, path string, newColumns []string) (int32, *types.Transaction, *types.Receipt, error) { + var ( + ret0 = new(int32) + ) + out := ret0 + transaction, receipt, err := _TableManager.contract.TransactWithResult(opts, out, "appendColumns", path, newColumns) + return *ret0, transaction, receipt, err } func (_TableManager *TableManagerTransactor) AsyncAppendColumns(handler func(*types.Receipt, error), opts *bind.TransactOpts, path string, newColumns []string) (*types.Transaction, error) { @@ -241,7 +247,7 @@ func (_TableManager *TableManagerTransactor) AsyncAppendColumns(handler func(*ty // AppendColumns is a paid mutator transaction binding the contract method 0x302baee0. // // Solidity: function appendColumns(string path, string[] newColumns) returns(int32) -func (_TableManager *TableManagerSession) AppendColumns(path string, newColumns []string) (*types.Transaction, *types.Receipt, error) { +func (_TableManager *TableManagerSession) AppendColumns(path string, newColumns []string) (int32, *types.Transaction, *types.Receipt, error) { return _TableManager.Contract.AppendColumns(&_TableManager.TransactOpts, path, newColumns) } @@ -252,7 +258,7 @@ func (_TableManager *TableManagerSession) AsyncAppendColumns(handler func(*types // AppendColumns is a paid mutator transaction binding the contract method 0x302baee0. // // Solidity: function appendColumns(string path, string[] newColumns) returns(int32) -func (_TableManager *TableManagerTransactorSession) AppendColumns(path string, newColumns []string) (*types.Transaction, *types.Receipt, error) { +func (_TableManager *TableManagerTransactorSession) AppendColumns(path string, newColumns []string) (int32, *types.Transaction, *types.Receipt, error) { return _TableManager.Contract.AppendColumns(&_TableManager.TransactOpts, path, newColumns) } @@ -263,8 +269,13 @@ func (_TableManager *TableManagerTransactorSession) AsyncAppendColumns(handler f // CreateKVTable is a paid mutator transaction binding the contract method 0xb0e89adb. // // Solidity: function createKVTable(string tableName, string keyField, string valueField) returns(int32) -func (_TableManager *TableManagerTransactor) CreateKVTable(opts *bind.TransactOpts, tableName string, keyField string, valueField string) (*types.Transaction, *types.Receipt, error) { - return _TableManager.contract.Transact(opts, "createKVTable", tableName, keyField, valueField) +func (_TableManager *TableManagerTransactor) CreateKVTable(opts *bind.TransactOpts, tableName string, keyField string, valueField string) (int32, *types.Transaction, *types.Receipt, error) { + var ( + ret0 = new(int32) + ) + out := ret0 + transaction, receipt, err := _TableManager.contract.TransactWithResult(opts, out, "createKVTable", tableName, keyField, valueField) + return *ret0, transaction, receipt, err } func (_TableManager *TableManagerTransactor) AsyncCreateKVTable(handler func(*types.Receipt, error), opts *bind.TransactOpts, tableName string, keyField string, valueField string) (*types.Transaction, error) { @@ -274,7 +285,7 @@ func (_TableManager *TableManagerTransactor) AsyncCreateKVTable(handler func(*ty // CreateKVTable is a paid mutator transaction binding the contract method 0xb0e89adb. // // Solidity: function createKVTable(string tableName, string keyField, string valueField) returns(int32) -func (_TableManager *TableManagerSession) CreateKVTable(tableName string, keyField string, valueField string) (*types.Transaction, *types.Receipt, error) { +func (_TableManager *TableManagerSession) CreateKVTable(tableName string, keyField string, valueField string) (int32, *types.Transaction, *types.Receipt, error) { return _TableManager.Contract.CreateKVTable(&_TableManager.TransactOpts, tableName, keyField, valueField) } @@ -285,7 +296,7 @@ func (_TableManager *TableManagerSession) AsyncCreateKVTable(handler func(*types // CreateKVTable is a paid mutator transaction binding the contract method 0xb0e89adb. // // Solidity: function createKVTable(string tableName, string keyField, string valueField) returns(int32) -func (_TableManager *TableManagerTransactorSession) CreateKVTable(tableName string, keyField string, valueField string) (*types.Transaction, *types.Receipt, error) { +func (_TableManager *TableManagerTransactorSession) CreateKVTable(tableName string, keyField string, valueField string) (int32, *types.Transaction, *types.Receipt, error) { return _TableManager.Contract.CreateKVTable(&_TableManager.TransactOpts, tableName, keyField, valueField) } @@ -293,21 +304,26 @@ func (_TableManager *TableManagerTransactorSession) AsyncCreateKVTable(handler f return _TableManager.Contract.AsyncCreateKVTable(handler, &_TableManager.TransactOpts, tableName, keyField, valueField) } -// CreateTable is a paid mutator transaction binding the contract method 0x31a5a51e. +// CreateTable is a paid mutator transaction binding the contract method 0x75b14eea. // // Solidity: function createTable(string path, TableInfo tableInfo) returns(int32) -func (_TableManager *TableManagerTransactor) CreateTable(opts *bind.TransactOpts, path string, tableInfo TableInfo) (*types.Transaction, *types.Receipt, error) { - return _TableManager.contract.Transact(opts, "createTable", path, tableInfo) +func (_TableManager *TableManagerTransactor) CreateTable(opts *bind.TransactOpts, path string, tableInfo TableInfo) (int32, *types.Transaction, *types.Receipt, error) { + var ( + ret0 = new(int32) + ) + out := ret0 + transaction, receipt, err := _TableManager.contract.TransactWithResult(opts, out, "createTable", path, tableInfo) + return *ret0, transaction, receipt, err } func (_TableManager *TableManagerTransactor) AsyncCreateTable(handler func(*types.Receipt, error), opts *bind.TransactOpts, path string, tableInfo TableInfo) (*types.Transaction, error) { return _TableManager.contract.AsyncTransact(opts, handler, "createTable", path, tableInfo) } -// CreateTable is a paid mutator transaction binding the contract method 0x31a5a51e. +// CreateTable is a paid mutator transaction binding the contract method 0x75b14eea. // // Solidity: function createTable(string path, TableInfo tableInfo) returns(int32) -func (_TableManager *TableManagerSession) CreateTable(path string, tableInfo TableInfo) (*types.Transaction, *types.Receipt, error) { +func (_TableManager *TableManagerSession) CreateTable(path string, tableInfo TableInfo) (int32, *types.Transaction, *types.Receipt, error) { return _TableManager.Contract.CreateTable(&_TableManager.TransactOpts, path, tableInfo) } @@ -315,10 +331,10 @@ func (_TableManager *TableManagerSession) AsyncCreateTable(handler func(*types.R return _TableManager.Contract.AsyncCreateTable(handler, &_TableManager.TransactOpts, path, tableInfo) } -// CreateTable is a paid mutator transaction binding the contract method 0x31a5a51e. +// CreateTable is a paid mutator transaction binding the contract method 0x75b14eea. // // Solidity: function createTable(string path, TableInfo tableInfo) returns(int32) -func (_TableManager *TableManagerTransactorSession) CreateTable(path string, tableInfo TableInfo) (*types.Transaction, *types.Receipt, error) { +func (_TableManager *TableManagerTransactorSession) CreateTable(path string, tableInfo TableInfo) (int32, *types.Transaction, *types.Receipt, error) { return _TableManager.Contract.CreateTable(&_TableManager.TransactOpts, path, tableInfo) } diff --git a/precompiled/crud/tableManager_service.go b/precompiled/crud/tableManager_service.go new file mode 100644 index 00000000..ed7234f8 --- /dev/null +++ b/precompiled/crud/tableManager_service.go @@ -0,0 +1,382 @@ +package crud + +import ( + //"encoding/json" + "fmt" + "math/big" + + "github.com/FISCO-BCOS/go-sdk/abi/bind" + "github.com/FISCO-BCOS/go-sdk/client" + "github.com/FISCO-BCOS/go-sdk/core/types" + "github.com/FISCO-BCOS/go-sdk/precompiled" + "github.com/ethereum/go-ethereum/common" +) + +const ( + TableKeyMaxLength int = 255 + + //crud precompiled contract error code + conditionOperationUndefined int64 = -51502 + parseConditionError int64 = -51501 + parseEntryError int64 = -51500 +) + +// getErrorMessage returns the message of error code +func getErrorMessage(errorCode int64) string { + var message string + switch errorCode { + case conditionOperationUndefined: + message = "condition operation undefined" + case parseConditionError: + message = "parse condition error" + case parseEntryError: + message = "parse entry error" + default: + message = "" + } + return message +} + +// errorCodeToError judges whether the error code represents an error +func errorCodeToError(errorCode int64) error { + var errorCodeMessage string + errorCodeMessage = precompiled.GetCommonErrorCodeMessage(errorCode) + if errorCodeMessage != "" { + return fmt.Errorf("error code: %v, error code message: %v", errorCode, errorCodeMessage) + } + errorCodeMessage = getErrorMessage(errorCode) + if errorCodeMessage != "" { + return fmt.Errorf("error code: %v, error code message: %v", errorCode, errorCodeMessage) + } + return nil +} + +type Service struct { + table *Table + tableManager *TableManager + KVTable *KVTable + tableManagerAuth *bind.TransactOpts + CallOpts *bind.CallOpts + client *client.Client +} + +var TableManagerAddress = common.HexToAddress("0x1002") + +func NewTableManagerService(client *client.Client) (*Service, error) { + tableManagerInstance, err := NewTableManager(TableManagerAddress, client) + if err != nil { + return nil, fmt.Errorf("construct CRUD failed: %+v", err) + } + auth := client.GetTransactOpts() + callOpts := client.GetCallOpts() + return &Service{tableManager: tableManagerInstance, tableManagerAuth: auth, CallOpts: callOpts, client: client}, nil +} + +/** + * ************************************************************************************************************** + * TableManager + * ************************************************************************************************************** +**/ +func (service *Service) CreateTable(tableName string, key string, valueFields []string) (int64, error) { + tableInfo := TableInfo{ + KeyColumn: key, + ValueColumns: valueFields, + } + _, _, receipt, err := service.tableManager.CreateTable(service.tableManagerAuth, tableName, tableInfo) + if err != nil { + return precompiled.DefaultErrorCode, fmt.Errorf("tableManagerService CreateTable failed: %v", err) + } + + address, err := service.tableManager.OpenTable(service.CallOpts, tableName) + if err != nil { + return precompiled.DefaultErrorCode, fmt.Errorf("tableManagerService OpenTable failed: %v", err) + } + fmt.Println("CreateTable address:", address) + crudInstance, err := NewTable(address, service.client) + if err != nil { + return precompiled.DefaultErrorCode, fmt.Errorf("construct TableFactor failed: %+v", err) + } + service.table = crudInstance + return parseReturnValue(receipt, "createTable") +} + +func (service *Service) AsyncCreateTable(handler func(*types.Receipt, error), tableName string, key string, valueFields []string) (*types.Transaction, error) { + tableInfo := TableInfo{ + KeyColumn: key, + ValueColumns: valueFields, + } + return service.tableManager.AsyncCreateTable(handler, service.tableManagerAuth, tableName, tableInfo) +} + +func (service *Service) CreateKVTable(tableName string, keyField string, valueField string) (int64, error) { + _, _, receipt, err := service.tableManager.CreateKVTable(service.tableManagerAuth, tableName, keyField, valueField) + if err != nil { + return precompiled.DefaultErrorCode, fmt.Errorf("tableManagerService CreateKVTable failed: %v", err) + } + + address, err := service.tableManager.OpenTable(service.CallOpts, tableName) + if err != nil { + return precompiled.DefaultErrorCode, fmt.Errorf("tableManagerService OpenTable failed: %v", err) + } + fmt.Println("CreateKVTable address:", address) + crudInstance, err := NewTable(address, service.client) + if err != nil { + return precompiled.DefaultErrorCode, fmt.Errorf("construct TableFactor failed: %+v", err) + } + service.table = crudInstance + return parseReturnValue(receipt, "createKVTable") +} + +func (service *Service) AsyncCreateKVTable(handler func(*types.Receipt, error), tableName string, keyField string, valueField string) (*types.Transaction, error) { + return service.tableManager.AsyncCreateKVTable(handler, service.tableManagerAuth, tableName, keyField, valueField) +} + +func (service *Service) OpenTable(tableName string) (int64, error) { + address, err := service.tableManager.OpenTable(service.CallOpts, tableName) + if err != nil { + return precompiled.DefaultErrorCode, fmt.Errorf("tableManagerService OpenTable failed: %v", err) + } + fmt.Println("OpenTable address:", address) + crudInstance, err := NewTable(address, service.client) + if err != nil { + return precompiled.DefaultErrorCode, fmt.Errorf("construct TableFactor failed: %+v", err) + } + service.table = crudInstance + return 0, nil +} + +func (service *Service) OpenKVTable(tableName string) (int64, error) { + address, err := service.tableManager.OpenTable(service.CallOpts, tableName) + if err != nil { + return precompiled.DefaultErrorCode, fmt.Errorf("tableManagerService OpenTable failed: %v", err) + } + fmt.Println("OpenTable address:", address) + KVTableInstance, err := NewKVTable(address, service.client) + if err != nil { + return precompiled.DefaultErrorCode, fmt.Errorf("construct TableFactor failed: %+v", err) + } + service.KVTable = KVTableInstance + return 0, nil +} + +func (service *Service) AppendColumns(path string, newColumns []string) (int64, error) { + _, _, receipt, err := service.tableManager.AppendColumns(service.tableManagerAuth, path, newColumns) + if err != nil { + return precompiled.DefaultErrorCode, fmt.Errorf("tableManagerService AppendColumns failed: %v", err) + } + return parseReturnValue(receipt, "createTable") +} + +func (service *Service) AsyncAppendColumns(handler func(*types.Receipt, error), path string, newColumns []string) (*types.Transaction, error) { + return service.tableManager.AsyncAppendColumns(handler, service.tableManagerAuth, path, newColumns) +} + +func (service *Service) DescWithKeyOrder(tableName string) (TableInfo, error) { + opts := &bind.CallOpts{From: service.tableManagerAuth.From} + ret0, err := service.tableManager.DescWithKeyOrder(opts, tableName) + if err != nil { + return *new(TableInfo), fmt.Errorf("tableManagerService DescWithKeyOrder failed: %v", err) + } + return ret0, err +} + +/** + * ************************************************************************************************************** + * Table + * ************************************************************************************************************** +**/ +func (service *Service) Insert(tableName string, entry Entry) (int64, error) { + _, err := service.OpenTable(tableName) + if err !=nil{ + return -1, fmt.Errorf("the table does not exist") + } + if len(entry.Key) > TableKeyMaxLength { + return -1, fmt.Errorf("the value of the table key exceeds the maximum limit( %d )", TableKeyMaxLength) + } + _, _, receipt, err := service.table.Insert(service.tableManagerAuth, entry) + if err != nil { + return -1, fmt.Errorf("tableManagerService Insert failed: %v", err) + } + return parseReturnValue(receipt, "insert") +} + +func (service *Service) AsyncInsert(handler func(*types.Receipt, error), tableName string, entry Entry) (*types.Transaction, error) { + _, err := service.OpenTable(tableName) + if err !=nil{ + return nil, fmt.Errorf("the table does not exist") + } + if len(entry.Key) > TableKeyMaxLength { + return nil, fmt.Errorf("the value of the table key exceeds the maximum limit( %d )", TableKeyMaxLength) + } + return service.table.AsyncInsert(handler, service.tableManagerAuth, entry) +} + +func (service *Service) Select0(tableName string, key string) (Entry, error) { + _, err := service.OpenTable(tableName) + if err !=nil{ + return Entry{}, fmt.Errorf("the table does not exist") + } + if len(key) > TableKeyMaxLength { + return Entry{}, fmt.Errorf("the value of the table key exceeds the maximum limit( %d )", TableKeyMaxLength) + } + entry, err := service.table.Select0(service.CallOpts, key) + if err != nil { + return Entry{}, fmt.Errorf("tableManagerService Select failed: %v", err) + } + return entry, nil +} + +func (service *Service) Select(tableName string, conditions []Condition, limit Limit) ([]Entry, error) { + _, err := service.OpenTable(tableName) + if err !=nil{ + return nil, fmt.Errorf("the table does not exist") + } + entries, err := service.table.Select(service.CallOpts, conditions, limit) + if err != nil { + return nil, fmt.Errorf("tableManagerService Select failed: %v", err) + } + return entries, nil +} + +func (service *Service) Update(tableName string, key string, updateFields []UpdateField) (int64, error) { + _, err := service.OpenTable(tableName) + if err !=nil{ + return -1, fmt.Errorf("the table does not exist") + } + if len(key) > TableKeyMaxLength { + return -1, fmt.Errorf("the value of the table key exceeds the maximum limit( %d )", TableKeyMaxLength) + } + _, _, receipt, err := service.table.Update(service.tableManagerAuth, key, updateFields) + if err != nil { + return -1, fmt.Errorf("tableManagerService Update failed: %v", err) + } + return parseReturnValue(receipt, "update") +} + +func (service *Service) Update0(tableName string, conditions []Condition, limit Limit, updateFields []UpdateField) (int64, error) { + _, err := service.OpenTable(tableName) + if err !=nil{ + return -1, fmt.Errorf("the table does not exist") + } + _, _, receipt, err := service.table.Update0(service.tableManagerAuth, conditions, limit, updateFields) + if err != nil { + return -1, fmt.Errorf("tableManagerService Update failed: %v", err) + } + return parseReturnValue(receipt, "update0") +} + +func (service *Service) AsyncUpdate(handler func(*types.Receipt, error), tableName string, key string, updateFields []UpdateField) (*types.Transaction, error) { + _, err := service.OpenTable(tableName) + if err !=nil{ + return nil, fmt.Errorf("the table does not exist") + } + if len(key) > TableKeyMaxLength { + return nil, fmt.Errorf("the value of the table key exceeds the maximum limit( %d )", TableKeyMaxLength) + } + return service.table.AsyncUpdate(handler, service.tableManagerAuth, key, updateFields) +} + +func (service *Service) AsyncUpdate0(handler func(*types.Receipt, error), tableName string, conditions []Condition, limit Limit, updateFields []UpdateField) (*types.Transaction, error) { + _, err := service.OpenTable(tableName) + if err !=nil{ + return nil, fmt.Errorf("the table does not exist") + } + return service.table.AsyncUpdate0(handler, service.tableManagerAuth, conditions, limit, updateFields) +} + +func (service *Service) Remove(tableName string, key string) (int64, error) { + _, err := service.OpenTable(tableName) + if err !=nil{ + return -1, fmt.Errorf("the table does not exist") + } + if len(key) > TableKeyMaxLength { + return -1, fmt.Errorf("the value of the table key exceeds the maximum limit( %d )", TableKeyMaxLength) + } + _, _, receipt, err := service.table.Remove(service.tableManagerAuth, key) + if err != nil { + return -1, fmt.Errorf("tableManagerService Remove failed: %v", err) + } + return parseReturnValue(receipt, "remove") +} + +func (service *Service) Remove0(tableName string, conditions []Condition, limit Limit) (int64, error) { + _, err := service.OpenTable(tableName) + if err !=nil{ + return -1, fmt.Errorf("the table does not exist") + } + _, _, receipt, err := service.table.Remove0(service.tableManagerAuth, conditions, limit) + if err != nil { + return -1, fmt.Errorf("tableManagerService Remove failed: %v", err) + } + return parseReturnValue(receipt, "remove0") +} + +func (service *Service) AsyncRemove(handler func(*types.Receipt, error), tableName string, key string) (*types.Transaction, error) { + _, err := service.OpenTable(tableName) + if err !=nil{ + return nil, fmt.Errorf("the table does not exist") + } + if len(key) > TableKeyMaxLength { + return nil, fmt.Errorf("the value of the table key exceeds the maximum limit( %d )", TableKeyMaxLength) + } + return service.table.AsyncRemove(handler, service.tableManagerAuth, key) +} + +func (service *Service) AsyncRemove0(handler func(*types.Receipt, error), tableName string, conditions []Condition, limit Limit) (*types.Transaction, error) { + _, err := service.OpenTable(tableName) + if err !=nil{ + return nil, fmt.Errorf("the table does not exist") + } + return service.table.AsyncRemove0(handler, service.tableManagerAuth, conditions, limit) +} + +/** + * ************************************************************************************************************** + * KVTable + * ************************************************************************************************************** +**/ +func (service *Service) Set(tableName string, key string, value string) (int64, error) { + _, err := service.OpenKVTable(tableName) + if err !=nil{ + return -1, fmt.Errorf("the table does not exist") + } + _, _, receipt, err := service.KVTable.Set(service.tableManagerAuth, key, value) + if err != nil { + return -1, fmt.Errorf("tableManagerService Set failed: %v", err) + } + return parseReturnValue(receipt, "set") +} + +func (service *Service) Get(tableName string, key string) (bool, string, error) { + _, err := service.OpenKVTable(tableName) + if err !=nil{ + return false, "", fmt.Errorf("the table does not exist") + } + ret0, ret1, err := service.KVTable.Get(service.CallOpts, key) + if err != nil { + return false, "", fmt.Errorf("KVTable Get failed: %v", err) + } + return ret0, ret1, err +} + +func parseReturnValue(receipt *types.Receipt, name string) (int64, error) { + errorMessage := receipt.GetErrorMessage() + if errorMessage != "" { + return int64(receipt.GetStatus()), fmt.Errorf("receipt.Status err: %v", errorMessage) + } + var bigNum *big.Int + var err error + if name == "createTable" { + bigNum, err = precompiled.ParseBigIntFromOutput(receipt) + } else { + bigNum, err = precompiled.ParseBigIntFromOutput(receipt) + } + if err != nil { + return precompiled.DefaultErrorCode, fmt.Errorf("parseReturnValue failed, err: %v", err) + } + errorCode, err := precompiled.BigIntToInt64(bigNum) + if err != nil { + return precompiled.DefaultErrorCode, fmt.Errorf("parseReturnValue failed, err: %v", err) + } + return errorCode, errorCodeToError(errorCode) +} \ No newline at end of file diff --git a/precompiled/crud/tableManager_service_test.go b/precompiled/crud/tableManager_service_test.go new file mode 100644 index 00000000..adf7f4c9 --- /dev/null +++ b/precompiled/crud/tableManager_service_test.go @@ -0,0 +1,646 @@ +package crud + +import ( + "context" + "encoding/hex" + "math/big" + "os" + "testing" + "time" + // "fmt" + "math/rand" + + "github.com/FISCO-BCOS/go-sdk/client" + "github.com/FISCO-BCOS/go-sdk/core/types" + "github.com/FISCO-BCOS/go-sdk/precompiled" +) + +const ( + tableName = "tableName" + tableNameForAsync = "tableName_async" + KVTableName = "kvtableName" + KVTableNameForAsync = "kvtableName_async" + tablePath = "/tables/tableName" + key = "keyName" + timeout = 1 * time.Second +) +var columnValue = "columnValue" +var columnName = "columnName" +var columnNames = []string{"columnName"} +var condition = Condition{ + Op: uint8(4), //EQ + Field: "columnName", + Value: "columnValue", +} +var limit = Limit{ + Offset: uint32(0), + Count: uint32(4), +} +var columnNames_update = []string{"columnName_update"} +var conditions = []Condition{condition} + +var ( + service *Service + channel = make(chan int) +) + +func getClient(t *testing.T) *client.Client { + privateKey, _ := hex.DecodeString("145e247e170ba3afd6ae97e88f00dbc976c2345d511b0f6713355d19d8b80b58") + config := &client.Config{IsSMCrypto: false, GroupID: "group0", + PrivateKey: privateKey, Host: "127.0.0.1", Port: 20200, TLSCaFile: "./ca.crt", TLSKeyFile: "./sdk.key", TLSCertFile: "./sdk.crt"} + c, err := client.DialContext(context.Background(), config) + if err != nil { + t.Fatalf("Dial to %s:%d failed of %v", config.Host, config.Port, err) + } + return c +} + +func getService(t *testing.T) { + c := getClient(t) + newService, err := NewTableManagerService(c) + if err != nil { + t.Fatalf("init CrudService failed: %+v", err) + } + service = newService +} + +func TestMain(m *testing.M) { + getService(&testing.T{}) + exitCode := m.Run() + os.Exit(exitCode) +} + +func TestCreateTable(t *testing.T) { + result, err := service.CreateTable(tableName, key, columnNames) + if err != nil { + t.Fatalf("create table failed: %v", err) + } + if result != 0 { + t.Fatalf("TestCreateTable failed, the result \"%v\" is inconsistent with \"0\"", result) + } + t.Logf("result: %d\n", result) +} + +func TestAsyncCreateTable(t *testing.T) { + handler := func(receipt *types.Receipt, err error) { + if err != nil { + t.Fatalf("receive receipt failed, %v\n", err) + } + var bigNum *big.Int + bigNum, err = precompiled.ParseBigIntFromOutput(receipt) + if err != nil { + t.Fatalf("parseReturnValue failed, err: %v\n", err) + } + result, err := precompiled.BigIntToInt64(bigNum) + if err != nil { + t.Fatalf("%v\n", err) + } + if result != 0 { + t.Fatalf("TestAsyncCreateTable failed, the result \"%v\" is inconsistent with \"0\"", result) + } + t.Logf("result: %d\n", result) + channel <- 0 + } + + _, err := service.AsyncCreateTable(handler, tableNameForAsync, key, columnNames) + if err != nil { + t.Fatalf("create table failed: %v", err) + } + select { + case <-channel: + return + case <-time.After(timeout): + t.Fatal("timeout") + } +} + +func TestCreateKVTable(t *testing.T) { + result, err := service.CreateKVTable(KVTableName, key, columnName) + if err != nil { + t.Fatalf("create table failed: %v", err) + } + if result != 0 { + t.Fatalf("TestCreateKVTable failed, the result \"%v\" is inconsistent with \"0\"", result) + } + t.Logf("result: %d\n", result) +} + +func TestAsyncCreateKVTable(t *testing.T) { + handler := func(receipt *types.Receipt, err error) { + if err != nil { + t.Fatalf("receive receipt failed, %v\n", err) + } + var bigNum *big.Int + bigNum, err = precompiled.ParseBigIntFromOutput(receipt) + if err != nil { + t.Fatalf("parseReturnValue failed, err: %v\n", err) + } + result, err := precompiled.BigIntToInt64(bigNum) + if err != nil { + t.Fatalf("%v\n", err) + } + if result != 0 { + t.Fatalf("TestAsyncCreateKVTable failed, the result \"%v\" is inconsistent with \"0\"", result) + } + t.Logf("result: %d\n", result) + channel <- 0 + } + + _, err := service.AsyncCreateKVTable(handler, KVTableNameForAsync, key, columnName) + if err != nil { + t.Fatalf("create table failed: %v", err) + } + select { + case <-channel: + return + case <-time.After(timeout): + t.Fatal("timeout") + } +} + +func TestAppendColumns(t *testing.T) { + newColumns:=[]string{"columnName_0","columnName_1"} + + result, err := service.AppendColumns(tablePath, newColumns) + if err != nil { + t.Fatalf("create AppendColumns failed: %v", err) + } + if result != 0 { + t.Fatalf("TestAppendColumns failed, the result \"%v\" is inconsistent with \"0\"", result) + } + t.Logf("result: %d\n", result) +} + +func TestAsyncAppendColumns(t *testing.T) { + newColumns:=[]string{"columnName_2","columnName_3"} + + handler := func(receipt *types.Receipt, err error) { + if err != nil { + t.Fatalf("receive receipt failed, %v\n", err) + } + var bigNum *big.Int + bigNum, err = precompiled.ParseBigIntFromOutput(receipt) + if err != nil { + t.Fatalf("parseReturnValue failed, err: %v\n", err) + } + result, err := precompiled.BigIntToInt64(bigNum) + if err != nil { + t.Fatalf("%v\n", err) + } + if result != 0 { + t.Fatalf("TestAsyncAppendColumns failed, the result \"%v\" is inconsistent with \"0\"", result) + } + t.Logf("result: %d\n", result) + channel <- 0 + } + + _, err := service.AsyncAppendColumns(handler, tablePath, newColumns) + if err != nil { + t.Fatalf("AsyncAppendColumns failed: %v", err) + } + select { + case <-channel: + return + case <-time.After(timeout): + t.Fatal("timeout") + } +} + +func TestDescWithKeyOrder(t *testing.T) { + tableInfo, err := service.DescWithKeyOrder(tableName) + if err != nil { + t.Fatalf("query table info by tableName failed: %v", err) + } + if tableInfo.KeyColumn != key { + t.Fatalf("TestDesc failed, the keyField \"%v\" is not inconsistent with \"name\"", tableInfo.KeyColumn) + } + if tableInfo.ValueColumns[0] != columnNames[0] { + t.Fatalf("TestDesc failed, the columnName \"%v\" is not inconsistent with \"item_id,column_name\"", tableInfo.ValueColumns[0]) + } + t.Logf("keyFiled is:%s\n", tableInfo.KeyColumn) + t.Logf("columnName is:%s\n", tableInfo.ValueColumns[0]) +} + +func TestInsert(t *testing.T) { + _, err := service.OpenTable(tableName) + if err !=nil{ + service.CreateTable(tableName, key, columnNames) + } + // tempColumnValues's length needs to be the same as the number of columns + tempColumnValues := []string{} + tableInfo, err := service.DescWithKeyOrder(tableName) + for i := 0; i < len(tableInfo.ValueColumns); i++ { + tempColumnValues=append(tempColumnValues,"columnValue") + } + key := randStringBytes(10) + t.Logf("key: %v\n", key) + entry := Entry{ + Key: key, + Fields: tempColumnValues, + } + + ret0, err := service.Insert(tableName,entry) + t.Logf("ret0: %v\n", ret0) + if err != nil { + t.Fatalf("insert table failed: %v", err) + } + + if ret0 != 1 { + t.Fatalf("TestInsert failed, the ret0 \"%v\" is inconsistent with \"1\"", ret0) + } + t.Logf("ret0: %d\n", ret0) +} + +func TestAsyncInsert(t *testing.T) { + handler := func(receipt *types.Receipt, err error) { + if err != nil { + t.Fatalf("receive receipt failed, %v\n", err) + } + var bigNum *big.Int + bigNum, err = precompiled.ParseBigIntFromOutput(receipt) + if err != nil { + t.Fatalf("parseReturnValue failed, err: %v\n", err) + } + result, err := precompiled.BigIntToInt64(bigNum) + if err != nil { + t.Fatalf("%v\n", err) + } + if result != 1 { + t.Fatalf("TestAsyncInsert failed, the result \"%v\" is inconsistent with \"1\"", result) + } + t.Logf("result: %d\n", result) + channel <- 0 + } + + _, err := service.OpenTable(tableName) + if err !=nil{ + service.CreateTable(tableName, key, columnNames) + } + // columnNames's length needs to be the same as the number of columns + tempColumnValues := []string{} + tableInfo, err := service.DescWithKeyOrder(tableName) + for i := 0; i < len(tableInfo.ValueColumns); i++ { + tempColumnValues=append(tempColumnValues,"columnValue") + } + key := randStringBytes(10) + t.Logf("key: %v\n", key) + entry := Entry{ + Key: key, + Fields: tempColumnValues, + } + + _, err = service.AsyncInsert(handler, tableName, entry) + if err != nil { + t.Fatalf("insert table failed: %v", err) + } + select { + case <-channel: + return + case <-time.After(timeout): + t.Fatal("timeout") + } +} + +func TestSelect0(t *testing.T) { + key := insertForTest() + + resultSelect, err := service.Select0(tableName, key) + if err != nil { + t.Fatalf("select table failed: %v", err) + } + if resultSelect.Fields[0] != columnValue { + t.Fatalf("TestSelect failed, the result of resultSelect \"%v\" is not inconsistent", resultSelect.Fields[0]) + } + t.Logf("resultSelect :\n") + + for i := 0; i < len(resultSelect.Fields); i++ { + t.Logf("resultSelect[%d]'s column_name is:%s\n", i, resultSelect.Fields[i]) + } +} + +func TestSelect(t *testing.T) { + insertForTest() + + resultSelects, err := service.Select(tableName, conditions, limit) + if err != nil { + t.Fatalf("select table failed: %v", err) + } + for i := 0; i < len(resultSelects); i++ { + if resultSelects[i].Fields[0] != columnValue { + t.Fatalf("TestSelect failed, the result of resultSelect \"%v\" is not inconsistent", resultSelects[i].Fields[0]) + } + } + t.Logf("resultSelects %v:",resultSelects) +} + +func TestUpdate(t *testing.T) { + // insert + key := insertForTest() + + // update + newValue := randStringBytes(10) + updateField := UpdateField{ + ColumnName: "columnName", + Value: newValue, + } + var updateFields []UpdateField + updateFields = append(updateFields, updateField) + _, err := service.Update(tableName, key, updateFields) + if err != nil { + t.Fatalf("update table failed: %v", err) + } + // check update results + resultSelect, err := service.Select0(tableName, key) + if err != nil { + t.Fatalf("select table failed: %v", err) + } + if resultSelect.Fields[0] != newValue { + t.Fatalf("TestUpdate failed, the result of resultUpdate \"%v\" is not inconsistent", resultSelect.Fields[0]) + } + t.Logf("updateResult: %s", resultSelect.Fields[0]) +} + +func TestUpdate0(t *testing.T) { + newValue := randStringBytes(10) + updateField := UpdateField{ + ColumnName: columnNames[0], + Value: newValue, + } + var updateFields []UpdateField + updateFields = append(updateFields, updateField) + + condition := Condition{ + Op: uint8(4), //EQ + Field: columnName, + Value: "columnValue", + } + conditions := []Condition{} + conditions=append(conditions,condition) + limit := Limit{ + Offset: uint32(0), + Count: uint32(4), + } + + newCondition := Condition{ + Op: uint8(4), //EQ + Field: columnName, + Value: newValue, + } + newConditions := []Condition{} + newConditions=append(newConditions,newCondition) + + // key origin results + originResultSelects, _ := service.Select(tableName, conditions, limit) + t.Logf("originResultSelects %v:",originResultSelects) + + // perform update + _, err := service.Update0(tableName, conditions, limit, updateFields) + if err != nil { + t.Fatalf("update table failed: %v", err) + } + + // check update results + afterResultSelects := []Entry{} + for i := 0; i < len(originResultSelects); i++ { + tempKey := originResultSelects[i].Key + tempResultSelect, _ := service.Select0(tableName, tempKey) + if tempResultSelect.Fields[0] != newValue { + t.Fatalf("TestSelect failed, the result of resultSelect \"%v\" is not inconsistent", tempResultSelect.Fields[0]) + } + afterResultSelects=append(afterResultSelects,tempResultSelect) + } + t.Logf("afterResultSelects %v:",afterResultSelects) +} + +func TestAsyncUpdate(t *testing.T) { + handler := func(receipt *types.Receipt, err error) { + if err != nil { + t.Fatalf("receive receipt failed, %v\n", err) + } + var bigNum *big.Int + bigNum, err = precompiled.ParseBigIntFromOutput(receipt) + if err != nil { + t.Fatalf("parseReturnValue failed, err: %v\n", err) + } + result, err := precompiled.BigIntToInt64(bigNum) + if err != nil { + t.Fatalf("%v\n", err) + } + if result != 1 { + t.Fatalf("TestAsyncUpdate failed, the result \"%v\" is inconsistent with \"1\"", result) + } + t.Logf("result: %d\n", result) + channel <- 0 + } + + key := insertForTest() + + newValue := randStringBytes(10) + t.Logf("newValue: %v\n", newValue) + updateField := UpdateField{ + ColumnName: columnName, + Value: newValue, + } + var updateFields []UpdateField + updateFields = append(updateFields, updateField) + _, err := service.AsyncUpdate(handler, tableName, key, updateFields) + if err != nil { + t.Fatalf("update table failed: %v", err) + } + select { + case <-channel: + return + case <-time.After(timeout): + t.Fatal("timeout") + } +} + +func TestAsyncUpdate0(t *testing.T) { + handler := func(receipt *types.Receipt, err error) { + if err != nil { + t.Fatalf("receive receipt failed, %v\n", err) + } + var bigNum *big.Int + bigNum, err = precompiled.ParseBigIntFromOutput(receipt) + if err != nil { + t.Fatalf("parseReturnValue failed, err: %v\n", err) + } + result, err := precompiled.BigIntToInt64(bigNum) + if err != nil { + t.Fatalf("%v\n", err) + } + if result < 1 { + t.Fatalf("TestAsyncUpdate failed, the result \"%v\" is less then \"1\"", result) + } + t.Logf("result: %d\n", result) + channel <- 0 + } + + insertForTest() + + newValue := randStringBytes(10) + t.Logf("newValue: %v\n", newValue) + updateField := UpdateField{ + ColumnName: columnName, + Value: newValue, + } + var updateFields []UpdateField + updateFields = append(updateFields, updateField) + _, err := service.AsyncUpdate0(handler, tableName, conditions, limit, updateFields) + if err != nil { + t.Fatalf("update table failed: %v", err) + } + select { + case <-channel: + return + case <-time.After(timeout): + t.Fatal("timeout") + } +} + +func TestRemove(t *testing.T) { + key := insertForTest() + + ret0, err := service.Remove(tableName, key) + if err != nil { + t.Fatalf("remove table failed: %v", err) + } + if ret0 != 1 { + t.Fatalf("TestRemove failed, the ret0 \"%v\" is inconsistent with \"1\"", ret0) + } + t.Logf("ret0: %d\n", ret0) +} + +func TestRemove0(t *testing.T) { + insertForTest() + + ret0, err := service.Remove0(tableName, conditions, limit) + if err != nil { + t.Fatalf("remove table failed: %v", err) + } + if ret0 < 1 { + t.Fatalf("TestRemove failed, the ret0 \"%v\" is less then \"1\"", ret0) + } + t.Logf("ret0: %d\n", ret0) +} + +func TestAsyncRemove(t *testing.T) { + handler := func(receipt *types.Receipt, err error) { + if err != nil { + t.Fatalf("receive receipt failed, %v\n", err) + } + var bigNum *big.Int + bigNum, err = precompiled.ParseBigIntFromOutput(receipt) + if err != nil { + t.Fatalf("parseReturnValue failed, err: %v\n", err) + } + result, err := precompiled.BigIntToInt64(bigNum) + if err != nil { + t.Fatalf("%v\n", err) + } + if result != 1 { + t.Fatalf("TestAsyncRemove failed, the result \"%v\" is inconsistent with \"1\"", result) + } + t.Logf("result: %d\n", result) + channel <- 0 + } + + key := insertForTest() + + _, err := service.AsyncRemove(handler, tableName, key) + if err != nil { + t.Fatalf("remove data failed: %v", err) + } + select { + case <-channel: + return + case <-time.After(timeout): + t.Fatal("timeout") + } +} + +func TestAsyncRemove0(t *testing.T) { + handler := func(receipt *types.Receipt, err error) { + if err != nil { + t.Fatalf("receive receipt failed, %v\n", err) + } + var bigNum *big.Int + bigNum, err = precompiled.ParseBigIntFromOutput(receipt) + if err != nil { + t.Fatalf("parseReturnValue failed, err: %v\n", err) + } + result, err := precompiled.BigIntToInt64(bigNum) + if err != nil { + t.Fatalf("%v\n", err) + } + if result < 1 { + t.Fatalf("TestAsyncRemove failed, the result \"%v\" is less then \"1\"", result) + } + t.Logf("result: %d\n", result) + channel <- 0 + } + + insertForTest() + + _, err := service.AsyncRemove0(handler, tableName, conditions, limit) + if err != nil { + t.Fatalf("remove data failed: %v", err) + } + select { + case <-channel: + return + case <-time.After(timeout): + t.Fatal("timeout") + } +} + +func TestSet(t *testing.T) { + _, err := service.OpenKVTable(KVTableName) + if err !=nil{ + service.CreateKVTable(KVTableName, key, columnName) + } + + key := randStringBytes(10) + value := randStringBytes(10) + + ret0, err := service.Set(KVTableName,key,value) + if err != nil { + t.Fatalf("KVTable set failed: %v", err) + } + if ret0 != 1 { + t.Fatalf("TestSet failed, the ret0 \"%v\" is inconsistent with \"1\"", ret0) + } + + _, tempValue, _ := service.Get(KVTableName,key) + if value != tempValue { + t.Fatalf("TestSet failed, the value \"%v\" is inconsistent with the tempValue \"%v\"", value, tempValue) + } + + t.Logf("key: %v\n", key) + t.Logf("value: %v\n", value) +} + +func insertForTest() string { + tempColumnValues := []string{} + tableInfo, _ := service.DescWithKeyOrder(tableName) + for i := 0; i < len(tableInfo.ValueColumns); i++ { + tempColumnValues=append(tempColumnValues,"columnValue") + } + key := randStringBytes(10) + entry := Entry{ + Key: key, + Fields: tempColumnValues, + } + service.Insert(tableName,entry) + return key +} + +func randStringBytes(n int) string { + rand.Seed(time.Now().UnixNano()) + const letterBytes = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" + b := make([]byte, n) + for i := range b { + b[i] = letterBytes[rand.Intn(len(letterBytes))] + } + return string(b) +} \ No newline at end of file diff --git a/precompiled/solidity/auth/Account.sol b/precompiled/solidity/auth/Account.sol new file mode 100644 index 00000000..70912750 --- /dev/null +++ b/precompiled/solidity/auth/Account.sol @@ -0,0 +1,23 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity >=0.6.10 <0.8.20; +pragma experimental ABIEncoderV2; + +enum AccountStatus{ + normal, + freeze, + abolish +} + +abstract contract AccountManager { + // 设置账户状态,只有治理委员可以调用,0 - normal, others - abnormal, 如果账户不存在会先创建 + function setAccountStatus(address addr, AccountStatus status) public virtual returns (int32); + // 任何用户都可以调用 + function getAccountStatus(address addr) public view virtual returns (AccountStatus); +} + +abstract contract Account { + // 设置账户状态,只有AccountManager可以调用, 0 - normal, others - abnormal + function setAccountStatus(AccountStatus status) public virtual returns (int32); + // 任何用户都可以调用 + function getAccountStatus() public view virtual returns (AccountStatus); +} diff --git a/precompiled/solidity/auth/BasicAuth.sol b/precompiled/solidity/auth/BasicAuth.sol new file mode 100644 index 00000000..d1f3bfaa --- /dev/null +++ b/precompiled/solidity/auth/BasicAuth.sol @@ -0,0 +1,29 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity >=0.6.10 <0.8.20; + +contract BasicAuth { + address public _owner; + + constructor() public { + _owner = msg.sender; + } + + modifier onlyOwner() { + require(auth(msg.sender), "Only owner!"); + _; + } + + function setOwner(address owner) public onlyOwner { + _owner = owner; + } + + function auth(address src) public view returns (bool) { + if (src == address(this)) { + return true; + } else if (src == _owner) { + return true; + } else { + return false; + } + } +} \ No newline at end of file diff --git a/precompiled/solidity/auth/Committee.sol b/precompiled/solidity/auth/Committee.sol new file mode 100644 index 00000000..ad678f95 --- /dev/null +++ b/precompiled/solidity/auth/Committee.sol @@ -0,0 +1,113 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity >=0.6.10 <0.8.20; + +import "./LibAddressSet.sol"; +import "./BasicAuth.sol"; + +contract Committee is BasicAuth { + using LibAddressSet for LibAddressSet.AddressSet; + + LibAddressSet.AddressSet private _governorSet; + mapping(address => uint32) private _weightMapping; + uint8 public _participatesRate; + uint8 public _winRate; + + constructor( + address[] memory governorList, + uint32[] memory weightList, + uint8 participatesRate, + uint8 winRate + ) public { + for (uint32 i = 0; i < governorList.length; i++) { + setWeight(governorList[i], weightList[i]); + } + _winRate = winRate; + _participatesRate = participatesRate; + setOwner(msg.sender); + } + + /* + * set rate by owner + * @param participate rate + * @param win rate + */ + function setRate(uint8 participatesRate, uint8 winRate) public onlyOwner { + _winRate = winRate; + _participatesRate = participatesRate; + } + + /* + * set weight only by owner + * @param governor external address + * @param weight + */ + function setWeight(address governor, uint32 weight) public onlyOwner { + if (weight == 0) { + require(governor != tx.origin, "You can not remove yourself!"); + delete _weightMapping[governor]; + _governorSet.remove(governor); + } else if (_governorSet.contains(governor)) { + _weightMapping[governor] = weight; + } else { + _weightMapping[governor] = weight; + _governorSet.add(governor); + } + } + + /* + * get committee info + */ + function getCommitteeInfo() + public + view + returns ( + uint8 participatesRate, + uint8 winRate, + address[] memory governors, + uint32[] memory weights + ) + { + governors = _governorSet.getAll(); + weights = new uint32[](governors.length); + for (uint256 i = 0; i < governors.length; i++) { + weights[i] = _weightMapping[governors[i]]; + } + winRate = _winRate; + participatesRate = _participatesRate; + } + + /* + * predicate governor + * @param governor address + */ + function isGovernor(address governor) public view returns (bool) { + return _governorSet.contains(governor); + } + + /* + * get weight + * @param governor address + */ + function getWeight(address governor) public view returns (uint32) { + return _weightMapping[governor]; + } + + /* + * compute weights with given votes list ++ * @param computed voters list + */ + function getWeights(address[] memory votes) public view returns (uint32) { + uint32 totalVotes = 0; + for (uint32 i = 0; i < votes.length; i++) { + totalVotes += _weightMapping[votes[i]]; + } + return totalVotes; + } + + /* + * compute weights with governor set + */ + function getWeights() public view returns (uint32) { + return getWeights(_governorSet.getAll()); + } +} \ No newline at end of file diff --git a/precompiled/solidity/auth/CommitteeManager.sol b/precompiled/solidity/auth/CommitteeManager.sol new file mode 100644 index 00000000..4ee1e76c --- /dev/null +++ b/precompiled/solidity/auth/CommitteeManager.sol @@ -0,0 +1,471 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity >=0.6.10 <0.8.20; +// pragma experimental ABIEncoderV2; + +import "./Committee.sol"; +import "./ProposalManager.sol"; +import "./ContractAuthPrecompiled.sol"; +import "./ConsensusPrecompiled.sol"; +import "./SystemConfigPrecompiled.sol"; +import "./VoteComputerTemplate.sol"; + +contract CommitteeManager { + // Governors and threshold + Committee public _committee; + // proposal manager + ProposalManager public _proposalMgr; + SystemConfigPrecompiled constant _systemConfigPrecompiled = + SystemConfigPrecompiled(address(0x1000)); + ConsensusPrecompiled constant _consensusPrecompiled = + ConsensusPrecompiled(address(0x1003)); + ContractAuthPrecompiled constant _contractPrecompiled = + ContractAuthPrecompiled(address(0x1005)); + + // exec proposal when vote pass through + // 0 == success, others exec error + event execResult(int256); + + struct ProposalInfo { + // Committee management: 11-set governor weight; 12-set rate; 13-upgrade VoteComputer contract; + // access control: 21-set deploy auth type; 22-modify deploy auth; + // contract admin: 31-reset admin + // system config management: 41- set config + // consensus node management: 51- set weight (weigh > 0, sealer; weight = 0, observer), 52- remove + uint8 proposalType; + // unique address + address resourceId; + // uint8 array + uint8[] uint8Array; + // string array + string[] strArray; + uint32 weight; + // address array + address[] addressArray; + bool flag; + } + // [id, Proposal] + mapping(uint256 => ProposalInfo) private _proposalInfoMap; + + modifier onlyGovernor() { + require(isGovernor(msg.sender), "you must be governor"); + _; + } + + constructor( + address[] memory initGovernors, + uint32[] memory weights, + uint8 participatesRate, + uint8 winRate + ) public { + //_contractPrecompiled = ContractAuthPrecompiled(0x1005); + _committee = new Committee( + initGovernors, + weights, + participatesRate, + winRate + ); + _proposalMgr = new ProposalManager(address(this), address(_committee)); + } + + /* + * apply for update governor + * @param external account + * @param weight, 0-delete, >0-update or insert + * @param blockNumberInterval, after current block number, it will be outdated. + */ + function createUpdateGovernorProposal( + address account, + uint32 weight, + uint256 blockNumberInterval + ) public onlyGovernor returns (uint256 currentproposalId) { + address[] memory addressArray = new address[](1); + uint8[] memory uint8Array; + string[] memory strArray; + addressArray[0] = account; + ProposalInfo memory proposalInfo = ProposalInfo( + 11, + account, + uint8Array, + strArray, + weight, + addressArray, + true + ); + currentproposalId = _createProposal(proposalInfo, blockNumberInterval); + } + + /* + * apply set participate rate and win rate. + * @param participate rate, [0,100]. if 0, always succeed. + * @param win rate, [0,100]. + * @param blockNumberInterval, after current block number, it will be outdated. + */ + function createSetRateProposal( + uint8 participatesRate, + uint8 winRate, + uint256 blockNumberInterval + ) public onlyGovernor returns (uint256 currentproposalId) { + require( + participatesRate >= 0 && participatesRate <= 100, + "invalid range of participatesRate" + ); + require(winRate >= 0 && winRate <= 100, "invalid range of winRate"); + address[] memory addressArray; + uint8[] memory uint8Array = new uint8[](2); + string[] memory strArray; + uint8Array[0] = participatesRate; + uint8Array[1] = winRate; + ProposalInfo memory proposalInfo = ProposalInfo( + 12, + address(this), + uint8Array, + strArray, + 0, + addressArray, + false + ); + currentproposalId = _createProposal(proposalInfo, blockNumberInterval); + } + + /* + * submit an propsal of upgrade VoteCompter.sol + * @param new address of VoteComputer + * @param contractAddr the address of contract which will propose to reset admin + */ + function createUpgradeVoteComputerProposal( + address newAddr, + uint256 blockNumberInterval + ) public onlyGovernor returns (uint256 currentproposalId) { + address[] memory allGovernors; + address[] memory emptyAddress; + (, , allGovernors, ) = _committee.getCommitteeInfo(); + VoteComputerTemplate newVoteComputer = VoteComputerTemplate(newAddr); + require( + newVoteComputer._committee() == _committee, + "new vote computer committee address mismatch" + ); + require( + newVoteComputer.determineVoteResult(allGovernors, emptyAddress) == + 2, + "new vote computer imperfection" + ); + address[] memory addressArray = new address[](1); + uint8[] memory uint8Array; + string[] memory strArray; + addressArray[0] = newAddr; + ProposalInfo memory proposalInfo = ProposalInfo( + 13, + address(_proposalMgr), + uint8Array, + strArray, + 0, + addressArray, + false + ); + currentproposalId = _createProposal(proposalInfo, blockNumberInterval); + } + + /* + * submit an proposal of setting deploy contract auth type + * @param deployAuthType: 1- whitelist; 2-blacklist + */ + function createSetDeployAuthTypeProposal( + uint8 deployAuthType, + uint256 blockNumberInterval + ) public onlyGovernor returns (uint256 currentproposalId) { + require( + _contractPrecompiled.deployType() != deployAuthType, + "the current deploy auth type is the same as you want to set" + ); + + address[] memory addressArray; + uint8[] memory uint8Array = new uint8[](1); + string[] memory strArray; + uint8Array[0] = deployAuthType; + ProposalInfo memory proposalInfo = ProposalInfo( + 21, + address(_contractPrecompiled), + uint8Array, + strArray, + 0, + addressArray, + false + ); + currentproposalId = _createProposal(proposalInfo, blockNumberInterval); + } + + /* + * submit an proposal of adding deploy contract auth for account + * @param account + * @param openFlag: true-open; false-close + */ + function createModifyDeployAuthProposal( + address account, + bool openFlag, + uint256 blockNumberInterval + ) public onlyGovernor returns (uint256 currentproposalId) { + address[] memory addressArray = new address[](1); + addressArray[0] = account; + uint8[] memory uint8Array; + string[] memory strArray; + ProposalInfo memory proposalInfo = ProposalInfo( + 22, + account, + uint8Array, + strArray, + 0, + addressArray, + openFlag + ); + currentproposalId = _createProposal(proposalInfo, blockNumberInterval); + } + + /* + * submit an propsal of resetting contract admin + * @param newAdmin + * @param contractAddr the address of contract which will propose to reset admin + */ + function createResetAdminProposal( + address newAdmin, + address contractAddr, + uint256 blockNumberInterval + ) public onlyGovernor returns (uint256 currentproposalId) { + require(contractAddr != address(0), "contract address not exists."); + // require(methodAuthMgr._owner() == address(this), "caller is not owner"); + require( + newAdmin != _contractPrecompiled.getAdmin(contractAddr), + "the account has been the admin of concurrt contract." + ); + address[] memory addressArray = new address[](1); + uint8[] memory uint8Array; + string[] memory strArray; + addressArray[0] = newAdmin; + ProposalInfo memory proposalInfo = ProposalInfo( + 31, + contractAddr, + uint8Array, + strArray, + 0, + addressArray, + false + ); + currentproposalId = _createProposal(proposalInfo, blockNumberInterval); + } + + /* + * submit a propsal of set system config + * @param key (tx_count_limit,consensus_leader_period,tx_gas_limit) + * @param value + */ + function createSetSysConfigProposal( + string memory key, + string memory value, + uint256 blockNumberInterval + ) public onlyGovernor returns (uint256 currentproposalId) { + require(bytes(key).length > 1, "invalid key length."); + address[] memory addressArray; + uint8[] memory uint8Array; + string[] memory strArray = new string[](2); + strArray[0] = key; + strArray[1] = value; + ProposalInfo memory proposalInfo = ProposalInfo( + 41, + address(_systemConfigPrecompiled), + uint8Array, + strArray, + 0, + addressArray, + false + ); + currentproposalId = _createProposal(proposalInfo, blockNumberInterval); + } + + /* + * submit a proposal of set consensus weight + * @param node + * @param weight: weigh > 0, sealer; weight = 0, observer + * @param addFlag true-> add, false-> set + * @param blockNumberInterval, after current block number, it will be outdated. + */ + function createSetConsensusWeightProposal( + string memory node, + uint32 weight, + bool addFlag, + uint256 blockNumberInterval + ) public onlyGovernor returns (uint256 currentproposalId) { + require(bytes(node).length > 1, "invalid node."); + address[] memory addressArray; + uint8[] memory uint8Array; + string[] memory strArray = new string[](1); + strArray[0] = node; + ProposalInfo memory proposalInfo = ProposalInfo( + 51, + address(_consensusPrecompiled), + uint8Array, + strArray, + weight, + addressArray, + addFlag + ); + currentproposalId = _createProposal(proposalInfo, blockNumberInterval); + } + + /* + * submit a proposal of remove node + * @param node + * @param blockNumberInterval, after current block number, it will be outdated. + */ + function createRmNodeProposal( + string memory node, + uint256 blockNumberInterval + ) public onlyGovernor returns (uint256 currentproposalId) { + require(bytes(node).length > 1, "invalid node."); + address[] memory addressArray; + uint8[] memory uint8Array; + string[] memory strArray = new string[](1); + strArray[0] = node; + ProposalInfo memory proposalInfo = ProposalInfo( + 52, + address(_consensusPrecompiled), + uint8Array, + strArray, + 0, + addressArray, + true + ); + currentproposalId = _createProposal(proposalInfo, blockNumberInterval); + } + + /* + * create proposal + * @param create address + * @param proposal type : 1X-committee;2X-deploy contract auth;3X-admin auth + * @param resource id + * @param after the block number interval, the proposal would be outdated. + */ + function _createProposal( + ProposalInfo memory proposalInfo, + uint256 blockNumberInterval + ) internal returns (uint256) { + uint256 proposalId = _proposalMgr.create( + msg.sender, + proposalInfo.proposalType, + proposalInfo.resourceId, + blockNumberInterval + ); + _proposalInfoMap[proposalId] = proposalInfo; + //detault vote agree for the proposal. + voteProposal(proposalId, true); + return proposalId; + } + + /* + * revoke proposal + * @param proposal id + */ + function revokeProposal(uint256 proposalId) public onlyGovernor { + _proposalMgr.revoke(proposalId, msg.sender); + } + + /* + * unified vote + * @param proposal id + * @param true or false + * @event error code, + 0 == exec success, others exec error + */ + function voteProposal(uint256 proposalId, bool agree) public onlyGovernor { + uint8 voteStatus = _proposalMgr.vote(proposalId, agree, msg.sender); + ProposalInfo memory proposalInfo; + if (voteStatus == 2) { + int256 retCode = 0; + uint8 proposalType = getProposalType(proposalId); + proposalInfo = _proposalInfoMap[proposalId]; + if (proposalType == 11) { + if (proposalInfo.weight == 0) { + require( + proposalInfo.addressArray[0] != msg.sender, + "You can not remove yourself!" + ); + } + _committee.setWeight( + proposalInfo.addressArray[0], + proposalInfo.weight + ); + } else if (proposalType == 12) { + _committee.setRate( + proposalInfo.uint8Array[0], + proposalInfo.uint8Array[1] + ); + } else if (proposalType == 13) { + _proposalMgr.setVoteComputer(proposalInfo.addressArray[0]); + } else if (proposalType == 21) { + retCode = _contractPrecompiled.setDeployAuthType( + proposalInfo.uint8Array[0] + ); + } else if (proposalType == 22) { + if (proposalInfo.flag) { + retCode = _contractPrecompiled.openDeployAuth( + proposalInfo.addressArray[0] + ); + } else { + retCode = _contractPrecompiled.closeDeployAuth( + proposalInfo.addressArray[0] + ); + } + } else if (proposalType == 31) { + // (contractAddress, adminAddress) + retCode = _contractPrecompiled.resetAdmin( + proposalInfo.resourceId, + proposalInfo.addressArray[0] + ); + } else if (proposalType == 41) { + retCode = _systemConfigPrecompiled.setValueByKey( + proposalInfo.strArray[0], + proposalInfo.strArray[1] + ); + } else if (proposalType == 51) { + if (proposalInfo.flag) { + if (proposalInfo.weight == 0) { + retCode = _consensusPrecompiled.addObserver( + proposalInfo.strArray[0] + ); + } else { + retCode = _consensusPrecompiled.addSealer( + proposalInfo.strArray[0], + uint256(proposalInfo.weight) + ); + } + } else { + retCode = _consensusPrecompiled.setWeight( + proposalInfo.strArray[0], + uint256(proposalInfo.weight) + ); + } + } else if (proposalType == 52) { + retCode = _consensusPrecompiled.remove( + proposalInfo.strArray[0] + ); + } else { + revert("vote type error."); + } + emit execResult(retCode); + } + } + + /* + * predicate governor + * @param external account + */ + function isGovernor(address account) public view returns (bool) { + return _committee.isGovernor(account); + } + + /* + * get proposal type + * @param proposal id + */ + function getProposalType(uint256 proposalId) public view returns (uint8) { + return _proposalInfoMap[proposalId].proposalType; + } +} \ No newline at end of file diff --git a/precompiled/solidity/auth/ConsensusPrecompiled.sol b/precompiled/solidity/auth/ConsensusPrecompiled.sol new file mode 100644 index 00000000..54c209e1 --- /dev/null +++ b/precompiled/solidity/auth/ConsensusPrecompiled.sol @@ -0,0 +1,12 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity >=0.6.10 <0.8.20; + +contract ConsensusPrecompiled { + function addSealer(string memory, uint256) public returns (int256) {} + + function addObserver(string memory) public returns (int256) {} + + function remove(string memory) public returns (int256) {} + + function setWeight(string memory, uint256) public returns (int256) {} +} \ No newline at end of file diff --git a/precompiled/solidity/auth/ContractAuthPrecompiled.sol b/precompiled/solidity/auth/ContractAuthPrecompiled.sol new file mode 100644 index 00000000..31c35176 --- /dev/null +++ b/precompiled/solidity/auth/ContractAuthPrecompiled.sol @@ -0,0 +1,28 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity >=0.6.10 <0.8.20; + +enum Status{ + normal, + freeze, + abolish +} + +abstract contract ContractAuthPrecompiled { + function getAdmin(address contractAddr) public view virtual returns (address); + function resetAdmin(address contractAddr, address admin) public virtual returns (int256); + function setMethodAuthType(address contractAddr, bytes4 func, uint8 authType) public virtual returns (int256); + function openMethodAuth(address contractAddr, bytes4 func, address account) public virtual returns (int256); + function closeMethodAuth(address contractAddr, bytes4 func, address account) public virtual returns (int256); + function checkMethodAuth(address contractAddr, bytes4 func, address account) public view virtual returns (bool); + function getMethodAuth(address contractAddr, bytes4 func) public view virtual returns (uint8,string[] memory,string[] memory); + function setContractStatus(address _address, bool isFreeze) public virtual returns(int); + function setContractStatus(address _address, Status _status) public virtual returns(int); + function contractAvailable(address _address) public view virtual returns (bool); + + function deployType() public view virtual returns (uint256); + function setDeployAuthType(uint8 _type) public virtual returns (int256); + function openDeployAuth(address account) public virtual returns (int256); + function closeDeployAuth(address account) public virtual returns (int256); + function hasDeployAuth(address account) public view virtual returns (bool); + function initAuth(string memory account) public virtual returns(int256); +} \ No newline at end of file diff --git a/precompiled/solidity/auth/ProposalManager.sol b/precompiled/solidity/auth/ProposalManager.sol new file mode 100644 index 00000000..efb1b980 --- /dev/null +++ b/precompiled/solidity/auth/ProposalManager.sol @@ -0,0 +1,267 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity >=0.6.10 <0.8.20; +pragma experimental ABIEncoderV2; + +import "./BasicAuth.sol"; +import "./VoteComputer.sol"; + +contract ProposalManager is BasicAuth { + struct ProposalInfo { + // unique address + address resourceId; + // creator external address + address proposer; + // proposal type: 1X-committee;2X-deploy contract auth;3X-admin auth + uint8 proposalType; + // block number interval + uint256 blockNumberInterval; + //0-not exist 1-created 2-passed 3-denied 4-revoked 5-outdated + uint8 status; + // approve voters list + address[] agreeVoters; + // against voters List + address[] againstVoters; + } + // Committee handler + VoteComputerTemplate public _voteComputer; + // auto generated proposal id + uint256 public _proposalCount; + // (id, proposal) + mapping(uint256 => ProposalInfo) public _proposals; + // (type, (resource id, proposal id)) + mapping(uint8 => mapping(address => uint256)) public _proposalIndex; + + modifier proposalExist(uint256 proposalId) { + require(_proposals[proposalId].status != 0, "Proposal not exist"); + _; + } + + modifier proposalVotable(uint256 proposalId) { + require(_proposals[proposalId].status == 1, "Proposal is not votable"); + _; + } + + constructor(address committeeMgrAddress, address committeeAddress) public { + _voteComputer = new VoteComputer(committeeMgrAddress, committeeAddress); + } + + function setVoteComputer(address addr) public onlyOwner { + _voteComputer = VoteComputerTemplate(addr); + } + + /* + * predicate proposal outdated + * @param proposal id + */ + function refreshProposalStatus(uint256 proposalId) + public + proposalExist(proposalId) + returns (uint8) + { + ProposalInfo storage proposal = _proposals[proposalId]; + if (proposal.status == 1) { + if (block.number > proposal.blockNumberInterval) { + proposal.status = 5; + return 5; + } + } + return proposal.status; + } + + /* + * create proposal + * @param create address + * @param proposal type : 1X-committee;2X-deploy contract auth;3X-admin auth + * @param resource id + * @param after the block number interval, the proposal would be outdated. + */ + function create( + address proposer, + uint8 proposalType, + address resourceId, + uint256 blockNumberInterval + ) public onlyOwner returns (uint256) { + uint256 alreadExistProposalId = _proposalIndex[proposalType][ + resourceId + ]; + if (_proposals[alreadExistProposalId].status == 1) { + refreshProposalStatus(alreadExistProposalId); + } + require( + _proposals[alreadExistProposalId].status != 1, + "Current proposal not end" + ); + _proposalCount++; + uint256 proposalId = _proposalCount; + address[] memory agreeVoters; + address[] memory againstVoters; + ProposalInfo memory proposal = ProposalInfo( + resourceId, + proposer, + proposalType, + block.number + blockNumberInterval, + 1, + agreeVoters, + againstVoters + ); + + _proposals[proposalId] = proposal; + _proposalIndex[proposalType][resourceId] = proposalId; + return proposalId; + } + + /* + * unified vote + * @param proposal id + * @param true or false + * @param voter address + */ + function vote( + uint256 proposalId, + bool agree, + address voterAddress + ) + public + onlyOwner + proposalExist(proposalId) + proposalVotable(proposalId) + returns (uint8) + { + ProposalInfo storage proposal = _proposals[proposalId]; + require(!hasVoted(proposal, voterAddress), "Already voted"); + if (agree) { + proposal.agreeVoters.push(voterAddress); + } else { + proposal.againstVoters.push(voterAddress); + } + uint8 status = _voteComputer.determineVoteResult( + proposal.agreeVoters, + proposal.againstVoters + ); + proposal.status = status; + return status; + } + + /* + * revoke proposal + * @param proposal id + * @param voter address + */ + function revoke(uint256 proposalId, address voterAddress) public onlyOwner { + ProposalInfo storage proposal = _proposals[proposalId]; + require( + refreshProposalStatus(proposalId) == 1, + "Only newly created proposal can be revoked" + ); + require(proposal.proposer == voterAddress, "Only proposer can revoke"); + proposal.status = 4; + } + + /* + * get proposal info + * @param proposal id + */ + function getProposalInfo(uint256 proposalId) + public + view + returns ( + address resourceId, + address proposer, + uint8 proposalType, + uint256 blockNumberInterval, + uint8 status, + address[] memory agreeVoters, + address[] memory againstVoters + ) + { + ProposalInfo storage proposal = _proposals[proposalId]; + resourceId = proposal.resourceId; + proposer = proposal.proposer; + proposalType = proposal.proposalType; + blockNumberInterval = proposal.blockNumberInterval; + status = proposal.status; + agreeVoters = proposal.agreeVoters; + againstVoters = proposal.againstVoters; + } + + /* + * get proposalInfo list, range in [from, to] + */ + function getProposalInfoList(uint256 from, uint256 to) + public + view + returns (ProposalInfo[] memory) + { + require( + from <= _proposalCount, + "'from' is greater than 'proposalCount'" + ); + require(from <= to, "'from' is greater than 'to'"); + if (to > _proposalCount) { + to = _proposalCount; + } + if (from < 1) { + from = 1; + } + ProposalInfo[] memory _infoList = new ProposalInfo[](to - from + 1); + uint256 _infoListIndex = 0; + for (uint256 i = from; i <= to; i++) { + ProposalInfo storage proposal = _proposals[i]; + _infoList[_infoListIndex++] = proposal; + } + return _infoList; + } + + /* + * get proposal status by proposal id + * @param proposal id + */ + function getProposalStatus(uint256 proposalId) public view returns (uint8) { + return _proposals[proposalId].status; + } + + /* + * get info by proposal type and resource id + * @param create address + * @param proposal type : 1X-committee;2X-deploy contract auth;3X-admin auth + * @param resource id + * @param after the block number interval, the proposal would be outdated. + */ + function getIdByTypeAndResourceId(uint8 proposalType, address resourceId) + public + view + returns (uint256) + { + return _proposalIndex[proposalType][resourceId]; + } + + /** + * judge account if voted for the proposal + */ + function hasVoted(ProposalInfo memory proposal, address account) + internal + pure + returns (bool) + { + if ( + contains(proposal.agreeVoters, account) || + contains(proposal.againstVoters, account) + ) { + return true; + } + return false; + } + + function contains(address[] memory array, address value) + internal + pure + returns (bool) + { + for (uint256 i = 0; i < array.length; i++) { + if (value == array[i]) { + return true; + } + } + return false; + } +} \ No newline at end of file diff --git a/precompiled/solidity/auth/README.md b/precompiled/solidity/auth/README.md new file mode 100644 index 00000000..04df3fe2 --- /dev/null +++ b/precompiled/solidity/auth/README.md @@ -0,0 +1 @@ +# [合约仓库](https://github.com/FISCO-BCOS/bcos-auth) diff --git a/precompiled/solidity/auth/SystemConfigPrecompiled.sol b/precompiled/solidity/auth/SystemConfigPrecompiled.sol new file mode 100644 index 00000000..e37a7178 --- /dev/null +++ b/precompiled/solidity/auth/SystemConfigPrecompiled.sol @@ -0,0 +1,15 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity >=0.6.10 <0.8.20; + +contract SystemConfigPrecompiled { + function setValueByKey(string memory key, string memory value) + public + returns (int256) + {} + + function getValueByKey(string memory key) + public + view + returns (string memory, int256) + {} +} \ No newline at end of file diff --git a/precompiled/solidity/auth/VoteComputerTemplate.sol b/precompiled/solidity/auth/VoteComputerTemplate.sol new file mode 100644 index 00000000..003974ba --- /dev/null +++ b/precompiled/solidity/auth/VoteComputerTemplate.sol @@ -0,0 +1,47 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity >=0.6.10 <0.8.20; + +import "./Committee.sol"; +import "./BasicAuth.sol"; + +abstract contract VoteComputerTemplate is BasicAuth { + // Governors and threshold + Committee public _committee; + + constructor(address committeeMgrAddress, address committeeAddress) { + setOwner(committeeMgrAddress); + _committee = Committee(committeeAddress); + // first, test committee exist; second, test committee is helthy + require( + _committee.getWeights() >= 1, + "committee is error, please check address!" + ); + } + + /* + * predicate vote result and return the status + * @param for voters list + * @param against voters list + */ + function determineVoteResult( + address[] memory agreeVoters, + address[] memory againstVoters + ) public view virtual returns (uint8); + + /* + * calculate vote result and return the status, + * this method only for committee check calculate logic + * @param agree voter total weight + * @param voted voter total weight + * @param all voter total weight + * @param participate threshold, percentage + * @param win threshold, percentage + */ + function voteResultCalc( + uint32 agreeVotes, + uint32 doneVotes, + uint32 allVotes, + uint8 participatesRate, + uint8 winRate + ) public pure virtual returns (uint8); +} \ No newline at end of file diff --git a/precompiled/solidity/bfs/BfsPrecompiled.sol b/precompiled/solidity/bfs/BfsPrecompiled.sol new file mode 100644 index 00000000..5edaac43 --- /dev/null +++ b/precompiled/solidity/bfs/BfsPrecompiled.sol @@ -0,0 +1,28 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity >=0.6.10 <0.8.20; +pragma experimental ABIEncoderV2; + + struct BfsInfo { + string file_name; + string file_type; + string[] ext; + } + +abstract contract BfsPrecompiled { + // @return return BfsInfo at most 500, if you want more, try list with paging interface + function list(string memory absolutePath) virtual public view returns (int32, BfsInfo[] memory); + // @return int, >=0 -> BfsInfo left, <0 -> errorCode + function list(string memory absolutePath, uint offset, uint limit) virtual public view returns (int, BfsInfo[] memory); + + function mkdir(string memory absolutePath) virtual public returns (int32); + + function link(string memory absolutePath, string memory _address, string memory _abi) virtual public returns (int); + // for cns compatibility + function link(string memory name, string memory version, string memory _address, string memory _abi) virtual public returns (int32); + + function readlink(string memory absolutePath) virtual public view returns (address); + + function touch(string memory absolutePath, string memory fileType) virtual public returns (int32); + + function rebuildBfs() virtual public returns (int); +} \ No newline at end of file diff --git a/precompiled/cns/CNS.sol b/precompiled/solidity/cns/CNS.sol similarity index 100% rename from precompiled/cns/CNS.sol rename to precompiled/solidity/cns/CNS.sol diff --git a/precompiled/config/SystemConfig.sol b/precompiled/solidity/config/SystemConfig.sol similarity index 100% rename from precompiled/config/SystemConfig.sol rename to precompiled/solidity/config/SystemConfig.sol diff --git a/precompiled/consensus/Consensus.sol b/precompiled/solidity/consensus/Consensus.sol similarity index 90% rename from precompiled/consensus/Consensus.sol rename to precompiled/solidity/consensus/Consensus.sol index a01b9d93..db90a6ce 100644 --- a/precompiled/consensus/Consensus.sol +++ b/precompiled/solidity/consensus/Consensus.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: Apache-2.0 -pragma solidity ^0.6.0; +pragma solidity >=0.6.10 <0.8.20; contract ConsensusPrecompiled { function addSealer(string memory,uint256) public returns (int32){} diff --git a/precompiled/solidity/crud/Cast.sol b/precompiled/solidity/crud/Cast.sol new file mode 100644 index 00000000..892ef20e --- /dev/null +++ b/precompiled/solidity/crud/Cast.sol @@ -0,0 +1,17 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity >=0.6.10 <0.8.20; +pragma experimental ABIEncoderV2; + +abstract contract Cast { + function stringToS256(string memory) public virtual view returns (int256); + function stringToS64(string memory) public virtual view returns (int64); + function stringToU256(string memory) public virtual view returns (uint256); + function stringToAddr(string memory) public virtual view returns (address); + function stringToBytes32(string memory) public virtual view returns (bytes32); + + function s256ToString(int256) public virtual view returns (string memory); + function s64ToString(int64) public virtual view returns (string memory); + function u256ToString(uint256) public virtual view returns (string memory); + function addrToString(address) public virtual view returns (string memory); + function bytes32ToString(bytes32) public virtual view returns (string memory); +} \ No newline at end of file diff --git a/precompiled/solidity/crud/EntryWrapper.sol b/precompiled/solidity/crud/EntryWrapper.sol new file mode 100644 index 00000000..19fac251 --- /dev/null +++ b/precompiled/solidity/crud/EntryWrapper.sol @@ -0,0 +1,101 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity >=0.6.10 <0.8.20; +pragma experimental ABIEncoderV2; +import "./Cast.sol"; + +// 记录,用于select和insert +struct Entry { + string key; + string[] fields; // 考虑2.0的Entry接口,临时Precompiled的问题,考虑加工具类接口 +} + +contract EntryWrapper { + Cast constant cast = Cast(address(0x100f)); + Entry entry; + constructor(Entry memory _entry) public { + entry = _entry; + } + function setEntry(Entry memory _entry) public { + entry = _entry; + } + function getEntry() public view returns(Entry memory) { + return entry; + } + function fieldSize() public view returns (uint256) { + return entry.fields.length; + } + function getInt(uint256 idx) public view returns (int256) { + require(idx >= 0 && idx < fieldSize(), "Index out of range!"); + return cast.stringToS256(entry.fields[idx]); + } + function getUInt(uint256 idx) public view returns (uint256) { + require(idx >= 0 && idx < fieldSize(), "Index out of range!"); + return cast.stringToU256(entry.fields[idx]); + } + function getAddress(uint256 idx) public view returns (address) { + require(idx >= 0 && idx < fieldSize(), "Index out of range!"); + return cast.stringToAddr(entry.fields[idx]); + } + function getBytes64(uint256 idx) public view returns (bytes1[64] memory) { + require(idx >= 0 && idx < fieldSize(), "Index out of range!"); + return bytesToBytes64(bytes(entry.fields[idx])); + } + function getBytes32(uint256 idx) public view returns (bytes32) { + require(idx >= 0 && idx < fieldSize(), "Index out of range!"); + return cast.stringToBytes32(entry.fields[idx]); + } + function getString(uint256 idx) public view returns (string memory) { + require(idx >= 0 && idx < fieldSize(), "Index out of range!"); + return entry.fields[idx]; + } + function set(uint256 idx, int256 value) public returns(int32) { + require(idx >= 0 && idx < fieldSize(), "Index out of range!"); + entry.fields[idx] = cast.s256ToString(value); + return 0; + } + function set(uint256 idx, uint256 value) public returns(int32) { + require(idx >= 0 && idx < fieldSize(), "Index out of range!"); + entry.fields[idx] = cast.u256ToString(value); + return 0; + } + function set(uint256 idx, string memory value) public returns(int32) { + require(idx >= 0 && idx < fieldSize(), "Index out of range!"); + entry.fields[idx] = value; + return 0; + } + function set(uint256 idx, address value) public returns(int32) { + require(idx >= 0 && idx < fieldSize(), "Index out of range!"); + entry.fields[idx] = cast.addrToString(value); + return 0; + } + function set(uint256 idx, bytes32 value) public returns(int32) { + require(idx >= 0 && idx < fieldSize(), "Index out of range!"); + entry.fields[idx] = cast.bytes32ToString(value); + return 0; + } + function set(uint256 idx, bytes1[64] memory value) public returns(int32) { + require(idx >= 0 && idx < fieldSize(), "Index out of range!"); + entry.fields[idx] = string(bytes64ToBytes(value)); + return 0; + } + function setKey(string memory value) public { + entry.key = value; + } + function getKey() public view returns (string memory) { + return entry.key; + } + function bytes64ToBytes(bytes1[64] memory src) private pure returns(bytes memory) { + bytes memory dst = new bytes(64); + for(uint32 i = 0; i < 64; i++) { + dst[i] = src[i][0]; + } + return dst; + } + function bytesToBytes64(bytes memory src) private pure returns(bytes1[64] memory) { + bytes1[64] memory dst; + for(uint32 i = 0; i < 64; i++) { + dst[i] = src[i]; + } + return dst; + } +} diff --git a/precompiled/solidity/crud/Table.sol b/precompiled/solidity/crud/Table.sol new file mode 100644 index 00000000..1a8c6c9f --- /dev/null +++ b/precompiled/solidity/crud/Table.sol @@ -0,0 +1,85 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity >=0.6.10 <0.8.20; +pragma experimental ABIEncoderV2; +import "./EntryWrapper.sol"; + +// KeyOrder指定Key的排序规则,字典序和数字序,如果指定为数字序,key只能为数字 +enum KeyOrder {Lexicographic, Numerical} +struct TableInfo { + KeyOrder keyOrder; + string keyColumn; + string[] valueColumns; +} + +// 更新字段,用于update +struct UpdateField { + string columnName; + // 考虑工具类 + string value; +} + +// 筛选条件,大于、大于等于、小于、小于等于 +enum ConditionOP {GT, GE, LT, LE, EQ, NE, STARTS_WITH, ENDS_WITH, CONTAINS} +struct Condition { + ConditionOP op; + string field; + string value; +} + +// 数量限制 +struct Limit { + uint32 offset; + // count limit max is 500 + uint32 count; +} + +// 表管理合约,是静态Precompiled,有固定的合约地址 +abstract contract TableManager { + // 创建表,传入TableInfo + function createTable(string memory path, TableInfo memory tableInfo) public virtual returns (int32); + + // 创建KV表,传入key和value字段名 + function createKVTable(string memory tableName, string memory keyField, string memory valueField) public virtual returns (int32); + + // 只提供给Solidity合约调用时使用 + function openTable(string memory path) public view virtual returns (address); + + // 变更表字段 + // 只能新增字段,不能删除字段,新增的字段默认值为空,不能与原有字段重复 + function appendColumns(string memory path, string[] memory newColumns) public virtual returns (int32); + + // 获取表信息 + function descWithKeyOrder(string memory tableName) public view virtual returns (TableInfo memory); +} + +// 表合约,是动态Precompiled,TableManager创建时指定地址 +abstract contract Table { + // 按key查询entry + function select(string memory key) public virtual view returns (Entry memory); + + // 按条件批量查询entry,condition为空则查询所有记录 + function select(Condition[] memory conditions, Limit memory limit) public virtual view returns (Entry[] memory); + + // 按照条件查询count数据 + function count(Condition[] memory conditions) public virtual view returns (uint32); + + // 插入数据 + function insert(Entry memory entry) public virtual returns (int32); + + // 按key更新entry + function update(string memory key, UpdateField[] memory updateFields) public virtual returns (int32); + + // 按条件批量更新entry,condition为空则更新所有记录 + function update(Condition[] memory conditions, Limit memory limit, UpdateField[] memory updateFields) public virtual returns (int32); + + // 按key删除entry + function remove(string memory key) public virtual returns (int32); + // 按条件批量删除entry,condition为空则删除所有记录 + function remove(Condition[] memory conditions, Limit memory limit) public virtual returns (int32); +} + +abstract contract KVTable { + function get(string memory key) public view virtual returns (bool, string memory); + + function set(string memory key, string memory value) public virtual returns (int32); +} \ No newline at end of file diff --git a/precompiled/solidity/sharding/ShardingPrecompiled.sol b/precompiled/solidity/sharding/ShardingPrecompiled.sol new file mode 100644 index 00000000..3c4edec5 --- /dev/null +++ b/precompiled/solidity/sharding/ShardingPrecompiled.sol @@ -0,0 +1,9 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity ^0.8.0; +pragma experimental ABIEncoderV2; + +contract ShardingPrecompiled{ + function getContractShard(string memory absolutePath) public view returns (int256,string memory) {} + function makeShard(string memory shardName) public returns (int256) {} + function linkShard(string memory shardName, string memory _address) public returns (int256) {} +} \ No newline at end of file