From d7ce51d555a73a76ccde135cdb43a0ca969692b3 Mon Sep 17 00:00:00 2001 From: wenlinli <1574249665@qq.com> Date: Thu, 26 Sep 2024 12:30:27 +0800 Subject: [PATCH] add balance interface and ut --- .ci/integration_test.sh | 2 +- v3/precompiled/balance/balance.go | 450 ++++++++++++++++++ v3/precompiled/balance/balance_service.go | 60 +++ .../balance/balance_service_test.go | 133 ++++++ .../solidity/balance/BalancePrecompiled.sol | 18 + 5 files changed, 662 insertions(+), 1 deletion(-) create mode 100644 v3/precompiled/balance/balance.go create mode 100644 v3/precompiled/balance/balance_service.go create mode 100644 v3/precompiled/balance/balance_service_test.go create mode 100644 v3/precompiled/solidity/balance/BalancePrecompiled.sol diff --git a/.ci/integration_test.sh b/.ci/integration_test.sh index cd2895ad..bfc7bdc3 100755 --- a/.ci/integration_test.sh +++ b/.ci/integration_test.sh @@ -328,7 +328,7 @@ precompiled_test(){ # TODO: consensus test use getSealer first # TODO: cns # TODO: permission - precompileds=(config crud auth config) + precompileds=(config crud auth config balance) sleep 10 for pkg in ${precompileds[*]}; do cp -R nodes/127.0.0.1/sdk/* "./precompiled/${pkg}" diff --git a/v3/precompiled/balance/balance.go b/v3/precompiled/balance/balance.go new file mode 100644 index 00000000..f3af5020 --- /dev/null +++ b/v3/precompiled/balance/balance.go @@ -0,0 +1,450 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package balanceprecompiled + +import ( + "fmt" + "math/big" + "strings" + + "github.com/FISCO-BCOS/go-sdk/v3/abi" + "github.com/FISCO-BCOS/go-sdk/v3/abi/bind" + "github.com/FISCO-BCOS/go-sdk/v3/types" + "github.com/ethereum/go-ethereum/common" +) + +// Reference imports to suppress errors if they are not otherwise used. +var ( + _ = big.NewInt + _ = strings.NewReader + _ = abi.U256 + _ = bind.Bind + _ = common.Big1 +) + +// BalancePrecompiledABI is the input ABI used to generate the binding from. +const BalancePrecompiledABI = "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"addBalance\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"getBalance\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"listCaller\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"registerCaller\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"subBalance\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"transfer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"unregisterCaller\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]" + +// BalancePrecompiledBin is the compiled bytecode used for deploying new contracts. +var BalancePrecompiledBin = "0x608060405234801561001057600080fd5b50610414806100206000396000f3fe608060405234801561001057600080fd5b506004361061007d5760003560e01c8063afb4bfbd1161005b578063afb4bfbd146100d8578063beabacc8146100f4578063cf8eeb7e14610110578063f8b2cb4f1461012c5761007d565b806321e5383a146100825780633b9a32de1461009e578063511ab10c146100ba575b600080fd5b61009c60048036038101906100979190610214565b61015c565b005b6100b860048036038101906100b39190610254565b610160565b005b6100c2610163565b6040516100cf919061033f565b60405180910390f35b6100f260048036038101906100ed9190610254565b610168565b005b61010e60048036038101906101099190610361565b61016b565b005b61012a60048036038101906101259190610214565b610170565b005b61014660048036038101906101419190610254565b610174565b60405161015391906103c3565b60405180910390f35b5050565b50565b606090565b50565b505050565b5050565b6000919050565b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006101ab82610180565b9050919050565b6101bb816101a0565b81146101c657600080fd5b50565b6000813590506101d8816101b2565b92915050565b6000819050919050565b6101f1816101de565b81146101fc57600080fd5b50565b60008135905061020e816101e8565b92915050565b6000806040838503121561022b5761022a61017b565b5b6000610239858286016101c9565b925050602061024a858286016101ff565b9150509250929050565b60006020828403121561026a5761026961017b565b5b6000610278848285016101c9565b91505092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b6102b6816101a0565b82525050565b60006102c883836102ad565b60208301905092915050565b6000602082019050919050565b60006102ec82610281565b6102f6818561028c565b93506103018361029d565b8060005b8381101561033257815161031988826102bc565b9750610324836102d4565b925050600181019050610305565b5085935050505092915050565b6000602082019050818103600083015261035981846102e1565b905092915050565b60008060006060848603121561037a5761037961017b565b5b6000610388868287016101c9565b9350506020610399868287016101c9565b92505060406103aa868287016101ff565b9150509250925092565b6103bd816101de565b82525050565b60006020820190506103d860008301846103b4565b9291505056fea2646970667358221220f4f1f0e50be54ee5394905a711259b7039cdf627b4521c2148afb1e185ed7c2a64736f6c634300080b0033" +var BalancePrecompiledSMBin = "0x" + +// DeployBalancePrecompiled deploys a new contract, binding an instance of BalancePrecompiled to it. +func DeployBalancePrecompiled(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Receipt, *BalancePrecompiled, error) { + parsed, err := abi.JSON(strings.NewReader(BalancePrecompiledABI)) + if err != nil { + return common.Address{}, nil, nil, err + } + + var bytecode []byte + if backend.SMCrypto() { + bytecode = common.FromHex(BalancePrecompiledSMBin) + } else { + bytecode = common.FromHex(BalancePrecompiledBin) + } + if len(bytecode) == 0 { + return common.Address{}, nil, nil, fmt.Errorf("cannot deploy empty bytecode") + } + address, receipt, contract, err := bind.DeployContract(auth, parsed, bytecode, BalancePrecompiledABI, backend) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, receipt, &BalancePrecompiled{BalancePrecompiledCaller: BalancePrecompiledCaller{contract: contract}, BalancePrecompiledTransactor: BalancePrecompiledTransactor{contract: contract}, BalancePrecompiledFilterer: BalancePrecompiledFilterer{contract: contract}}, nil +} + +func AsyncDeployBalancePrecompiled(auth *bind.TransactOpts, handler func(*types.Receipt, error), backend bind.ContractBackend) (*types.Transaction, error) { + parsed, err := abi.JSON(strings.NewReader(BalancePrecompiledABI)) + if err != nil { + return nil, err + } + + var bytecode []byte + if backend.SMCrypto() { + bytecode = common.FromHex(BalancePrecompiledSMBin) + } else { + bytecode = common.FromHex(BalancePrecompiledBin) + } + if len(bytecode) == 0 { + return nil, fmt.Errorf("cannot deploy empty bytecode") + } + tx, err := bind.AsyncDeployContract(auth, handler, parsed, bytecode, BalancePrecompiledABI, backend) + if err != nil { + return nil, err + } + return tx, nil +} + +// BalancePrecompiled is an auto generated Go binding around a Solidity contract. +type BalancePrecompiled struct { + BalancePrecompiledCaller // Read-only binding to the contract + BalancePrecompiledTransactor // Write-only binding to the contract + BalancePrecompiledFilterer // Log filterer for contract events +} + +// BalancePrecompiledCaller is an auto generated read-only Go binding around a Solidity contract. +type BalancePrecompiledCaller struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// BalancePrecompiledTransactor is an auto generated write-only Go binding around a Solidity contract. +type BalancePrecompiledTransactor struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// BalancePrecompiledFilterer is an auto generated log filtering Go binding around a Solidity contract events. +type BalancePrecompiledFilterer struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// BalancePrecompiledSession is an auto generated Go binding around a Solidity contract, +// with pre-set call and transact options. +type BalancePrecompiledSession struct { + Contract *BalancePrecompiled // 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 +} + +// BalancePrecompiledCallerSession is an auto generated read-only Go binding around a Solidity contract, +// with pre-set call options. +type BalancePrecompiledCallerSession struct { + Contract *BalancePrecompiledCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session +} + +// BalancePrecompiledTransactorSession is an auto generated write-only Go binding around a Solidity contract, +// with pre-set transact options. +type BalancePrecompiledTransactorSession struct { + Contract *BalancePrecompiledTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// BalancePrecompiledRaw is an auto generated low-level Go binding around a Solidity contract. +type BalancePrecompiledRaw struct { + Contract *BalancePrecompiled // Generic contract binding to access the raw methods on +} + +// BalancePrecompiledCallerRaw is an auto generated low-level read-only Go binding around a Solidity contract. +type BalancePrecompiledCallerRaw struct { + Contract *BalancePrecompiledCaller // Generic read-only contract binding to access the raw methods on +} + +// BalancePrecompiledTransactorRaw is an auto generated low-level write-only Go binding around a Solidity contract. +type BalancePrecompiledTransactorRaw struct { + Contract *BalancePrecompiledTransactor // Generic write-only contract binding to access the raw methods on +} + +// NewBalancePrecompiled creates a new instance of BalancePrecompiled, bound to a specific deployed contract. +func NewBalancePrecompiled(address common.Address, backend bind.ContractBackend) (*BalancePrecompiled, error) { + contract, err := bindBalancePrecompiled(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &BalancePrecompiled{BalancePrecompiledCaller: BalancePrecompiledCaller{contract: contract}, BalancePrecompiledTransactor: BalancePrecompiledTransactor{contract: contract}, BalancePrecompiledFilterer: BalancePrecompiledFilterer{contract: contract}}, nil +} + +// NewBalancePrecompiledCaller creates a new read-only instance of BalancePrecompiled, bound to a specific deployed contract. +func NewBalancePrecompiledCaller(address common.Address, caller bind.ContractCaller) (*BalancePrecompiledCaller, error) { + contract, err := bindBalancePrecompiled(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &BalancePrecompiledCaller{contract: contract}, nil +} + +// NewBalancePrecompiledTransactor creates a new write-only instance of BalancePrecompiled, bound to a specific deployed contract. +func NewBalancePrecompiledTransactor(address common.Address, transactor bind.ContractTransactor) (*BalancePrecompiledTransactor, error) { + contract, err := bindBalancePrecompiled(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &BalancePrecompiledTransactor{contract: contract}, nil +} + +// NewBalancePrecompiledFilterer creates a new log filterer instance of BalancePrecompiled, bound to a specific deployed contract. +func NewBalancePrecompiledFilterer(address common.Address, filterer bind.ContractFilterer) (*BalancePrecompiledFilterer, error) { + contract, err := bindBalancePrecompiled(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &BalancePrecompiledFilterer{contract: contract}, nil +} + +// bindBalancePrecompiled binds a generic wrapper to an already deployed contract. +func bindBalancePrecompiled(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := abi.JSON(strings.NewReader(BalancePrecompiledABI)) + 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 (_BalancePrecompiled *BalancePrecompiledRaw) Call(opts *bind.CallOpts, result interface{}, method string, params ...interface{}) error { + return _BalancePrecompiled.Contract.BalancePrecompiledCaller.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 (_BalancePrecompiled *BalancePrecompiledRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, *types.Receipt, error) { + return _BalancePrecompiled.Contract.BalancePrecompiledTransactor.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_BalancePrecompiled *BalancePrecompiledRaw) TransactWithResult(opts *bind.TransactOpts, result interface{}, method string, params ...interface{}) (*types.Transaction, *types.Receipt, error) { + return _BalancePrecompiled.Contract.BalancePrecompiledTransactor.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 (_BalancePrecompiled *BalancePrecompiledCallerRaw) Call(opts *bind.CallOpts, result interface{}, method string, params ...interface{}) error { + return _BalancePrecompiled.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 (_BalancePrecompiled *BalancePrecompiledTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, *types.Receipt, error) { + return _BalancePrecompiled.Contract.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_BalancePrecompiled *BalancePrecompiledTransactorRaw) TransactWithResult(opts *bind.TransactOpts, result interface{}, method string, params ...interface{}) (*types.Transaction, *types.Receipt, error) { + return _BalancePrecompiled.Contract.contract.TransactWithResult(opts, result, method, params...) +} + +// GetBalance is a free data retrieval call binding the contract method 0xf8b2cb4f. +// +// Solidity: function getBalance(address account) constant returns(uint256) +func (_BalancePrecompiled *BalancePrecompiledCaller) GetBalance(opts *bind.CallOpts, account common.Address) (*big.Int, error) { + var ( + ret0 = new(*big.Int) + ) + out := ret0 + err := _BalancePrecompiled.contract.Call(opts, out, "getBalance", account) + return *ret0, err +} + +// GetBalance is a free data retrieval call binding the contract method 0xf8b2cb4f. +// +// Solidity: function getBalance(address account) constant returns(uint256) +func (_BalancePrecompiled *BalancePrecompiledSession) GetBalance(account common.Address) (*big.Int, error) { + return _BalancePrecompiled.Contract.GetBalance(&_BalancePrecompiled.CallOpts, account) +} + +// GetBalance is a free data retrieval call binding the contract method 0xf8b2cb4f. +// +// Solidity: function getBalance(address account) constant returns(uint256) +func (_BalancePrecompiled *BalancePrecompiledCallerSession) GetBalance(account common.Address) (*big.Int, error) { + return _BalancePrecompiled.Contract.GetBalance(&_BalancePrecompiled.CallOpts, account) +} + +// ListCaller is a free data retrieval call binding the contract method 0x511ab10c. +// +// Solidity: function listCaller() constant returns(address[]) +func (_BalancePrecompiled *BalancePrecompiledCaller) ListCaller(opts *bind.CallOpts) ([]common.Address, error) { + var ( + ret0 = new([]common.Address) + ) + out := ret0 + err := _BalancePrecompiled.contract.Call(opts, out, "listCaller") + return *ret0, err +} + +// ListCaller is a free data retrieval call binding the contract method 0x511ab10c. +// +// Solidity: function listCaller() constant returns(address[]) +func (_BalancePrecompiled *BalancePrecompiledSession) ListCaller() ([]common.Address, error) { + return _BalancePrecompiled.Contract.ListCaller(&_BalancePrecompiled.CallOpts) +} + +// ListCaller is a free data retrieval call binding the contract method 0x511ab10c. +// +// Solidity: function listCaller() constant returns(address[]) +func (_BalancePrecompiled *BalancePrecompiledCallerSession) ListCaller() ([]common.Address, error) { + return _BalancePrecompiled.Contract.ListCaller(&_BalancePrecompiled.CallOpts) +} + +// AddBalance is a paid mutator transaction binding the contract method 0x21e5383a. +// +// Solidity: function addBalance(address account, uint256 amount) returns() +func (_BalancePrecompiled *BalancePrecompiledTransactor) AddBalance(opts *bind.TransactOpts, account common.Address, amount *big.Int) (*types.Transaction, *types.Receipt, error) { + var () + out := &[]interface{}{} + transaction, receipt, err := _BalancePrecompiled.contract.TransactWithResult(opts, out, "addBalance", account, amount) + return transaction, receipt, err +} + +func (_BalancePrecompiled *BalancePrecompiledTransactor) AsyncAddBalance(handler func(*types.Receipt, error), opts *bind.TransactOpts, account common.Address, amount *big.Int) (*types.Transaction, error) { + return _BalancePrecompiled.contract.AsyncTransact(opts, handler, "addBalance", account, amount) +} + +// AddBalance is a paid mutator transaction binding the contract method 0x21e5383a. +// +// Solidity: function addBalance(address account, uint256 amount) returns() +func (_BalancePrecompiled *BalancePrecompiledSession) AddBalance(account common.Address, amount *big.Int) (*types.Transaction, *types.Receipt, error) { + return _BalancePrecompiled.Contract.AddBalance(&_BalancePrecompiled.TransactOpts, account, amount) +} + +func (_BalancePrecompiled *BalancePrecompiledSession) AsyncAddBalance(handler func(*types.Receipt, error), account common.Address, amount *big.Int) (*types.Transaction, error) { + return _BalancePrecompiled.Contract.AsyncAddBalance(handler, &_BalancePrecompiled.TransactOpts, account, amount) +} + +// AddBalance is a paid mutator transaction binding the contract method 0x21e5383a. +// +// Solidity: function addBalance(address account, uint256 amount) returns() +func (_BalancePrecompiled *BalancePrecompiledTransactorSession) AddBalance(account common.Address, amount *big.Int) (*types.Transaction, *types.Receipt, error) { + return _BalancePrecompiled.Contract.AddBalance(&_BalancePrecompiled.TransactOpts, account, amount) +} + +func (_BalancePrecompiled *BalancePrecompiledTransactorSession) AsyncAddBalance(handler func(*types.Receipt, error), account common.Address, amount *big.Int) (*types.Transaction, error) { + return _BalancePrecompiled.Contract.AsyncAddBalance(handler, &_BalancePrecompiled.TransactOpts, account, amount) +} + +// RegisterCaller is a paid mutator transaction binding the contract method 0x3b9a32de. +// +// Solidity: function registerCaller(address account) returns() +func (_BalancePrecompiled *BalancePrecompiledTransactor) RegisterCaller(opts *bind.TransactOpts, account common.Address) (*types.Transaction, *types.Receipt, error) { + var () + out := &[]interface{}{} + transaction, receipt, err := _BalancePrecompiled.contract.TransactWithResult(opts, out, "registerCaller", account) + return transaction, receipt, err +} + +func (_BalancePrecompiled *BalancePrecompiledTransactor) AsyncRegisterCaller(handler func(*types.Receipt, error), opts *bind.TransactOpts, account common.Address) (*types.Transaction, error) { + return _BalancePrecompiled.contract.AsyncTransact(opts, handler, "registerCaller", account) +} + +// RegisterCaller is a paid mutator transaction binding the contract method 0x3b9a32de. +// +// Solidity: function registerCaller(address account) returns() +func (_BalancePrecompiled *BalancePrecompiledSession) RegisterCaller(account common.Address) (*types.Transaction, *types.Receipt, error) { + return _BalancePrecompiled.Contract.RegisterCaller(&_BalancePrecompiled.TransactOpts, account) +} + +func (_BalancePrecompiled *BalancePrecompiledSession) AsyncRegisterCaller(handler func(*types.Receipt, error), account common.Address) (*types.Transaction, error) { + return _BalancePrecompiled.Contract.AsyncRegisterCaller(handler, &_BalancePrecompiled.TransactOpts, account) +} + +// RegisterCaller is a paid mutator transaction binding the contract method 0x3b9a32de. +// +// Solidity: function registerCaller(address account) returns() +func (_BalancePrecompiled *BalancePrecompiledTransactorSession) RegisterCaller(account common.Address) (*types.Transaction, *types.Receipt, error) { + return _BalancePrecompiled.Contract.RegisterCaller(&_BalancePrecompiled.TransactOpts, account) +} + +func (_BalancePrecompiled *BalancePrecompiledTransactorSession) AsyncRegisterCaller(handler func(*types.Receipt, error), account common.Address) (*types.Transaction, error) { + return _BalancePrecompiled.Contract.AsyncRegisterCaller(handler, &_BalancePrecompiled.TransactOpts, account) +} + +// SubBalance is a paid mutator transaction binding the contract method 0xcf8eeb7e. +// +// Solidity: function subBalance(address account, uint256 amount) returns() +func (_BalancePrecompiled *BalancePrecompiledTransactor) SubBalance(opts *bind.TransactOpts, account common.Address, amount *big.Int) (*types.Transaction, *types.Receipt, error) { + var () + out := &[]interface{}{} + transaction, receipt, err := _BalancePrecompiled.contract.TransactWithResult(opts, out, "subBalance", account, amount) + return transaction, receipt, err +} + +func (_BalancePrecompiled *BalancePrecompiledTransactor) AsyncSubBalance(handler func(*types.Receipt, error), opts *bind.TransactOpts, account common.Address, amount *big.Int) (*types.Transaction, error) { + return _BalancePrecompiled.contract.AsyncTransact(opts, handler, "subBalance", account, amount) +} + +// SubBalance is a paid mutator transaction binding the contract method 0xcf8eeb7e. +// +// Solidity: function subBalance(address account, uint256 amount) returns() +func (_BalancePrecompiled *BalancePrecompiledSession) SubBalance(account common.Address, amount *big.Int) (*types.Transaction, *types.Receipt, error) { + return _BalancePrecompiled.Contract.SubBalance(&_BalancePrecompiled.TransactOpts, account, amount) +} + +func (_BalancePrecompiled *BalancePrecompiledSession) AsyncSubBalance(handler func(*types.Receipt, error), account common.Address, amount *big.Int) (*types.Transaction, error) { + return _BalancePrecompiled.Contract.AsyncSubBalance(handler, &_BalancePrecompiled.TransactOpts, account, amount) +} + +// SubBalance is a paid mutator transaction binding the contract method 0xcf8eeb7e. +// +// Solidity: function subBalance(address account, uint256 amount) returns() +func (_BalancePrecompiled *BalancePrecompiledTransactorSession) SubBalance(account common.Address, amount *big.Int) (*types.Transaction, *types.Receipt, error) { + return _BalancePrecompiled.Contract.SubBalance(&_BalancePrecompiled.TransactOpts, account, amount) +} + +func (_BalancePrecompiled *BalancePrecompiledTransactorSession) AsyncSubBalance(handler func(*types.Receipt, error), account common.Address, amount *big.Int) (*types.Transaction, error) { + return _BalancePrecompiled.Contract.AsyncSubBalance(handler, &_BalancePrecompiled.TransactOpts, account, amount) +} + +// Transfer is a paid mutator transaction binding the contract method 0xbeabacc8. +// +// Solidity: function transfer(address from, address to, uint256 amount) returns() +func (_BalancePrecompiled *BalancePrecompiledTransactor) Transfer(opts *bind.TransactOpts, from common.Address, to common.Address, amount *big.Int) (*types.Transaction, *types.Receipt, error) { + var () + out := &[]interface{}{} + transaction, receipt, err := _BalancePrecompiled.contract.TransactWithResult(opts, out, "transfer", from, to, amount) + return transaction, receipt, err +} + +func (_BalancePrecompiled *BalancePrecompiledTransactor) AsyncTransfer(handler func(*types.Receipt, error), opts *bind.TransactOpts, from common.Address, to common.Address, amount *big.Int) (*types.Transaction, error) { + return _BalancePrecompiled.contract.AsyncTransact(opts, handler, "transfer", from, to, amount) +} + +// Transfer is a paid mutator transaction binding the contract method 0xbeabacc8. +// +// Solidity: function transfer(address from, address to, uint256 amount) returns() +func (_BalancePrecompiled *BalancePrecompiledSession) Transfer(from common.Address, to common.Address, amount *big.Int) (*types.Transaction, *types.Receipt, error) { + return _BalancePrecompiled.Contract.Transfer(&_BalancePrecompiled.TransactOpts, from, to, amount) +} + +func (_BalancePrecompiled *BalancePrecompiledSession) AsyncTransfer(handler func(*types.Receipt, error), from common.Address, to common.Address, amount *big.Int) (*types.Transaction, error) { + return _BalancePrecompiled.Contract.AsyncTransfer(handler, &_BalancePrecompiled.TransactOpts, from, to, amount) +} + +// Transfer is a paid mutator transaction binding the contract method 0xbeabacc8. +// +// Solidity: function transfer(address from, address to, uint256 amount) returns() +func (_BalancePrecompiled *BalancePrecompiledTransactorSession) Transfer(from common.Address, to common.Address, amount *big.Int) (*types.Transaction, *types.Receipt, error) { + return _BalancePrecompiled.Contract.Transfer(&_BalancePrecompiled.TransactOpts, from, to, amount) +} + +func (_BalancePrecompiled *BalancePrecompiledTransactorSession) AsyncTransfer(handler func(*types.Receipt, error), from common.Address, to common.Address, amount *big.Int) (*types.Transaction, error) { + return _BalancePrecompiled.Contract.AsyncTransfer(handler, &_BalancePrecompiled.TransactOpts, from, to, amount) +} + +// UnregisterCaller is a paid mutator transaction binding the contract method 0xafb4bfbd. +// +// Solidity: function unregisterCaller(address account) returns() +func (_BalancePrecompiled *BalancePrecompiledTransactor) UnregisterCaller(opts *bind.TransactOpts, account common.Address) (*types.Transaction, *types.Receipt, error) { + var () + out := &[]interface{}{} + transaction, receipt, err := _BalancePrecompiled.contract.TransactWithResult(opts, out, "unregisterCaller", account) + return transaction, receipt, err +} + +func (_BalancePrecompiled *BalancePrecompiledTransactor) AsyncUnregisterCaller(handler func(*types.Receipt, error), opts *bind.TransactOpts, account common.Address) (*types.Transaction, error) { + return _BalancePrecompiled.contract.AsyncTransact(opts, handler, "unregisterCaller", account) +} + +// UnregisterCaller is a paid mutator transaction binding the contract method 0xafb4bfbd. +// +// Solidity: function unregisterCaller(address account) returns() +func (_BalancePrecompiled *BalancePrecompiledSession) UnregisterCaller(account common.Address) (*types.Transaction, *types.Receipt, error) { + return _BalancePrecompiled.Contract.UnregisterCaller(&_BalancePrecompiled.TransactOpts, account) +} + +func (_BalancePrecompiled *BalancePrecompiledSession) AsyncUnregisterCaller(handler func(*types.Receipt, error), account common.Address) (*types.Transaction, error) { + return _BalancePrecompiled.Contract.AsyncUnregisterCaller(handler, &_BalancePrecompiled.TransactOpts, account) +} + +// UnregisterCaller is a paid mutator transaction binding the contract method 0xafb4bfbd. +// +// Solidity: function unregisterCaller(address account) returns() +func (_BalancePrecompiled *BalancePrecompiledTransactorSession) UnregisterCaller(account common.Address) (*types.Transaction, *types.Receipt, error) { + return _BalancePrecompiled.Contract.UnregisterCaller(&_BalancePrecompiled.TransactOpts, account) +} + +func (_BalancePrecompiled *BalancePrecompiledTransactorSession) AsyncUnregisterCaller(handler func(*types.Receipt, error), account common.Address) (*types.Transaction, error) { + return _BalancePrecompiled.Contract.AsyncUnregisterCaller(handler, &_BalancePrecompiled.TransactOpts, account) +} diff --git a/v3/precompiled/balance/balance_service.go b/v3/precompiled/balance/balance_service.go new file mode 100644 index 00000000..390ea226 --- /dev/null +++ b/v3/precompiled/balance/balance_service.go @@ -0,0 +1,60 @@ +package balanceprecompiled + +import ( + "fmt" + "github.com/FISCO-BCOS/go-sdk/v3/abi/bind" + "github.com/FISCO-BCOS/go-sdk/v3/client" + "github.com/FISCO-BCOS/go-sdk/v3/types" + "github.com/ethereum/go-ethereum/common" + "math/big" +) + +type Service struct { + balance *BalancePrecompiled + BalancePrecompiledAuth *bind.TransactOpts + client *client.Client +} + +var balancePrecompiledAddress = common.HexToAddress("0000000000000000000000000000000000001011") + +func NewBalanceService(client *client.Client) (*Service, error) { + instance, err := NewBalancePrecompiled(balancePrecompiledAddress, client) + if err != nil { + return nil, err + } + auth := client.GetTransactOpts() + return &Service{balance: instance, BalancePrecompiledAuth: auth, client: client}, nil +} + +func (service *Service) GetBalance(account string) (*big.Int, error) { + opts := &bind.CallOpts{From: service.BalancePrecompiledAuth.From} + ret0, err := service.balance.GetBalance(opts, common.HexToAddress(account)) + if err != nil { + return big.NewInt(0), err + } + return ret0, nil +} + +func (service *Service) Transfer(from string, to string, value *big.Int) (receipt *types.Receipt, err error) { + _, receipt, err = service.balance.Transfer(service.BalancePrecompiledAuth, common.HexToAddress(from), common.HexToAddress(to), value) + if err != nil { + return nil, fmt.Errorf("service Transfer failed: %+v", err) + } + return receipt, nil +} + +func (service *Service) addBalance(account string, value *big.Int) (receipt *types.Receipt, err error) { + _, receipt, err = service.balance.AddBalance(service.BalancePrecompiledAuth, common.HexToAddress(account), value) + if err != nil { + return nil, fmt.Errorf("service addBalance failed: %+v", err) + } + return receipt, nil +} + +func (service *Service) subBalance(account string, value *big.Int) (receipt *types.Receipt, err error) { + _, receipt, err = service.balance.SubBalance(service.BalancePrecompiledAuth, common.HexToAddress(account), value) + if err != nil { + return nil, fmt.Errorf("service subBalance failed: %+v", err) + } + return receipt, nil +} diff --git a/v3/precompiled/balance/balance_service_test.go b/v3/precompiled/balance/balance_service_test.go new file mode 100644 index 00000000..29589fa0 --- /dev/null +++ b/v3/precompiled/balance/balance_service_test.go @@ -0,0 +1,133 @@ +package balanceprecompiled + +import ( + "context" + "encoding/hex" + "github.com/FISCO-BCOS/go-sdk/v3/client" + "math/big" + "os" + "testing" +) + +func getClient(t *testing.T) *client.Client { + privateKey, _ := hex.DecodeString("b89d42f12290070f235fb8fb61dcf96e3b11516c5d4f6333f26e49bb955f8b62") + 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 := NewBalanceService(c) + if err != nil { + t.Fatalf("init CnsService failed: %+v", err) + } + service = newService +} + +var ( + service *Service + channel = make(chan int) +) + +func TestMain(m *testing.M) { + getService(&testing.T{}) + exitCode := m.Run() + os.Exit(exitCode) +} + +func TestGetBalance(t *testing.T) { + address := "0xc92ad282ba7868b032341a3921b3635b0c45de74" + balance, err := service.GetBalance(address) + if err != nil { + t.Fatalf("get balance failed: %+v", err) + } + if balance.Cmp(big.NewInt(0)) == 0 { + t.Fatalf("0xc92ad282ba7868b032341a3921b3635b0c45de74 balance is 0") + } + t.Logf("TestGetBalance failed: %+v", balance) +} + +func TestBalance(t *testing.T) { + account := "0xc92ad282ba7868b032341a3921b3635b0c45de74" + value := big.NewInt(100) + _, err := service.addBalance(account, value) + if err != nil { + t.Fatalf("add balance failed: %+v", err) + } + balance, err := service.GetBalance(account) + if err != nil { + t.Fatalf("get balance failed: %+v", err) + } + // check balance + if balance.Cmp(value) != 0 { + t.Fatalf("add balance failed, balance is not equal to %+v", value) + } + + // sub balance + value1 := big.NewInt(50) + _, err = service.subBalance(account, value1) + if err != nil { + t.Fatalf("sub balance failed: %+v", err) + } + + // check balance + balance, err = service.GetBalance(account) + if err != nil { + t.Fatalf("get balance failed: %+v", err) + } + if balance.Cmp(value1) != 0 { + t.Fatalf("sub balance failed, balance is not equal to %+v", value1) + } + + t.Logf("TestBalance success") +} + +func TestTransferBalance(t *testing.T) { + from := "0xc92ad282ba7868b032341a3921b3635b0c45de74" + to := "0x2c7536e3605d9c16a7a3d7b1898e529396a65c23" + value := big.NewInt(10) + // addBalance to from + _, err := service.addBalance(from, big.NewInt(50)) + if err != nil { + t.Fatalf("add balance failed: %+v", err) + } + // check from balance + balance, err := service.GetBalance(from) + if err != nil { + t.Fatalf("get balance failed: %+v", err) + } + if balance.Cmp(big.NewInt(50)) != 0 { + t.Fatalf("add balance failed, from balance is not equal to 50") + } + + // transfer + _, err = service.Transfer(from, to, value) + if err != nil { + t.Fatalf("transfer balance failed: %+v", err) + } + + // check from balance + fromBalance, err := service.GetBalance(from) + if err != nil { + t.Fatalf("get balance failed: %+v", err) + } + if fromBalance.Cmp(big.NewInt(40)) != 0 { + t.Fatalf("transfer balance failed, from balance is not equal to 40") + } + + // check to balance + toBalance, err := service.GetBalance(to) + if err != nil { + t.Fatalf("get balance failed: %+v", err) + } + if toBalance.Cmp(big.NewInt(10)) != 0 { + t.Fatalf("transfer balance failed, to balance is not equal to 10") + } + + t.Logf("TestTransferBalance success") +} diff --git a/v3/precompiled/solidity/balance/BalancePrecompiled.sol b/v3/precompiled/solidity/balance/BalancePrecompiled.sol new file mode 100644 index 00000000..0bf524b3 --- /dev/null +++ b/v3/precompiled/solidity/balance/BalancePrecompiled.sol @@ -0,0 +1,18 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity ^0.8.0; + +contract BalancePrecompiled { + function getBalance(address account) public view returns (uint256) {} + + function addBalance(address account, uint256 amount) public {} + + function subBalance(address account, uint256 amount) public {} + + function transfer(address from, address to, uint256 amount) public {} + + function registerCaller(address account) public {} + + function unregisterCaller(address account) public {} + + function listCaller() public view returns (address[] memory) {} +}