From 670b1fe4249cfd4091d46ac4552032ece30c3e55 Mon Sep 17 00:00:00 2001 From: XingQiang Bai Date: Mon, 8 Jan 2024 17:34:57 +0800 Subject: [PATCH] add getABI method (#248) --- .ci/ethPrecompiled/bn256.go | 4 +- .ci/ethPrecompiled/bn256_gm.go | 4 +- .ci/hello/HelloWorld.go | 4 +- .ci/store/Store.go | 12 +- go.mod | 17 - go.sum | 23 -- v3/abi/bind/backend.go | 4 +- v3/abi/bind/base.go | 35 +- v3/abi/bind/template.go | 4 +- v3/client/connection.go | 170 +++------ v3/client/go_client.go | 52 ++- v3/client/go_client_test.go | 43 ++- v3/cmd/commandline/auth_manager.go | 36 +- v3/cmd/commandline/commands.go | 34 +- v3/cmd/commandline/system_config.go | 30 +- v3/examples/KVTableTest.go | 4 +- v3/examples/hello_world/wrapper/HelloWorld.go | 4 +- v3/examples/parallelok/main.go | 2 +- v3/examples/parallelok/parallelOk.go | 4 +- v3/go.mod | 5 +- v3/go.sum | 6 +- v3/ios/contract_proxy.go | 4 +- v3/precompiled/auth/Committee.go | 4 +- v3/precompiled/auth/CommitteeManager.go | 4 +- .../auth/ContractAuthPrecompiled.go | 4 +- v3/precompiled/auth/ProposalManager.go | 4 +- v3/precompiled/auth/auth_manager_service.go | 6 + v3/precompiled/sharding/sharding.go | 4 +- .../contract/kvTableTest/KVTableTest.go | 4 +- .../contract/parallelOk/ParallelOk.go | 4 +- v3/types/transaction.go | 349 +++++------------- v3/types/transaction_signing.go | 96 ++--- 32 files changed, 373 insertions(+), 607 deletions(-) diff --git a/.ci/ethPrecompiled/bn256.go b/.ci/ethPrecompiled/bn256.go index 37e786cb..555cc951 100644 --- a/.ci/ethPrecompiled/bn256.go +++ b/.ci/ethPrecompiled/bn256.go @@ -37,7 +37,7 @@ func DeployPrecompiledbn256(auth *bind.TransactOpts, backend bind.ContractBacken return common.Address{}, nil, nil, err } - address, receipt, contract, err := bind.DeployContract(auth, parsed, common.FromHex(Precompiledbn256Bin), backend) + address, receipt, contract, err := bind.DeployContract(auth, parsed, common.FromHex(Precompiledbn256Bin), Precompiledbn256ABI, backend) if err != nil { return common.Address{}, nil, nil, err } @@ -50,7 +50,7 @@ func AsyncDeployPrecompiledbn256(auth *bind.TransactOpts, handler func(*types.Re return nil, err } - tx, err := bind.AsyncDeployContract(auth, handler, parsed, common.FromHex(Precompiledbn256Bin), backend) + tx, err := bind.AsyncDeployContract(auth, handler, parsed, common.FromHex(Precompiledbn256Bin), Precompiledbn256ABI, backend) if err != nil { return nil, err } diff --git a/.ci/ethPrecompiled/bn256_gm.go b/.ci/ethPrecompiled/bn256_gm.go index 0e0500ab..3332c04d 100644 --- a/.ci/ethPrecompiled/bn256_gm.go +++ b/.ci/ethPrecompiled/bn256_gm.go @@ -37,7 +37,7 @@ func DeployPrecompiledbn256(auth *bind.TransactOpts, backend bind.ContractBacken return common.Address{}, nil, nil, err } - address, receipt, contract, err := bind.DeployContract(auth, parsed, common.FromHex(Precompiledbn256Bin), backend) + address, receipt, contract, err := bind.DeployContract(auth, parsed, common.FromHex(Precompiledbn256Bin), Precompiledbn256ABI, backend) if err != nil { return common.Address{}, nil, nil, err } @@ -50,7 +50,7 @@ func AsyncDeployPrecompiledbn256(auth *bind.TransactOpts, handler func(*types.Re return nil, err } - tx, err := bind.AsyncDeployContract(auth, handler, parsed, common.FromHex(Precompiledbn256Bin), backend) + tx, err := bind.AsyncDeployContract(auth, handler, parsed, common.FromHex(Precompiledbn256Bin), Precompiledbn256ABI, backend) if err != nil { return nil, err } diff --git a/.ci/hello/HelloWorld.go b/.ci/hello/HelloWorld.go index 1393ceee..29325864 100644 --- a/.ci/hello/HelloWorld.go +++ b/.ci/hello/HelloWorld.go @@ -37,7 +37,7 @@ func DeployHelloWorld(auth *bind.TransactOpts, backend bind.ContractBackend) (co return common.Address{}, nil, nil, err } - address, receipt, contract, err := bind.DeployContract(auth, parsed, common.FromHex(HelloWorldBin), backend) + address, receipt, contract, err := bind.DeployContract(auth, parsed, common.FromHex(HelloWorldBin), HelloWorldABI, backend) if err != nil { return common.Address{}, nil, nil, err } @@ -50,7 +50,7 @@ func AsyncDeployHelloWorld(auth *bind.TransactOpts, handler func(*types.Receipt, return nil, err } - tx, err := bind.AsyncDeployContract(auth, handler, parsed, common.FromHex(HelloWorldBin), backend) + tx, err := bind.AsyncDeployContract(auth, handler, parsed, common.FromHex(HelloWorldBin), HelloWorldABI, backend) if err != nil { return nil, err } diff --git a/.ci/store/Store.go b/.ci/store/Store.go index 01689e97..1d5564f2 100644 --- a/.ci/store/Store.go +++ b/.ci/store/Store.go @@ -37,7 +37,7 @@ func DeployStore(auth *bind.TransactOpts, backend bind.ContractBackend, _version return common.Address{}, nil, nil, err } - address, receipt, contract, err := bind.DeployContract(auth, parsed, common.FromHex(StoreBin), backend, _version) + address, receipt, contract, err := bind.DeployContract(auth, parsed, common.FromHex(StoreBin), StoreABI, backend, _version) if err != nil { return common.Address{}, nil, nil, err } @@ -50,7 +50,7 @@ func AsyncDeployStore(auth *bind.TransactOpts, handler func(*types.Receipt, erro return nil, err } - tx, err := bind.AsyncDeployContract(auth, handler, parsed, common.FromHex(StoreBin), backend, _version) + tx, err := bind.AsyncDeployContract(auth, handler, parsed, common.FromHex(StoreBin), StoreABI, backend, _version) if err != nil { return nil, err } @@ -294,11 +294,11 @@ type StoreItemSet struct { // WatchItemSet is a free log subscription operation binding the contract event 0xe79e73da417710ae99aa2088575580a60415d359acfad9cdd3382d59c80281d4. // // Solidity: event ItemSet(bytes32 key, bytes32 value) -func (_Store *StoreFilterer) WatchItemSet(fromBlock *int64, handler func(int, []types.Log)) error { +func (_Store *StoreFilterer) WatchItemSet(fromBlock *int64, handler func(int, []types.Log)) (string, error) { return _Store.contract.WatchLogs(fromBlock, handler, "ItemSet") } -func (_Store *StoreFilterer) WatchAllItemSet(fromBlock *int64, handler func(int, []types.Log)) error { +func (_Store *StoreFilterer) WatchAllItemSet(fromBlock *int64, handler func(int, []types.Log)) (string, error) { return _Store.contract.WatchLogs(fromBlock, handler, "ItemSet") } @@ -316,11 +316,11 @@ func (_Store *StoreFilterer) ParseItemSet(log types.Log) (*StoreItemSet, error) // WatchItemSet is a free log subscription operation binding the contract event 0xe79e73da417710ae99aa2088575580a60415d359acfad9cdd3382d59c80281d4. // // Solidity: event ItemSet(bytes32 key, bytes32 value) -func (_Store *StoreSession) WatchItemSet(fromBlock *int64, handler func(int, []types.Log)) error { +func (_Store *StoreSession) WatchItemSet(fromBlock *int64, handler func(int, []types.Log)) (string, error) { return _Store.Contract.WatchItemSet(fromBlock, handler) } -func (_Store *StoreSession) WatchAllItemSet(fromBlock *int64, handler func(int, []types.Log)) error { +func (_Store *StoreSession) WatchAllItemSet(fromBlock *int64, handler func(int, []types.Log)) (string, error) { return _Store.Contract.WatchAllItemSet(fromBlock, handler) } diff --git a/go.mod b/go.mod index 20f97613..a4611188 100644 --- a/go.mod +++ b/go.mod @@ -2,20 +2,3 @@ module github.com/FISCO-BCOS/go-sdk go 1.21.5 -replace ( - // github.com/FISCO-BCOS/bcos-c-sdk v0.0.0-20231221132830-c0cfb1d98eec => ../bcos-c-sdk - golang.org/x/net => github.com/golang/net v0.0.0-20190415214537-1da14a5a36f2 - golang.org/x/sync => github.com/golang/sync v0.0.0-20190412183630-56d357773e84 -) - -require ( - github.com/FISCO-BCOS/crypto v0.0.0-20200202032121-bd8ab0b5d4f1 - github.com/ethereum/go-ethereum v1.10.21 - github.com/sirupsen/logrus v1.4.2 -) - -require ( - github.com/konsorten/go-windows-terminal-sequences v1.0.1 // indirect - golang.org/x/crypto v0.0.0-20210921155107-089bfa567519 // indirect - golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a // indirect -) diff --git a/go.sum b/go.sum index 478aec2a..e69de29b 100644 --- a/go.sum +++ b/go.sum @@ -1,23 +0,0 @@ -github.com/FISCO-BCOS/crypto v0.0.0-20200202032121-bd8ab0b5d4f1 h1:ThPht4qK10+cMZC5COIjHPq0INm5HAMVYqrez5zEgFI= -github.com/FISCO-BCOS/crypto v0.0.0-20200202032121-bd8ab0b5d4f1/go.mod h1:UrLdwsFrjiaCsvdcPLcH6B7s/FUmym3qfM93u2ziR+4= -github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= -github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/ethereum/go-ethereum v1.10.21 h1:5lqsEx92ZaZzRyOqBEXux4/UR06m296RGzN3ol3teJY= -github.com/ethereum/go-ethereum v1.10.21/go.mod h1:EYFyF19u3ezGLD4RqOkLq+ZCXzYbLoNDdZlMt7kyKFg= -github.com/konsorten/go-windows-terminal-sequences v1.0.1 h1:mweAR1A6xJ3oS2pRaGiHgQ4OO8tzTaLawm8vnODuwDk= -github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= -github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= -github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4= -github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= -github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= -github.com/stretchr/testify v1.7.2 h1:4jaiDzPyXQvSd7D0EjG45355tLlV3VOECpq10pLC+8s= -github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals= -golang.org/x/crypto v0.0.0-20210921155107-089bfa567519 h1:7I4JAnoQBe7ZtJcBaYHi5UtiO8tQHbUSXxL+pnGRANg= -golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a h1:dGzPydgVsqGcTRVwiLJ1jVbufYwmzD3LfVPLKsKg+0k= -golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= -gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/v3/abi/bind/backend.go b/v3/abi/bind/backend.go index ee0da673..3ed0eabf 100644 --- a/v3/abi/bind/backend.go +++ b/v3/abi/bind/backend.go @@ -70,8 +70,8 @@ type ContractTransactor interface { // PendingCodeAt returns the code of the given account in the pending state. PendingCodeAt(ctx context.Context, account common.Address) ([]byte, error) // SendTransaction injects the transaction into the pending pool for execution. - SendTransaction(ctx context.Context, tx *types.Transaction, contract *common.Address, input []byte) (*types.Receipt, error) - AsyncSendTransaction(ctx context.Context, tx *types.Transaction, contract *common.Address, input []byte, handler func(*types.Receipt, error)) error + SendTransaction(ctx context.Context, tx *types.Transaction) (*types.Receipt, error) + AsyncSendTransaction(ctx context.Context, tx *types.Transaction, handler func(*types.Receipt, error)) error // GetGroupID returns the groupID of the client GetGroupID() string // GetChainID returns the chainID of the blockchain diff --git a/v3/abi/bind/base.go b/v3/abi/bind/base.go index 4238ad29..e76f710f 100755 --- a/v3/abi/bind/base.go +++ b/v3/abi/bind/base.go @@ -97,26 +97,27 @@ func NewBoundContract(address common.Address, abi abi.ABI, caller ContractCaller // DeployContract deploys a contract onto the Ethereum blockchain and binds the // deployment address with a Go wrapper. -func DeployContract(opts *TransactOpts, abi abi.ABI, bytecode []byte, backend ContractBackend, params ...interface{}) (common.Address, *types.Receipt, *BoundContract, error) { - _, receipt, c, err := deploy(opts, abi, bytecode, backend, params...) +func DeployContract(opts *TransactOpts, abi abi.ABI, bytecode []byte, abiStr string, backend ContractBackend, params ...interface{}) (common.Address, *types.Receipt, *BoundContract, error) { + _, receipt, c, err := deploy(opts, abi, bytecode, abiStr, backend, params...) addr := common.Address{} if receipt != nil { addr = common.HexToAddress(receipt.ContractAddress) } return addr, receipt, c, err } -func DeployContractGetReceipt(opts *TransactOpts, abi abi.ABI, bytecode []byte, backend ContractBackend, params ...interface{}) (*types.Transaction, *types.Receipt, *BoundContract, error) { - tx, receipt, c, err := deploy(opts, abi, bytecode, backend, params...) + +func DeployContractGetReceipt(opts *TransactOpts, abi abi.ABI, bytecode []byte, abiStr string, backend ContractBackend, params ...interface{}) (*types.Transaction, *types.Receipt, *BoundContract, error) { + tx, receipt, c, err := deploy(opts, abi, bytecode, abiStr, backend, params...) return tx, receipt, c, err } -func deploy(opts *TransactOpts, abi abi.ABI, bytecode []byte, backend ContractBackend, params ...interface{}) (*types.Transaction, *types.Receipt, *BoundContract, error) { +func deploy(opts *TransactOpts, abi abi.ABI, bytecode []byte, abiStr string, backend ContractBackend, params ...interface{}) (*types.Transaction, *types.Receipt, *BoundContract, error) { c := NewBoundContract(common.Address{}, abi, backend, backend, backend) input, err := c.abi.Pack("", params...) if err != nil { return nil, nil, nil, err } - tx, receipt, err := c.transact(opts, nil, append(bytecode, input...)) + tx, receipt, err := c.transact(opts, nil, append(bytecode, input...), abiStr) if err != nil { return nil, nil, nil, err } @@ -127,7 +128,7 @@ func deploy(opts *TransactOpts, abi abi.ABI, bytecode []byte, backend ContractBa return tx, receipt, c, nil } -func AsyncDeployContract(opts *TransactOpts, handler func(*types.Receipt, error), abi abi.ABI, bytecode []byte, backend ContractBackend, params ...interface{}) (*types.Transaction, error) { +func AsyncDeployContract(opts *TransactOpts, handler func(*types.Receipt, error), abi abi.ABI, bytecode []byte, abiStr string, backend ContractBackend, params ...interface{}) (*types.Transaction, error) { // Otherwise try to deploy the contract c := NewBoundContract(common.Address{}, abi, backend, backend, backend) @@ -135,7 +136,7 @@ func AsyncDeployContract(opts *TransactOpts, handler func(*types.Receipt, error) if err != nil { return nil, err } - return c.asyncTransact(opts, nil, append(bytecode, input...), handler) + return c.asyncTransact(opts, nil, append(bytecode, input...), abiStr, handler) } // Call invokes the (constant) contract method with params as input values and @@ -198,7 +199,7 @@ func (c *BoundContract) TransactWithResult(opts *TransactOpts, result interface{ if err != nil { return nil, nil, err } - tx, receipt, err := c.transact(opts, &c.address, input) + tx, receipt, err := c.transact(opts, &c.address, input, "") c.abi.Unpack(result, method, common.FromHex(receipt.GetOutput())) return tx, receipt, err } @@ -210,7 +211,7 @@ func (c *BoundContract) Transact(opts *TransactOpts, method string, params ...in if err != nil { return nil, nil, err } - return c.transact(opts, &c.address, input) + return c.transact(opts, &c.address, input, "") } func (c *BoundContract) AsyncTransact(opts *TransactOpts, handler func(*types.Receipt, error), method string, params ...interface{}) (*types.Transaction, error) { @@ -219,28 +220,30 @@ func (c *BoundContract) AsyncTransact(opts *TransactOpts, handler func(*types.Re if err != nil { return nil, err } - return c.asyncTransact(opts, &c.address, input, handler) + return c.asyncTransact(opts, &c.address, input, "", handler) } // Transfer initiates a plain transaction to move funds to the contract, calling // its default method if one is available. func (c *BoundContract) Transfer(opts *TransactOpts) (*types.Transaction, *types.Receipt, error) { - return c.transact(opts, &c.address, nil) + return c.transact(opts, &c.address, nil, "") } // transact executes an actual transaction invocation, first deriving any missing // authorization fields, and then scheduling the transaction for execution. -func (c *BoundContract) transact(opts *TransactOpts, contract *common.Address, input []byte) (*types.Transaction, *types.Receipt, error) { +func (c *BoundContract) transact(opts *TransactOpts, contract *common.Address, input []byte, abi string) (*types.Transaction, *types.Receipt, error) { var receipt *types.Receipt var err error - if receipt, err = c.transactor.SendTransaction(ensureContext(opts.Context), nil, contract, input); err != nil { + tx := types.NewSimpleTx(contract, input, abi, "", "", c.transactor.SMCrypto()) + if receipt, err = c.transactor.SendTransaction(ensureContext(opts.Context), tx); err != nil { return nil, nil, err } return nil, receipt, nil } -func (c *BoundContract) asyncTransact(opts *TransactOpts, contract *common.Address, input []byte, handler func(*types.Receipt, error)) (*types.Transaction, error) { - if err := c.transactor.AsyncSendTransaction(ensureContext(opts.Context), nil, contract, input, handler); err != nil { +func (c *BoundContract) asyncTransact(opts *TransactOpts, contract *common.Address, input []byte, abi string, handler func(*types.Receipt, error)) (*types.Transaction, error) { + tx := types.NewSimpleTx(contract, input, abi, "", "", c.transactor.SMCrypto()) + if err := c.transactor.AsyncSendTransaction(ensureContext(opts.Context), tx, handler); err != nil { return nil, err } return nil, nil diff --git a/v3/abi/bind/template.go b/v3/abi/bind/template.go index 44634b8d..2d98b3e2 100644 --- a/v3/abi/bind/template.go +++ b/v3/abi/bind/template.go @@ -154,7 +154,7 @@ var ( if len(bytecode) == 0 { return common.Address{}, nil, nil, fmt.Errorf("cannot deploy empty bytecode") } - address, receipt, contract, err := bind.DeployContract(auth, parsed, bytecode, backend {{range .Constructor.Inputs}}, {{.Name}}{{end}}) + address, receipt, contract, err := bind.DeployContract(auth, parsed, bytecode, {{.Type}}ABI, backend {{range .Constructor.Inputs}}, {{.Name}}{{end}}) if err != nil { return common.Address{}, nil, nil, err } @@ -179,7 +179,7 @@ var ( if len(bytecode) == 0 { return nil, fmt.Errorf("cannot deploy empty bytecode") } - tx, err := bind.AsyncDeployContract(auth, handler, parsed, bytecode, backend {{range .Constructor.Inputs}}, {{.Name}}{{end}}) + tx, err := bind.AsyncDeployContract(auth, handler, parsed, bytecode, {{.Type}}ABI, backend {{range .Constructor.Inputs}}, {{.Name}}{{end}}) if err != nil { return nil, err } diff --git a/v3/client/connection.go b/v3/client/connection.go index fec66394..104879c5 100644 --- a/v3/client/connection.go +++ b/v3/client/connection.go @@ -20,7 +20,6 @@ import ( "errors" "fmt" "os" - "strconv" "sync" "sync/atomic" "time" @@ -35,7 +34,7 @@ import ( var ( ErrClientQuit = errors.New("client is closed") ErrNoResult = errors.New("no result in JSON-RPC response") - ErrNoRpcMehtod = errors.New("no rpc method") + ErrNoRpcMethod = errors.New("no rpc method") ErrSubscriptionQueueOverflow = errors.New("subscription queue overflow") errClientReconnected = errors.New("client reconnected") errDead = errors.New("connection lost") @@ -47,20 +46,7 @@ const ( defaultDialTimeout = 10 * time.Second // used if context has no deadline subscribeTimeout = 5 * time.Second // overall timeout eth_subscribe, rpc_modules calls amopTimeout = 1000 -) - -const ( - // Subscriptions are removed when the subscriber cannot keep up. - // - // This can be worked around by supplying a channel with sufficiently sized buffer, - // but this can be inconvenient and hard to explain in the docs. Another issue with - // buffered channels is that the buffer is static even though it might not be needed - // most of the time. - // - // The approach taken here is to maintain a per-subscription linked list buffer - // shrinks on demand. If the buffer reaches the size below, the subscription is - // dropped. - maxClientSubscriptionBuffer = 20000 + jsonRPCVersion = "2.0" ) // Error wraps RPC errors, which contain an error code in addition to the message. @@ -69,59 +55,12 @@ type Error interface { ErrorCode() int // returns the code } -// ServerCodec implements reading, parsing and writing RPC messages for the server side of -// a RPC session. Implementations must be go-routine safe since the codec can be called in -// multiple go-routines concurrently. -type ServerCodec interface { - Read() (msgs []*jsonrpcMessage, isBatch bool, err error) - Close() - jsonWriter -} - -// jsonWriter can write JSON messages to its underlying connection. -// Implementations must be safe for concurrent use. -type jsonWriter interface { - Write(context.Context, interface{}) error - // Closed returns a channel which is closed when the connection is closed. - Closed() <-chan interface{} - // RemoteAddr returns the peer address of the connection. - RemoteAddr() string -} - // Connection represents a connection to an RPC server. type Connection struct { csdk *csdk.CSDK - idCounter uint32 + idCounter int64 blockNumberNotify func(int64) notifyLock sync.Mutex - - // This function, if non-nil, is called when the connection is lost. - reconnectFunc reconnectFunc - - // writeConn is used for writing to the connection on the caller's goroutine. It should - // only be accessed outside of dispatch, with the write lock held. The write lock is - // taken by sending on requestOp and released by sending on sendDone. - writeConn jsonWriter - - // for dispatch - didClose chan struct{} // closed when client quits - reconnected chan ServerCodec // where write/reconnect sends the new connection -} - -type reconnectFunc func(ctx context.Context) (ServerCodec, error) - -type clientContextKey struct{} - -type clientConn struct { - codec ServerCodec -} - -func (c *Connection) newClientConn(conn ServerCodec) *clientConn { - return &clientConn{conn} -} - -func (cc *clientConn) close(err error, inflightReq *requestOp) { - cc.codec.Close() } type requestOp struct { @@ -195,28 +134,12 @@ func processEventLogMsg(respBody []byte, handler interface{}) { handler.(func(int, []types.Log))(int(eventLogResponse.Status), logs) } -// ClientFromContext Connection retrieves the client from the context, if any. This can be used to perform -// 'reverse calls' in a handler method. -func ClientFromContext(ctx context.Context) (*Connection, bool) { - client, ok := ctx.Value(clientContextKey{}).(*Connection) - return client, ok -} - -func NewClient(connect reconnectFunc, csdk *csdk.CSDK) (*Connection, error) { - c := initClient(nil) - c.reconnectFunc = connect - c.csdk = csdk - return c, nil -} - func NewConnectionByFile(configFile, groupID string, privateKey []byte) (*Connection, error) { sdk, err := csdk.NewSDKByConfigFile(configFile, groupID, privateKey) if err != nil { return nil, err } - c := initClient(nil) - c.reconnectFunc = nil - c.csdk = sdk + c := &Connection{csdk: sdk} return c, nil } @@ -245,28 +168,28 @@ func NewConnection(config *Config) (*Connection, error) { if err != nil { return nil, err } - c := initClient(nil) - c.reconnectFunc = nil - c.csdk = sdk + c := &Connection{csdk: sdk} return c, nil } -func initClient(conn ServerCodec) *Connection { - c := &Connection{ - writeConn: conn, - didClose: make(chan struct{}), - reconnected: make(chan ServerCodec), - } - return c -} - func (c *Connection) GetCSDK() *csdk.CSDK { return c.csdk } -func (c *Connection) nextID() json.RawMessage { - id := atomic.AddUint32(&c.idCounter, 1) - return strconv.AppendUint(nil, uint64(id), 10) +func (c *Connection) nextID() int64 { + id := atomic.AddInt64(&c.idCounter, 1) + return id +} + +func (c *Connection) NewMessage(method string, paramsIn ...interface{}) (*jsonrpcMessage, error) { + msg := &jsonrpcMessage{Version: jsonRPCVersion, ID: c.nextID(), Method: method} + if paramsIn != nil { // prevent sending "params":null + var err error + if msg.Params, err = json.Marshal(paramsIn); err != nil { + return nil, err + } + } + return msg, nil } // Close closes the client, aborting any in-flight requests. @@ -435,6 +358,8 @@ func (c *Connection) CallContext(ctx context.Context, result interface{}, method c.csdk.GetGroupInfoList(op.respChanData) case "getPendingTxSize": c.csdk.GetPendingTxSize(op.respChanData) + case "asyncSendTransaction": + fallthrough case "sendTransaction": fallthrough case "SendEncodedTransaction": @@ -442,10 +367,23 @@ func (c *Connection) CallContext(ctx context.Context, result interface{}, method if method == "sendTransaction" { data := hexutil.Encode(args[0].([]byte)) contractAddress := args[1].(string) - if len(args) >= 3 { - handler = args[2].(func(*types.Receipt, error)) + var abiStr string + if len(args) >= 3 && len(contractAddress) == 0 { + abiStr = args[2].(string) } - _, err := c.csdk.CreateAndSendTransaction(op.respChanData, contractAddress, data, "", true) + _, err := c.csdk.CreateAndSendTransaction(op.respChanData, contractAddress, data, abiStr, "", true) + if err != nil { + return err + } + } else if method == "asyncSendTransaction" { + data := hexutil.Encode(args[0].([]byte)) + contractAddress := args[1].(string) + handler = args[2].(func(*types.Receipt, error)) + var abiStr string + if len(args) >= 4 && len(contractAddress) == 0 { + abiStr = args[3].(string) + } + _, err := c.csdk.CreateAndSendTransaction(op.respChanData, contractAddress, data, abiStr, "", true) if err != nil { return err } @@ -487,7 +425,7 @@ func (c *Connection) CallContext(ctx context.Context, result interface{}, method return nil } default: - return ErrNoRpcMehtod + return ErrNoRpcMethod } // dispatch has accepted the request and will close the channel when it quits. @@ -504,27 +442,19 @@ func (c *Connection) CallContext(ctx context.Context, result interface{}, method } } -func (c *Connection) reconnect(ctx context.Context) error { - if c.reconnectFunc == nil { - return errDead - } - - if _, ok := ctx.Deadline(); !ok { - var cancel func() - ctx, cancel = context.WithTimeout(ctx, defaultDialTimeout) - defer cancel() - } - newconn, err := c.reconnectFunc(ctx) +func (c *Connection) sendRPCRequest(group, node, jsonRequest string) (*jsonrpcMessage, error) { + callback := &csdk.CallbackChan{Data: make(chan csdk.Response, 1)} + err := c.csdk.SendRPCRequest(group, node, jsonRequest, callback) if err != nil { - // logrus.Trace("RPC client reconnect failed", "err", err) - return err + return nil, err } - select { - case c.reconnected <- newconn: - c.writeConn = newconn - return nil - case <-c.didClose: - newconn.Close() - return ErrClientQuit + respBody := <-callback.Data + var respData jsonrpcMessage + if respBody.Err == nil { + if err = json.Unmarshal(respBody.Result.([]byte), &respData); err != nil { + return nil, err + } + return &respData, nil } + return nil, respBody.Err } diff --git a/v3/client/go_client.go b/v3/client/go_client.go index 3aed2bfb..0648f79f 100644 --- a/v3/client/go_client.go +++ b/v3/client/go_client.go @@ -22,7 +22,6 @@ import ( "fmt" "log" "math/big" - "strconv" "strings" "github.com/FISCO-BCOS/go-sdk/v3/abi/bind" @@ -164,12 +163,20 @@ func (c *Client) CodeAt(ctx context.Context, address common.Address, blockNumber return js, err } -// Filters -func toBlockNumArg(number *big.Int) string { - if number == nil { - return "latest" +func (c *Client) GetABI(ctx context.Context, address common.Address) (string, error) { + req, err := c.conn.NewMessage("getABI", c.groupID, "", address.Hex()) + if err != nil { + return "", err + } + message, err := json.Marshal(req) + if err != nil { + return "", err } - return hexutil.EncodeBig(number) + response, err := c.conn.sendRPCRequest(c.groupID, "", string(message)) + if err != nil { + return "", err + } + return string(response.Result), nil } // PendingCodeAt returns the contract code of the given account in the pending state. @@ -231,15 +238,15 @@ func (c *Client) PendingCallContract(ctx context.Context, msg ethereum.CallMsg) // // If the transaction was a contract creation use the TransactionReceipt method to get the // contract address after the transaction has been mined. -func (c *Client) SendTransaction(ctx context.Context, tx *types.Transaction, contract *common.Address, input []byte) (*types.Receipt, error) { +func (c *Client) SendTransaction(ctx context.Context, tx *types.Transaction) (*types.Receipt, error) { var err error var anonymityReceipt = &struct { types.Receipt }{} - if contract != nil { - err = c.conn.CallContext(ctx, anonymityReceipt, "sendTransaction", input, strings.ToLower(contract.String())) + if tx.To() != nil { + err = c.conn.CallContext(ctx, anonymityReceipt, "sendTransaction", tx.Input(), strings.ToLower(tx.To().String())) } else { - err = c.conn.CallContext(ctx, anonymityReceipt, "sendTransaction", input, "") + err = c.conn.CallContext(ctx, anonymityReceipt, "sendTransaction", tx.Input(), "", tx.ABI()) } if err != nil { errorStr := fmt.Sprintf("%s", err) @@ -253,15 +260,15 @@ func (c *Client) SendTransaction(ctx context.Context, tx *types.Transaction, con } // AsyncSendTransaction send transaction async -func (c *Client) AsyncSendTransaction(ctx context.Context, tx *types.Transaction, contract *common.Address, input []byte, handler func(*types.Receipt, error)) error { +func (c *Client) AsyncSendTransaction(ctx context.Context, tx *types.Transaction, handler func(*types.Receipt, error)) error { var err error var anonymityReceipt = &struct { types.Receipt }{} - if contract != nil { - err = c.conn.CallContext(ctx, anonymityReceipt, "sendTransaction", input, strings.ToLower(contract.String()[2:]), handler) + if tx.To() != nil { + err = c.conn.CallContext(ctx, anonymityReceipt, "asyncSendTransaction", tx.Input(), strings.ToLower(tx.To().String()), handler) } else { - err = c.conn.CallContext(ctx, anonymityReceipt, "sendTransaction", input, "", handler) + err = c.conn.CallContext(ctx, anonymityReceipt, "asyncSendTransaction", tx.Input(), "", handler, tx.ABI()) } if err != nil { return err @@ -679,20 +686,3 @@ func (c *Client) GetSystemConfigByKey(ctx context.Context, configKey string) (*t //js, err := json.MarshalIndent(raw, "", indent) return &raw, err } - -func getVersionNumber(strVersion string) (int, error) { - strList := strings.Split(strVersion, ".") - if len(strList) != 3 { - return 0, fmt.Errorf("strList length must be 3") - } - var versionNumber int - for i := 0; i < len(strList); i++ { - num, err := strconv.Atoi(strList[i]) - if err != nil { - return 0, fmt.Errorf("getVersionNumber failed, err: %v", err) - } - versionNumber += num - versionNumber = versionNumber << 8 - } - return versionNumber, nil -} diff --git a/v3/client/go_client_test.go b/v3/client/go_client_test.go index d1bbc338..8794107f 100644 --- a/v3/client/go_client_test.go +++ b/v3/client/go_client_test.go @@ -270,12 +270,12 @@ func TestPendingTxSize(t *testing.T) { func deployHelloWorld(t *testing.T) (*common.Address, *common.Hash) { c := GetClient(t) parsed, _ := abi.JSON(strings.NewReader(HelloWorldABI)) - address, tx, _, err := bind.DeployContract(c.GetTransactOpts(), parsed, common.FromHex(HelloWorldBin), c) + address, receipt, _, err := bind.DeployContract(c.GetTransactOpts(), parsed, common.FromHex(HelloWorldBin), HelloWorldABI, c) if err != nil { t.Errorf("DeployHelloWorld failed: %v", err) return nil, nil } - txHash := common.HexToHash(tx.TransactionHash) + txHash := common.HexToHash(receipt.TransactionHash) return &address, &txHash } @@ -286,7 +286,16 @@ func TestGetCode(t *testing.T) { if err != nil { t.Fatalf("contract not found: %v", err) } - + abi, err := c.GetABI(context.Background(), *address) + if err != nil { + t.Fatalf("abi not found: %v", err) + } + abi = strings.ReplaceAll(abi, "\\", "") + abi = abi[1:] + abi = abi[:len(abi)-1] + if abi != HelloWorldABI { + t.Fatalf("abi mismatch: %s != %s", abi, HelloWorldABI) + } t.Logf("the contract code:\n%s", raw) } @@ -442,7 +451,7 @@ func TestCreateEncodedTransactionAndSend(t *testing.T) { func TestAsnycHelloWorldSet(t *testing.T) { c := GetClient(t) parsed, _ := abi.JSON(strings.NewReader(HelloWorldABI)) - address, receipt, _, err := bind.DeployContract(c.GetTransactOpts(), parsed, common.FromHex(HelloWorldBin), c) + address, receipt, _, err := bind.DeployContract(c.GetTransactOpts(), parsed, common.FromHex(HelloWorldBin), HelloWorldABI, c) if err != nil { t.Fatalf("DeployHelloWorld failed: %v", err) } @@ -456,7 +465,8 @@ func TestAsnycHelloWorldSet(t *testing.T) { var wg sync.WaitGroup count := 100 for i := 0; i < count; i++ { - err = c.AsyncSendTransaction(context.Background(), nil, &address, input, func(receipt *types.Receipt, err error) { + tx := types.NewSimpleTx(&address, input, HelloWorldABI, "", "", c.SMCrypto()) + err = c.AsyncSendTransaction(context.Background(), tx, func(receipt *types.Receipt, err error) { wg.Done() if err != nil { t.Fatalf("SendTransaction error: %v", err) @@ -476,7 +486,7 @@ func TestAsnycHelloWorldSet(t *testing.T) { func TestHelloWorldSet(t *testing.T) { c := GetClient(t) parsed, _ := abi.JSON(strings.NewReader(HelloWorldABI)) - address, receipt, _, err := bind.DeployContract(c.GetTransactOpts(), parsed, common.FromHex(HelloWorldBin), c) + address, receipt, _, err := bind.DeployContract(c.GetTransactOpts(), parsed, common.FromHex(HelloWorldBin), HelloWorldABI, c) if err != nil { t.Fatalf("DeployHelloWorld failed: %v", err) } @@ -489,7 +499,8 @@ func TestHelloWorldSet(t *testing.T) { } count := 5 for i := 0; i < count; i++ { - receipt, err = c.SendTransaction(context.Background(), nil, &address, input) + tx := types.NewSimpleTx(&address, input, HelloWorldABI, "", "", c.SMCrypto()) + receipt, err = c.SendTransaction(context.Background(), tx) if err != nil { t.Fatalf("SendTransaction error: %v", err) } @@ -502,7 +513,7 @@ func TestHelloWorldSet(t *testing.T) { func TestSetPrivateKey(t *testing.T) { c := GetClient(t) parsed, _ := abi.JSON(strings.NewReader(HelloWorldABI)) - address, receipt, _, err := bind.DeployContract(c.GetTransactOpts(), parsed, common.FromHex(HelloWorldBin), c) + address, receipt, _, err := bind.DeployContract(c.GetTransactOpts(), parsed, common.FromHex(HelloWorldBin), HelloWorldABI, c) if err != nil { t.Fatalf("DeployHelloWorld failed: %v", err) } @@ -519,7 +530,8 @@ func TestSetPrivateKey(t *testing.T) { if err != nil { t.Fatalf("parsed.Pack error: %v", err) } - receipt, err = c.SendTransaction(context.Background(), nil, &address, input) + txPointer := types.NewSimpleTx(&address, input, HelloWorldABI, "", "", c.SMCrypto()) + receipt, err = c.SendTransaction(context.Background(), txPointer) if err != nil { t.Fatalf("SendTransaction error: %v", err) } @@ -535,7 +547,8 @@ func TestSetPrivateKey(t *testing.T) { if err != nil { t.Fatalf("SetPrivateKey failed of %v", err) } - receipt, err = c.SendTransaction(context.Background(), nil, &address, input) + txPointer = types.NewSimpleTx(&address, input, HelloWorldABI, "", "", c.SMCrypto()) + receipt, err = c.SendTransaction(context.Background(), txPointer) if err != nil { t.Fatalf("SendTransaction error: %v", err) } @@ -565,7 +578,7 @@ func GetClientForBench(b *testing.B) *Client { func BenchmarkHelloWorldSet(b *testing.B) { c := GetClientForBench(b) parsed, _ := abi.JSON(strings.NewReader(HelloWorldABI)) - address, receipt, _, err := bind.DeployContract(c.GetTransactOpts(), parsed, common.FromHex(HelloWorldBin), c) + address, receipt, _, err := bind.DeployContract(c.GetTransactOpts(), parsed, common.FromHex(HelloWorldBin), HelloWorldABI, c) if err != nil { b.Fatalf("DeployHelloWorld failed: %v", err) } @@ -578,7 +591,8 @@ func BenchmarkHelloWorldSet(b *testing.B) { } b.ResetTimer() for i := 0; i < b.N; i++ { - receipt, err = c.SendTransaction(context.Background(), nil, &address, input) + txPointer := types.NewSimpleTx(&address, input, HelloWorldABI, "", "", c.SMCrypto()) + receipt, err = c.SendTransaction(context.Background(), txPointer) if err != nil { b.Fatalf("SendTransaction error: %v", err) } @@ -591,7 +605,7 @@ func BenchmarkHelloWorldSet(b *testing.B) { func BenchmarkAsyncHelloWorldSet(b *testing.B) { c := GetClientForBench(b) parsed, _ := abi.JSON(strings.NewReader(HelloWorldABI)) - address, receipt, _, err := bind.DeployContract(c.GetTransactOpts(), parsed, common.FromHex(HelloWorldBin), c) + address, receipt, _, err := bind.DeployContract(c.GetTransactOpts(), parsed, common.FromHex(HelloWorldBin), HelloWorldABI, c) if err != nil { b.Fatalf("DeployHelloWorld failed: %v", err) } @@ -605,7 +619,8 @@ func BenchmarkAsyncHelloWorldSet(b *testing.B) { if err != nil { b.Fatalf("parsed.Pack error: %v", err) } - err = c.AsyncSendTransaction(context.Background(), nil, &address, input, func(receipt *types.Receipt, err error) { + txPointer := types.NewSimpleTx(&address, input, HelloWorldABI, "", "", c.SMCrypto()) + err = c.AsyncSendTransaction(context.Background(), txPointer, func(receipt *types.Receipt, err error) { wg.Done() if err != nil { b.Fatalf("SendTransaction error: %v", err) diff --git a/v3/cmd/commandline/auth_manager.go b/v3/cmd/commandline/auth_manager.go index e0dee7e3..e0fcc52a 100644 --- a/v3/cmd/commandline/auth_manager.go +++ b/v3/cmd/commandline/auth_manager.go @@ -58,7 +58,7 @@ For more information please refer: Run: func(cmd *cobra.Command, args []string) { accountAddress := args[0] if !IsValidAccount(accountAddress) { - fmt.Printf("the format of accountAddress %v is unvalid\n", accountAddress) + fmt.Printf("the format of accountAddress %v is invalid\n", accountAddress) return } @@ -87,7 +87,7 @@ Arguments: For example: - [checkMethodAuth] [0x112fb844934c794a9e425dd6b4e57eff1b519f17][c53057b4][0x112fb844934c794a9e425dd6b4e57eff1b519f17] + [checkMethodAuth] 0x112fb844934c794a9e425dd6b4e57eff1b519f17 c53057b4 0x112fb844934c794a9e425dd6b4e57eff1b519f17 For more information please refer: @@ -96,18 +96,18 @@ For more information please refer: Run: func(cmd *cobra.Command, args []string) { contractAddr := args[0] if !IsValidAccount(contractAddr) { - fmt.Printf("the format of contractAddr %v is unvalid\n", contractAddr) + fmt.Printf("the format of contractAddr %v is invalid\n", contractAddr) return } funcSelectorStr := args[1] funcByte, err := hex.DecodeString(funcSelectorStr) if err != nil { - fmt.Printf("the format of funcSelector %v is unvalid , hex decode err\n", funcSelectorStr) + fmt.Printf("the format of funcSelector %v is invalid , hex decode err\n", funcSelectorStr) return } if len(funcByte) != 4 { - fmt.Printf("the format of funcSelector %v is unvalid\n", funcSelectorStr) + fmt.Printf("the format of funcSelector %v is invalid\n", funcSelectorStr) return } @@ -119,7 +119,7 @@ For more information please refer: accountAddress := args[2] if !IsValidAccount(accountAddress) { - fmt.Printf("the format of accountAddress %v is unvalid\n", accountAddress) + fmt.Printf("the format of accountAddress %v is invalid\n", accountAddress) return } @@ -155,7 +155,7 @@ For more information please refer: Run: func(cmd *cobra.Command, args []string) { contractAddr := args[0] if !IsValidAccount(contractAddr) { - fmt.Printf("the format of contractAddr %v is unvalid\n", contractAddr) + fmt.Printf("the format of contractAddr %v is invalid\n", contractAddr) return } @@ -192,12 +192,12 @@ For more information please refer: Run: func(cmd *cobra.Command, args []string) { newAdmin := args[0] if !IsValidAccount(newAdmin) { - fmt.Printf("the format of newAdmin %v is unvalid\n", newAdmin) + fmt.Printf("the format of newAdmin %v is invalid\n", newAdmin) return } contractAddr := args[1] if !IsValidAccount(contractAddr) { - fmt.Printf("the format of contractAddr %v is unvalid\n", contractAddr) + fmt.Printf("the format of contractAddr %v is invalid\n", contractAddr) return } @@ -234,7 +234,7 @@ For more information please refer: Run: func(cmd *cobra.Command, args []string) { accountAddress := args[0] if !IsValidAccount(accountAddress) { - fmt.Printf("the format of accountAddress %v is unvalid\n", accountAddress) + fmt.Printf("the format of accountAddress %v is invalid\n", accountAddress) return } @@ -375,7 +375,7 @@ For more information please refer: Run: func(cmd *cobra.Command, args []string) { accountAddress := args[0] if !IsValidAccount(accountAddress) { - fmt.Printf("the format of accountAddress %v is unvalid\n", accountAddress) + fmt.Printf("the format of accountAddress %v is invalid\n", accountAddress) return } @@ -498,18 +498,18 @@ For more information please refer: Run: func(cmd *cobra.Command, args []string) { accountAddress := args[0] if !IsValidAccount(accountAddress) { - fmt.Printf("the format of accountAddress %v is unvalid\n", accountAddress) + fmt.Printf("the format of accountAddress %v is invalid\n", accountAddress) return } funcSelectorStr := args[1] funcByte, err := hex.DecodeString(funcSelectorStr) if err != nil { - fmt.Printf("the format of funcSelector %v is unvalid , hex decode err\n", funcSelectorStr) + fmt.Printf("the format of funcSelector %v is invalid , hex decode err\n", funcSelectorStr) return } if len(funcByte) != 4 { - fmt.Printf("the format of funcSelector %v is unvalid\n", funcSelectorStr) + fmt.Printf("the format of funcSelector %v is invalid\n", funcSelectorStr) return } @@ -565,18 +565,18 @@ For more information please refer: Run: func(cmd *cobra.Command, args []string) { contractAddr := args[0] if !IsValidAccount(contractAddr) { - fmt.Printf("the format of contractAddr %v is unvalid\n", contractAddr) + fmt.Printf("the format of contractAddr %v is invalid\n", contractAddr) return } funcSelectorStr := args[1] funcByte, err := hex.DecodeString(funcSelectorStr) if err != nil { - fmt.Printf("the format of funcSelector %v is unvalid , hex decode err\n", funcSelectorStr) + fmt.Printf("the format of funcSelector %v is invalid , hex decode err\n", funcSelectorStr) return } if len(funcByte) != 4 { - fmt.Printf("the format of funcSelector %v is unvalid\n", funcSelectorStr) + fmt.Printf("the format of funcSelector %v is invalid\n", funcSelectorStr) return } @@ -588,7 +588,7 @@ For more information please refer: accountAddr := args[2] if !IsValidAccount(accountAddr) { - fmt.Printf("the format of accountAddr %v is unvalid\n", accountAddr) + fmt.Printf("the format of accountAddr %v is invalid\n", accountAddr) return } diff --git a/v3/cmd/commandline/commands.go b/v3/cmd/commandline/commands.go index b054ea95..1c2b5518 100644 --- a/v3/cmd/commandline/commands.go +++ b/v3/cmd/commandline/commands.go @@ -544,6 +544,38 @@ For more information please refer: }, } +var getABICmd = &cobra.Command{ + Use: "getABI", + Short: "[contract address] Get the contract data from contract address", + Long: `Return contract data queried according to contract address. +Arguments: +[contract address]: contract hash string. + +For example: + + getABI 0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b + +For more information please refer: + + https://fisco-bcos-documentation.readthedocs.io/zh_CN/latest/docs/api.html#`, + Args: cobra.ExactArgs(1), + Run: func(cmd *cobra.Command, args []string) { + _, err := isValidHex(args[0]) + if err != nil { + fmt.Println(err) + return + } + + contractAdd := common.HexToAddress(args[0]) + abi, err := RPC.GetABI(context.Background(), contractAdd) + if err != nil { + fmt.Printf("This address does not exist: %v\n", err) + return + } + fmt.Printf("Contract Code: \n%s\n", abi) + }, +} + var getTotalTransactionCountCmd = &cobra.Command{ Use: "getTotalTransactionCount", Short: " Get the total transactions and the latest block height", @@ -666,7 +698,7 @@ func init() { // add transaction/receipt command rootCmd.AddCommand(getTransactionByHashCmd, getTransactionReceiptCmd, getPendingTxSizeCmd) // add contract command - rootCmd.AddCommand(getCodeCmd, getTotalTransactionCountCmd, getSystemConfigByKeyCmd) + rootCmd.AddCommand(getCodeCmd, getABICmd, getTotalTransactionCountCmd, getSystemConfigByKeyCmd) // add contract command // cobra.OnInitialize(initConfig) diff --git a/v3/cmd/commandline/system_config.go b/v3/cmd/commandline/system_config.go index 4e8ab391..9c8d58b8 100644 --- a/v3/cmd/commandline/system_config.go +++ b/v3/cmd/commandline/system_config.go @@ -4,46 +4,42 @@ import ( "fmt" "github.com/FISCO-BCOS/go-sdk/v3/precompiled/config" + mapset "github.com/deckarep/golang-set/v2" "github.com/spf13/cobra" ) +var configSet = mapset.NewSet[string]("tx_count_limit", "tx_gas_limit", "consensus_leader_period", "rpbft_epoch_block_num", "auth_check_status", "compatibility_version", "feature_rpbft_epoch_sealer_num", "feature_rpbft_epoch_block_num", "feature_rpbft", "feature_balance_precompiled", "feature_rpbft_notify_rotate") + var setSystemConfigByKey = &cobra.Command{ Use: "setSystemConfigByKey", Short: "[system_configuration_item] Set the system configuration through key-value", - Long: `Returns the system configuration through key-value. + Long: fmt.Sprintf(`Returns the system configuration through key-value. Arguments: - [key]: currently only support four key: "tx_count_limit", "tx_gas_limit", "rpbft_epoch_sealer_num", "rpbft_epoch_block_num", "consensus_timeout". + [key]: currently only support four key: %s. [key value]: the value of corresponding key. For example: - - [setSystemConfigByKey] [tx_count_limit] 10000`, + setSystemConfigByKey tx_count_limit 10000`, configSet.String()), Args: cobra.ExactArgs(2), Run: func(cmd *cobra.Command, args []string) { - //configMap := make(map[string]struct{}) - //configMap["tx_count_limit"] = struct{}{} - //configMap["tx_gas_limit"] = struct{}{} - //configMap["rpbft_epoch_sealer_num"] = struct{}{} - //configMap["rpbft_epoch_block_num"] = struct{}{} - //configMap["consensus_timeout"] = struct{}{} - //if _, ok := configMap[args[0]]; !ok { - // fmt.Println("The key not found: ", args[0], ", currently only support [tx_count_limit], [tx_gas_limit], [rpbft_epoch_sealer_num], [rpbft_epoch_block_num] and [consensus_timeout]") - // return - //} + if configSet.Contains(args[0]) { + fmt.Printf("The key not found: %s, currently only support %v", args[0], configSet) + return + } key := args[0] value := args[1] sysConfig, err := config.NewSystemConfigService(RPC) if err != nil { - fmt.Printf("setSystemConfigByKeyCmd failed, config.NewSystemConfigService err: %v\n", err) + fmt.Printf("setSystemConfigByKey failed, config.NewSystemConfigService err: %v\n", err) return } result, err := sysConfig.SetValueByKey(key, value) if err != nil { - fmt.Printf("setSystemConfigByKeyCmd failed, sysConfig.SetValueByKey err: %v\n", err) + fmt.Printf("setSystemConfigByKey failed, sysConfig.SetValueByKey err: %v\n", err) return } if result != 0 { - fmt.Printf("setSystemConfigByKeyCmd failed, the result is: %v", result) + fmt.Printf("setSystemConfigByKey failed, the result is: %v", result) return } fmt.Println("success") diff --git a/v3/examples/KVTableTest.go b/v3/examples/KVTableTest.go index c201da6c..d4f6149f 100644 --- a/v3/examples/KVTableTest.go +++ b/v3/examples/KVTableTest.go @@ -37,7 +37,7 @@ func DeployKVTableTest(auth *bind.TransactOpts, backend bind.ContractBackend) (c return common.Address{}, nil, nil, err } - address, receipt, contract, err := bind.DeployContract(auth, parsed, common.FromHex(KVTableTestBin), backend) + address, receipt, contract, err := bind.DeployContract(auth, parsed, common.FromHex(KVTableTestBin), KVTableTestABI, backend) if err != nil { return common.Address{}, nil, nil, err } @@ -50,7 +50,7 @@ func AsyncDeployKVTableTest(auth *bind.TransactOpts, handler func(*types.Receipt return nil, err } - tx, err := bind.AsyncDeployContract(auth, handler, parsed, common.FromHex(KVTableTestBin), backend) + tx, err := bind.AsyncDeployContract(auth, handler, parsed, common.FromHex(KVTableTestBin), KVTableTestABI, backend) if err != nil { return nil, err } diff --git a/v3/examples/hello_world/wrapper/HelloWorld.go b/v3/examples/hello_world/wrapper/HelloWorld.go index 7a48b946..e9cb67d5 100644 --- a/v3/examples/hello_world/wrapper/HelloWorld.go +++ b/v3/examples/hello_world/wrapper/HelloWorld.go @@ -45,7 +45,7 @@ func DeployHelloWorld(auth *bind.TransactOpts, backend bind.ContractBackend, ini } else { bytecode = common.FromHex(HelloWorldBin) } - address, receipt, contract, err := bind.DeployContract(auth, parsed, bytecode, backend, initValue) + address, receipt, contract, err := bind.DeployContract(auth, parsed, bytecode, HelloWorldABI, backend, initValue) if err != nil { return common.Address{}, nil, nil, err } @@ -63,7 +63,7 @@ func AsyncDeployHelloWorld(auth *bind.TransactOpts, handler func(*types.Receipt, } else { bytecode = common.FromHex(HelloWorldBin) } - tx, err := bind.AsyncDeployContract(auth, handler, parsed, bytecode, backend, initValue) + tx, err := bind.AsyncDeployContract(auth, handler, parsed, bytecode, HelloWorldABI, backend, initValue) if err != nil { return nil, err } diff --git a/v3/examples/parallelok/main.go b/v3/examples/parallelok/main.go index 4a629c9f..4f37640e 100644 --- a/v3/examples/parallelok/main.go +++ b/v3/examples/parallelok/main.go @@ -39,7 +39,7 @@ func main() { fmt.Println("start perf groupID:", groupID, "userCount:", userCount, "total:", total, "qps:", qps) privateKey, _ := hex.DecodeString("145e247e170ba3afd6ae97e88f00dbc976c2345d511b0f6713355d19d8b80b58") - config := &client.Config{IsSMCrypto: false, GroupID: groupID, DisableSsl: false, + config := &client.Config{IsSMCrypto: false, GroupID: groupID, DisableSsl: true, PrivateKey: privateKey, Host: "127.0.0.1", Port: 20200, TLSCaFile: "./conf/ca.crt", TLSKeyFile: "./conf/sdk.key", TLSCertFile: "./conf/sdk.crt"} client, err := client.DialContext(context.Background(), config) // client, err := client.Dial("./config.ini", groupID, privateKey) diff --git a/v3/examples/parallelok/parallelOk.go b/v3/examples/parallelok/parallelOk.go index 671ab990..6263a98d 100644 --- a/v3/examples/parallelok/parallelOk.go +++ b/v3/examples/parallelok/parallelOk.go @@ -48,7 +48,7 @@ func DeployTransfer(auth *bind.TransactOpts, backend bind.ContractBackend) (comm if len(bytecode) == 0 { return common.Address{}, nil, nil, fmt.Errorf("cannot deploy empty bytecode") } - address, receipt, contract, err := bind.DeployContract(auth, parsed, bytecode, backend) + address, receipt, contract, err := bind.DeployContract(auth, parsed, bytecode, TransferABI, backend) if err != nil { return common.Address{}, nil, nil, err } @@ -70,7 +70,7 @@ func AsyncDeployTransfer(auth *bind.TransactOpts, handler func(*types.Receipt, e if len(bytecode) == 0 { return nil, fmt.Errorf("cannot deploy empty bytecode") } - tx, err := bind.AsyncDeployContract(auth, handler, parsed, bytecode, backend) + tx, err := bind.AsyncDeployContract(auth, handler, parsed, bytecode, TransferABI, backend) if err != nil { return nil, err } diff --git a/v3/go.mod b/v3/go.mod index bbeac5f6..23812562 100644 --- a/v3/go.mod +++ b/v3/go.mod @@ -3,14 +3,15 @@ module github.com/FISCO-BCOS/go-sdk/v3 go 1.21.5 replace ( - // github.com/FISCO-BCOS/bcos-c-sdk v0.0.0-20231221132830-c0cfb1d98eec => ../../bcos-c-sdk + // github.com/FISCO-BCOS/bcos-c-sdk v0.0.0-20240105080731-14b9b42a47a9 => ../../bcos-c-sdk golang.org/x/net => github.com/golang/net v0.0.0-20190415214537-1da14a5a36f2 golang.org/x/sync => github.com/golang/sync v0.0.0-20190412183630-56d357773e84 ) require ( - github.com/FISCO-BCOS/bcos-c-sdk v0.0.0-20231221132830-c0cfb1d98eec + github.com/FISCO-BCOS/bcos-c-sdk v0.0.0-20240105080731-14b9b42a47a9 github.com/FISCO-BCOS/crypto v0.0.0-20200202032121-bd8ab0b5d4f1 + github.com/deckarep/golang-set/v2 v2.6.0 github.com/ethereum/go-ethereum v1.10.21 github.com/schollz/progressbar/v3 v3.14.1 github.com/sirupsen/logrus v1.8.1 diff --git a/v3/go.sum b/v3/go.sum index 11236e83..47b7d609 100644 --- a/v3/go.sum +++ b/v3/go.sum @@ -21,8 +21,8 @@ dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7 github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/DATA-DOG/go-sqlmock v1.3.3/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM= -github.com/FISCO-BCOS/bcos-c-sdk v0.0.0-20231221132830-c0cfb1d98eec h1:flo/0fBn5dYHy41gIPZNiiFVN/Fc5KfnfQStgYOuiCI= -github.com/FISCO-BCOS/bcos-c-sdk v0.0.0-20231221132830-c0cfb1d98eec/go.mod h1:7kTVptunvfx0JH/XIuFj0ybRq0MLAsK4daizrE9RvN0= +github.com/FISCO-BCOS/bcos-c-sdk v0.0.0-20240105080731-14b9b42a47a9 h1:7nDyMqU60RVTdEfpaQy5d+JCzERuXOnzrYngs/434J0= +github.com/FISCO-BCOS/bcos-c-sdk v0.0.0-20240105080731-14b9b42a47a9/go.mod h1:n2KxbYa73MW3xdLVu2vpPpoblZMms+CwPmvFkubO9xM= github.com/FISCO-BCOS/crypto v0.0.0-20200202032121-bd8ab0b5d4f1 h1:ThPht4qK10+cMZC5COIjHPq0INm5HAMVYqrez5zEgFI= github.com/FISCO-BCOS/crypto v0.0.0-20200202032121-bd8ab0b5d4f1/go.mod h1:UrLdwsFrjiaCsvdcPLcH6B7s/FUmym3qfM93u2ziR+4= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= @@ -73,6 +73,8 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/deckarep/golang-set v1.8.0 h1:sk9/l/KqpunDwP7pSjUg0keiOOLEnOBHzykLrsPppp4= github.com/deckarep/golang-set v1.8.0/go.mod h1:5nI87KwE7wgsBU1F4GKAw2Qod7p5kyS383rP6+o6qqo= +github.com/deckarep/golang-set/v2 v2.6.0 h1:XfcQbWM1LlMB8BsJ8N9vW5ehnnPVIw0je80NsVHagjM= +github.com/deckarep/golang-set/v2 v2.6.0/go.mod h1:VAky9rY/yGXJOLEDv3OMci+7wtDpOF4IN+y82NBOac4= github.com/decred/dcrd/crypto/blake256 v1.0.0 h1:/8DMNYp9SGi5f0w7uCm6d6M4OU2rGFK09Y2A4Xv7EE0= github.com/decred/dcrd/crypto/blake256 v1.0.0/go.mod h1:sQl2p6Y26YV+ZOcSTP6thNdn47hh8kt6rqSlvmrXFAc= github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1 h1:YLtO71vCjJRCBcrPMtQ9nqBsqpA1m5sE92cU+pd5Mcc= diff --git a/v3/ios/contract_proxy.go b/v3/ios/contract_proxy.go index 423fa128..e76d4ba2 100644 --- a/v3/ios/contract_proxy.go +++ b/v3/ios/contract_proxy.go @@ -27,7 +27,7 @@ type ContractProxy struct { chainID string smCrypto bool callback PostCallback - idCounter uint32 + idCounter uint64 } // CodeAt returns the code of the given account. This is needed to differentiate @@ -185,7 +185,7 @@ func (c *ContractProxy) UnSubscribeEventLogs(ctx context.Context, filterID strin } func (c *ContractProxy) nextID() json.RawMessage { - id := atomic.AddUint32(&c.idCounter, 1) + id := atomic.AddUint64(&c.idCounter, 1) return strconv.AppendUint(nil, uint64(id), 10) } func (c *ContractProxy) newMessage(method string, paramsIn ...interface{}) (*jsonrpcMessage, error) { diff --git a/v3/precompiled/auth/Committee.go b/v3/precompiled/auth/Committee.go index 3cc63dbe..e5ac0023 100644 --- a/v3/precompiled/auth/Committee.go +++ b/v3/precompiled/auth/Committee.go @@ -37,7 +37,7 @@ func DeployCommittee(auth *bind.TransactOpts, backend bind.ContractBackend, gove return common.Address{}, nil, nil, err } - address, receipt, contract, err := bind.DeployContract(auth, parsed, common.FromHex(CommitteeBin), backend, governorList, weightList, participatesRate, winRate) + address, receipt, contract, err := bind.DeployContract(auth, parsed, common.FromHex(CommitteeBin), CommitteeABI, backend, governorList, weightList, participatesRate, winRate) if err != nil { return common.Address{}, nil, nil, err } @@ -50,7 +50,7 @@ func AsyncDeployCommittee(auth *bind.TransactOpts, handler func(*types.Receipt, return nil, err } - tx, err := bind.AsyncDeployContract(auth, handler, parsed, common.FromHex(CommitteeBin), backend, governorList, weightList, participatesRate, winRate) + tx, err := bind.AsyncDeployContract(auth, handler, parsed, common.FromHex(CommitteeBin), CommitteeABI, backend, governorList, weightList, participatesRate, winRate) if err != nil { return nil, err } diff --git a/v3/precompiled/auth/CommitteeManager.go b/v3/precompiled/auth/CommitteeManager.go index 60f25ec0..8998987e 100644 --- a/v3/precompiled/auth/CommitteeManager.go +++ b/v3/precompiled/auth/CommitteeManager.go @@ -37,7 +37,7 @@ func DeployCommitteeManager(auth *bind.TransactOpts, backend bind.ContractBacken return common.Address{}, nil, nil, err } - address, receipt, contract, err := bind.DeployContract(auth, parsed, common.FromHex(CommitteeManagerBin), backend, initGovernors, weights, participatesRate, winRate) + address, receipt, contract, err := bind.DeployContract(auth, parsed, common.FromHex(CommitteeManagerBin), CommitteeManagerABI, backend, initGovernors, weights, participatesRate, winRate) if err != nil { return common.Address{}, nil, nil, err } @@ -50,7 +50,7 @@ func AsyncDeployCommitteeManager(auth *bind.TransactOpts, handler func(*types.Re return nil, err } - tx, err := bind.AsyncDeployContract(auth, handler, parsed, common.FromHex(CommitteeManagerBin), backend, initGovernors, weights, participatesRate, winRate) + tx, err := bind.AsyncDeployContract(auth, handler, parsed, common.FromHex(CommitteeManagerBin), CommitteeManagerABI, backend, initGovernors, weights, participatesRate, winRate) if err != nil { return nil, err } diff --git a/v3/precompiled/auth/ContractAuthPrecompiled.go b/v3/precompiled/auth/ContractAuthPrecompiled.go index 3e30d5de..66fe88a0 100644 --- a/v3/precompiled/auth/ContractAuthPrecompiled.go +++ b/v3/precompiled/auth/ContractAuthPrecompiled.go @@ -37,7 +37,7 @@ func DeployContractAuthPrecompiled(auth *bind.TransactOpts, backend bind.Contrac return common.Address{}, nil, nil, err } - address, receipt, contract, err := bind.DeployContract(auth, parsed, common.FromHex(ContractAuthPrecompiledBin), backend) + address, receipt, contract, err := bind.DeployContract(auth, parsed, common.FromHex(ContractAuthPrecompiledBin), ContractAuthPrecompiledABI, backend) if err != nil { return common.Address{}, nil, nil, err } @@ -50,7 +50,7 @@ func AsyncDeployContractAuthPrecompiled(auth *bind.TransactOpts, handler func(*t return nil, err } - tx, err := bind.AsyncDeployContract(auth, handler, parsed, common.FromHex(ContractAuthPrecompiledBin), backend) + tx, err := bind.AsyncDeployContract(auth, handler, parsed, common.FromHex(ContractAuthPrecompiledBin), ContractAuthPrecompiledABI, backend) if err != nil { return nil, err } diff --git a/v3/precompiled/auth/ProposalManager.go b/v3/precompiled/auth/ProposalManager.go index 7d3609cb..0eac56ca 100644 --- a/v3/precompiled/auth/ProposalManager.go +++ b/v3/precompiled/auth/ProposalManager.go @@ -48,7 +48,7 @@ func DeployProposalManager(auth *bind.TransactOpts, backend bind.ContractBackend return common.Address{}, nil, nil, err } - address, receipt, contract, err := bind.DeployContract(auth, parsed, common.FromHex(ProposalManagerBin), backend, committeeMgrAddress, committeeAddress) + address, receipt, contract, err := bind.DeployContract(auth, parsed, common.FromHex(ProposalManagerBin), ProposalManagerABI, backend, committeeMgrAddress, committeeAddress) if err != nil { return common.Address{}, nil, nil, err } @@ -61,7 +61,7 @@ func AsyncDeployProposalManager(auth *bind.TransactOpts, handler func(*types.Rec return nil, err } - tx, err := bind.AsyncDeployContract(auth, handler, parsed, common.FromHex(ProposalManagerBin), backend, committeeMgrAddress, committeeAddress) + tx, err := bind.AsyncDeployContract(auth, handler, parsed, common.FromHex(ProposalManagerBin), ProposalManagerABI, backend, committeeMgrAddress, committeeAddress) if err != nil { return nil, err } diff --git a/v3/precompiled/auth/auth_manager_service.go b/v3/precompiled/auth/auth_manager_service.go index dbc24a16..911ac840 100644 --- a/v3/precompiled/auth/auth_manager_service.go +++ b/v3/precompiled/auth/auth_manager_service.go @@ -39,6 +39,12 @@ type AuthManagerService struct { proposalManager *ProposalManager } +const ( + ACCOUNT_STATUS_NORMAL = iota + ACCOUNT_STATUS_FREEZE + ACCOUNT_STATUS_ABOLISH +) + var committeeManagerAddress = common.HexToAddress("0000000000000000000000000000000000010001") var accountManagerAddress = common.HexToAddress("0000000000000000000000000000000000010003") diff --git a/v3/precompiled/sharding/sharding.go b/v3/precompiled/sharding/sharding.go index 1f95a241..1c6d058d 100644 --- a/v3/precompiled/sharding/sharding.go +++ b/v3/precompiled/sharding/sharding.go @@ -37,7 +37,7 @@ func DeploySharding(auth *bind.TransactOpts, backend bind.ContractBackend) (comm return common.Address{}, nil, nil, err } - address, receipt, contract, err := bind.DeployContract(auth, parsed, common.FromHex(ShardingBin), backend) + address, receipt, contract, err := bind.DeployContract(auth, parsed, common.FromHex(ShardingBin), ShardingABI, backend) if err != nil { return common.Address{}, nil, nil, err } @@ -50,7 +50,7 @@ func AsyncDeploySharding(auth *bind.TransactOpts, handler func(*types.Receipt, e return nil, err } - tx, err := bind.AsyncDeployContract(auth, handler, parsed, common.FromHex(ShardingBin), backend) + tx, err := bind.AsyncDeployContract(auth, handler, parsed, common.FromHex(ShardingBin), ShardingABI, backend) if err != nil { return nil, err } diff --git a/v3/test/performanceTest/contract/kvTableTest/KVTableTest.go b/v3/test/performanceTest/contract/kvTableTest/KVTableTest.go index 2e5ce12d..dc9f2b77 100644 --- a/v3/test/performanceTest/contract/kvTableTest/KVTableTest.go +++ b/v3/test/performanceTest/contract/kvTableTest/KVTableTest.go @@ -37,7 +37,7 @@ func DeployKVTableTest(auth *bind.TransactOpts, backend bind.ContractBackend) (c return common.Address{}, nil, nil, err } - address, receipt, contract, err := bind.DeployContract(auth, parsed, common.FromHex(KVTableTestBin), backend) + address, receipt, contract, err := bind.DeployContract(auth, parsed, common.FromHex(KVTableTestBin), KVTableTestABI, backend) if err != nil { return common.Address{}, nil, nil, err } @@ -50,7 +50,7 @@ func AsyncDeployKVTableTest(auth *bind.TransactOpts, handler func(*types.Receipt return nil, err } - tx, err := bind.AsyncDeployContract(auth, handler, parsed, common.FromHex(KVTableTestBin), backend) + tx, err := bind.AsyncDeployContract(auth, handler, parsed, common.FromHex(KVTableTestBin), KVTableTestABI, backend) if err != nil { return nil, err } diff --git a/v3/test/performanceTest/contract/parallelOk/ParallelOk.go b/v3/test/performanceTest/contract/parallelOk/ParallelOk.go index 30e35af2..ba0df534 100644 --- a/v3/test/performanceTest/contract/parallelOk/ParallelOk.go +++ b/v3/test/performanceTest/contract/parallelOk/ParallelOk.go @@ -37,7 +37,7 @@ func DeployParallelOk(auth *bind.TransactOpts, backend bind.ContractBackend) (co return common.Address{}, nil, nil, err } - address, receipt, contract, err := bind.DeployContract(auth, parsed, common.FromHex(ParallelOkBin), backend) + address, receipt, contract, err := bind.DeployContract(auth, parsed, common.FromHex(ParallelOkBin), ParallelOkABI, backend) if err != nil { return common.Address{}, nil, nil, err } @@ -50,7 +50,7 @@ func AsyncDeployParallelOk(auth *bind.TransactOpts, handler func(*types.Receipt, return nil, err } - tx, err := bind.AsyncDeployContract(auth, handler, parsed, common.FromHex(ParallelOkBin), backend) + tx, err := bind.AsyncDeployContract(auth, handler, parsed, common.FromHex(ParallelOkBin), ParallelOkABI, backend) if err != nil { return nil, err } diff --git a/v3/types/transaction.go b/v3/types/transaction.go index ea7a66f1..373e485a 100644 --- a/v3/types/transaction.go +++ b/v3/types/transaction.go @@ -4,13 +4,10 @@ import ( "bytes" "errors" "fmt" - "io" "math/big" - "sync/atomic" "github.com/FISCO-BCOS/go-sdk/v3/smcrypto/sm3" "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/rlp" "golang.org/x/crypto/sha3" ) @@ -20,92 +17,94 @@ var ( ) type Transaction struct { - data txdata - // caches - hash atomic.Value - size atomic.Value - from atomic.Value - smcrypto bool -} - -type txdata struct { - AccountNonce *big.Int `json:"nonce" gencodec:"required"` - Price *big.Int `json:"gasPrice" gencodec:"required"` - GasLimit *big.Int `json:"gas" gencodec:"required"` - BlockLimit *big.Int `json:"blocklimit" gencodec:"required"` - Recipient *common.Address `json:"to" rlp:"nil"` // nil means contract creation - Amount *big.Int `json:"value" gencodec:"required"` - Payload []byte `json:"input" gencodec:"required"` - // for fisco bcos 2.0 - ChainID *big.Int `json:"chainId" gencodec:"required"` - GroupID *big.Int `json:"groupId" gencodec:"required"` - ExtraData []byte `json:"extraData" gencodec:"required"` // rlp:"nil" + Data transactionData + DataHash *common.Hash `json:"dataHash"` + Signature []byte `json:"signature"` + ImportTime int64 `json:"importTime"` + Attribute int `json:"attribute"` + Sender *common.Address `json:"sender"` // nil means contract creation + ExtraData string `json:"extraData"` + SMCrypto bool `json:"-"` // Signature values - V *big.Int `json:"v" gencodec:"required"` - R *big.Int `json:"r" gencodec:"required"` - S *big.Int `json:"s" gencodec:"required"` + V *big.Int `json:"v"` + R *big.Int `json:"r"` + S *big.Int `json:"s"` +} - // This is only used when marshaling to JSON. - Hash *common.Hash `json:"hash" rlp:"-"` +type transactionData struct { + Version int32 `json:"version"` + ChainID string `json:"chainID"` + GroupID string `json:"groupID"` + BlockLimit int64 `json:"blockLimit"` + Nonce string `json:"nonce"` + To *common.Address `json:"to"` // nil means contract creation + Input []byte `json:"input"` + Abi string `json:"abi"` + Value *big.Int `json:"value"` + GasPrice *big.Int `json:"gasPrice"` + GasLimit int64 `json:"gasLimit"` + MaxFeePerGas *big.Int `json:"maxFeePerGas"` + MaxPriorityFeePerGas *big.Int `json:"maxPriorityFeePerGas"` } // NewTransaction returns a new transaction -func NewTransaction(nonce *big.Int, to common.Address, amount *big.Int, gasLimit *big.Int, gasPrice *big.Int, blockLimit *big.Int, data []byte, chainId *big.Int, groupId *big.Int, extraData []byte, smcrypto bool) *Transaction { - return newTransaction(nonce, &to, amount, gasLimit, gasPrice, blockLimit, data, chainId, groupId, extraData, smcrypto) +func NewTransaction(to common.Address, amount *big.Int, gasLimit int64, gasPrice *big.Int, blockLimit int64, data []byte, nonce, chainId, groupId, extraData string, smcrypto bool) *Transaction { + return newTransaction(&to, amount, gasLimit, gasPrice, blockLimit, data, nonce, chainId, groupId, extraData, smcrypto) } // NewContractCreation creates a contract transaction -func NewContractCreation(nonce *big.Int, amount *big.Int, gasLimit *big.Int, gasPrice *big.Int, blockLimit *big.Int, data []byte, chainId *big.Int, groupId *big.Int, extraData []byte, smcrypto bool) *Transaction { - return newTransaction(nonce, nil, amount, gasLimit, gasPrice, blockLimit, data, chainId, groupId, extraData, smcrypto) +func NewContractCreation(amount *big.Int, gasLimit int64, blockLimit int64, data []byte, nonce, chainId, groupId, extraData string, smcrypto bool) *Transaction { + return newTransaction(nil, amount, gasLimit, nil, blockLimit, data, nonce, chainId, groupId, extraData, smcrypto) } -func newTransaction(nonce *big.Int, to *common.Address, amount *big.Int, gasLimit *big.Int, gasPrice *big.Int, blockLimit *big.Int, data []byte, chainId *big.Int, groupId *big.Int, extraData []byte, smcrypto bool) *Transaction { +// NewSimpleTx creates a contract transaction, if nonce is empty string, the nonce will be auto generated +func NewSimpleTx(to *common.Address, data []byte, abi, nonce, extraData string, smcrypto bool) *Transaction { if len(data) > 0 { data = common.CopyBytes(data) } - d := txdata{ - AccountNonce: nonce, - Recipient: to, - Payload: data, - Amount: new(big.Int), - GasLimit: gasLimit, - BlockLimit: blockLimit, - Price: new(big.Int), - ChainID: new(big.Int), - GroupID: new(big.Int), - ExtraData: extraData, - V: new(big.Int), - R: new(big.Int), - S: new(big.Int), + d := transactionData{ + To: to, + Input: data, + Abi: abi, + Nonce: nonce, } - if amount != nil { - d.Amount.Set(amount) - } - if gasPrice != nil { - d.Price.Set(gasPrice) + return &Transaction{Data: d, SMCrypto: smcrypto, ExtraData: extraData} +} + +func newTransaction(to *common.Address, amount *big.Int, gasLimit int64, gasPrice *big.Int, blockLimit int64, data []byte, nonce, chainId, groupId string, extraData string, smcrypto bool) *Transaction { + if len(data) > 0 { + data = common.CopyBytes(data) } - if chainId != nil { - d.ChainID.Set(chainId) + d := transactionData{ + Nonce: nonce, + To: to, + Input: data, + Value: new(big.Int), + GasLimit: gasLimit, + BlockLimit: blockLimit, + GasPrice: new(big.Int), + ChainID: chainId, + GroupID: groupId, } - if groupId != nil { - d.GroupID.Set(groupId) + if amount != nil { + d.Value.Set(amount) } - if extraData != nil { - d.ExtraData = extraData + if gasPrice != nil { + d.GasPrice.Set(gasPrice) } - return &Transaction{data: d, smcrypto: smcrypto} + return &Transaction{Data: d, SMCrypto: smcrypto, ExtraData: extraData} } // ChainID returns which chain id this transaction was signed for (if at all) func (tx *Transaction) ChainID() *big.Int { - return deriveChainID(tx.data.V) + return deriveChainID(tx.V) } // Protected returns whether the transaction is protected from replay protection. func (tx *Transaction) Protected() bool { - return isProtectedV(tx.data.V) + return isProtectedV(tx.V) } func isProtectedV(V *big.Int) bool { @@ -117,50 +116,34 @@ func isProtectedV(V *big.Int) bool { return true } -// EncodeRLP implements rlp.Encoder -func (tx *Transaction) EncodeRLP(w io.Writer) error { - return rlp.Encode(w, &tx.data) -} - -// DecodeRLP implements rlp.Decoder -func (tx *Transaction) DecodeRLP(s *rlp.Stream) error { - _, size, _ := s.Kind() - err := s.Decode(&tx.data) - if err == nil { - tx.size.Store(common.StorageSize(rlp.ListSize(size))) - } - - return err -} - -func (tx *Transaction) Data() []byte { return common.CopyBytes(tx.data.Payload) } -func (tx *Transaction) Gas() *big.Int { return tx.data.GasLimit } -func (tx *Transaction) GasPrice() *big.Int { return new(big.Int).Set(tx.data.Price) } -func (tx *Transaction) Value() *big.Int { return new(big.Int).Set(tx.data.Amount) } -func (tx *Transaction) Nonce() *big.Int { return tx.data.AccountNonce } +func (tx *Transaction) Input() []byte { return common.CopyBytes(tx.Data.Input) } +func (tx *Transaction) ABI() string { return tx.Data.Abi } +func (tx *Transaction) GasPrice() *big.Int { return new(big.Int).Set(tx.Data.GasPrice) } +func (tx *Transaction) Value() *big.Int { return new(big.Int).Set(tx.Data.Value) } +func (tx *Transaction) Nonce() string { return tx.Data.Nonce } func (tx *Transaction) CheckNonce() bool { return true } // To returns the recipient address of the transaction. // It returns nil if the transaction is a contract creation. func (tx *Transaction) To() *common.Address { - if tx.data.Recipient == nil { + if tx.Data.To == nil { return nil } - to := *tx.data.Recipient + to := *tx.Data.To return &to } // Hash hashes the RLP encoding of tx. // It uniquely identifies the transaction. func (tx *Transaction) Hash() common.Hash { - if hash := tx.hash.Load(); hash != nil { - return hash.(common.Hash) + if hash := tx.DataHash; hash != nil { + return *hash } - if tx.smcrypto { + if tx.SMCrypto { return tx.sm3HashWithSig() } v := rlpHash(tx) - tx.hash.Store(v) + tx.DataHash = &v return v } @@ -170,16 +153,15 @@ func (tx *Transaction) SM3HashNonSig() (h common.Hash) { var src []byte buf := bytes.NewBuffer(src) rlp.Encode(buf, []interface{}{ - tx.data.AccountNonce, - tx.data.Price, - tx.data.GasLimit, - tx.data.BlockLimit, - tx.data.Recipient, - tx.data.Amount, - tx.data.Payload, - tx.data.ChainID, - tx.data.GroupID, - tx.data.ExtraData, + tx.Data.Nonce, + tx.Data.GasPrice, + tx.Data.GasLimit, + tx.Data.BlockLimit, + tx.Data.To, + tx.Data.Value, + tx.Data.Input, + tx.Data.ChainID, + tx.Data.GroupID, }) v := sm3.Hash(buf.Bytes()) copy(h[:], v) @@ -193,7 +175,7 @@ func (tx *Transaction) sm3HashWithSig() (h common.Hash) { rlp.Encode(buf, tx) v := sm3.Hash(buf.Bytes()) copy(h[:], v) - tx.hash.Store(h) + tx.DataHash = &h return h } @@ -204,62 +186,6 @@ func rlpHash(x interface{}) (h common.Hash) { return h } -func (tx *Transaction) RlpEncodeTxdata() ([]byte, error) { - return rlp.EncodeToBytes([]interface{}{ - tx.data.AccountNonce, - tx.data.Price, - tx.data.GasLimit, - tx.data.BlockLimit, - tx.data.Recipient, - tx.data.Amount, - tx.data.Payload, - tx.data.ChainID, - tx.data.GroupID, - tx.data.ExtraData, - }) -} - -// Size returns the true RLP encoded storage size of the transaction, either by -// encoding and returning it, or returning a previsouly cached value. -func (tx *Transaction) Size() common.StorageSize { - if size := tx.size.Load(); size != nil { - return size.(common.StorageSize) - } - c := writeCounter(0) - rlp.Encode(&c, &tx.data) - tx.size.Store(common.StorageSize(c)) - return common.StorageSize(c) -} - -type writeCounter common.StorageSize - -func (c *writeCounter) Write(b []byte) (int, error) { - *c += writeCounter(len(b)) - return len(b), nil -} - -// AsMessage returns the transaction as a core.Message. -// -// AsMessage requires a signer to derive the sender. -// -// XXX Rename message to something less arbitrary? -func (tx *Transaction) AsMessage(s Signer) (Message, error) { - msg := Message{ - nonce: tx.data.AccountNonce, - gasLimit: tx.data.GasLimit, - gasPrice: new(big.Int).Set(tx.data.Price), - blockLimit: tx.data.BlockLimit, - to: tx.data.Recipient, - amount: tx.data.Amount, - data: tx.data.Payload, - checkNonce: true, - } - - var err error - msg.from, err = Sender(s, tx) - return msg, err -} - // WithSignature returns a new transaction with the given signature. // This signature needs to be in the [R || S || V] format where V is 0 or 1. func (tx *Transaction) WithSignature(signer Signer, sig []byte) (*Transaction, error) { @@ -267,9 +193,9 @@ func (tx *Transaction) WithSignature(signer Signer, sig []byte) (*Transaction, e if err != nil { return nil, err } - cpy := &Transaction{data: tx.data} - cpy.data.R, cpy.data.S, cpy.data.V = r, s, v - cpy.smcrypto = tx.smcrypto + cpy := &Transaction{Data: tx.Data} + cpy.R, cpy.S, cpy.V = r, s, v + cpy.SMCrypto = tx.SMCrypto return cpy, nil } @@ -282,23 +208,23 @@ func (tx *Transaction) WithSM2Signature(signer Signer, sig []byte) (*Transaction r := new(big.Int).SetBytes(sig[:32]) s := new(big.Int).SetBytes(sig[32:64]) v := new(big.Int).SetBytes(sig[64:]) - cpy := &Transaction{data: tx.data} - cpy.data.R, cpy.data.S, cpy.data.V = r, s, v - cpy.smcrypto = tx.smcrypto + cpy := &Transaction{Data: tx.Data} + cpy.R, cpy.S, cpy.V = r, s, v + cpy.SMCrypto = tx.SMCrypto return cpy, nil } // Cost returns amount + gasprice * gaslimit. func (tx *Transaction) Cost() *big.Int { - total := new(big.Int).Mul(tx.data.Price, new(big.Int).Set(tx.data.GasLimit)) - total.Add(total, tx.data.Amount) + total := new(big.Int).Mul(tx.Data.GasPrice, new(big.Int).SetInt64(tx.Data.GasLimit)) + total.Add(total, tx.Data.Value) return total } // SignatureValues returns the V, R, S signature values of the transaction. // The return values should not be modified by the caller. func (tx *Transaction) SignatureValues() (v, r, s *big.Int) { - return tx.data.V, tx.data.R, tx.data.S + return tx.V, tx.R, tx.S } // Transactions is a Transaction slice type for basic sorting. @@ -333,98 +259,3 @@ func TxDifference(a, b Transactions) Transactions { return keep } - -// TxByNonce implements the sort interface to allow sorting a list of transactions -// by their nonces. This is usually only useful for sorting transactions from a -// single account, otherwise a nonce comparison doesn't make much sense. -type TxByNonce Transactions - -func (s TxByNonce) Len() int { return len(s) } -func (s TxByNonce) Less(i, j int) bool { - return s[i].data.AccountNonce.Cmp(s[j].data.AccountNonce) > 0 -} //{ return s[i].data.AccountNonce < s[j].data.AccountNonce } -func (s TxByNonce) Swap(i, j int) { s[i], s[j] = s[j], s[i] } - -// Message is a fully derived transaction and implements core.Message -// -// NOTE: In a future PR this will be removed. -type Message struct { - to *common.Address - from common.Address - nonce *big.Int - amount *big.Int - gasLimit *big.Int - gasPrice *big.Int - blockLimit *big.Int - data []byte - checkNonce bool -} - -func NewMessage(from common.Address, to *common.Address, nonce *big.Int, amount *big.Int, gasLimit *big.Int, gasPrice *big.Int, blockLimit *big.Int, data []byte, checkNonce bool) Message { - return Message{ - from: from, - to: to, - nonce: nonce, - amount: amount, - gasLimit: gasLimit, - gasPrice: gasPrice, - blockLimit: blockLimit, - data: data, - checkNonce: checkNonce, - } -} - -func (m Message) From() common.Address { return m.from } -func (m Message) To() *common.Address { return m.to } -func (m Message) GasPrice() *big.Int { return m.gasPrice } -func (m Message) Value() *big.Int { return m.amount } -func (m Message) Gas() *big.Int { return m.gasLimit } -func (m Message) Nonce() *big.Int { return m.nonce } -func (m Message) Data() []byte { return m.data } -func (m Message) CheckNonce() bool { return m.checkNonce } - -type newTransactionStruct struct { - data newrawtxdata - // caches - hash atomic.Value - size atomic.Value - from atomic.Value -} - -type newrawtxdata struct { - AccountNonce *big.Int `json:"nonce" gencodec:"required"` - Price *big.Int `json:"gasPrice" gencodec:"required"` - GasLimit *big.Int `json:"gas" gencodec:"required"` - BlockLimit *big.Int `json:"blocklimit" gencodec:"required"` - Recipient string `json:"to" rlp:"nil"` // nil means contract creation - Amount *big.Int `json:"value" gencodec:"required"` - Payload string `json:"input" gencodec:"required"` - - // Signature values - V *big.Int `json:"v" gencodec:"required"` - R *big.Int `json:"r" gencodec:"required"` - S *big.Int `json:"s" gencodec:"required"` - - // This is only used when marshaling to JSON. - Hash *common.Hash `json:"hash" rlp:"-"` -} - -func (tx *Transaction) ConverToNewRawTx() *newTransactionStruct { - return &newTransactionStruct{ - data: newrawtxdata{ - AccountNonce: tx.data.AccountNonce, - Price: tx.data.Price, - GasLimit: tx.data.GasLimit, - BlockLimit: tx.data.BlockLimit, - Recipient: tx.data.Recipient.String(), - Amount: tx.data.Amount, - Payload: hexutil.Bytes(tx.data.Payload).String(), - V: tx.data.V, - R: tx.data.R, - S: tx.data.S, - }, - hash: tx.hash, - size: tx.size, - from: tx.from, - } -} diff --git a/v3/types/transaction_signing.go b/v3/types/transaction_signing.go index 761c9faa..b50aab07 100644 --- a/v3/types/transaction_signing.go +++ b/v3/types/transaction_signing.go @@ -62,31 +62,31 @@ func SignTx(tx *Transaction, s Signer, prv *ecdsa.PrivateKey) (*Transaction, err return tx.WithSignature(s, sig) } -// Sender returns the address derived from the signature (V, R, S) using secp256k1 -// elliptic curve and an error if it failed deriving or upon an incorrect -// signature. -// -// Sender may cache the address, allowing it to be used regardless of -// signing method. The cache is invalidated if the cached signer does -// not match the signer used in the current call. -func Sender(signer Signer, tx *Transaction) (common.Address, error) { - if sc := tx.from.Load(); sc != nil { - sigCache := sc.(sigCache) - // If the signer used to derive from in a previous - // call is not the same as used current, invalidate - // the cache. - if sigCache.signer.Equal(signer) { - return sigCache.from, nil - } - } +// // Sender returns the address derived from the signature (V, R, S) using secp256k1 +// // elliptic curve and an error if it failed deriving or upon an incorrect +// // signature. +// // +// // Sender may cache the address, allowing it to be used regardless of +// // signing method. The cache is invalidated if the cached signer does +// // not match the signer used in the current call. +// func Sender(signer Signer, tx *Transaction) (common.Address, error) { +// if sc := tx.Sender.Load(); sc != nil { +// sigCache := sc.(sigCache) +// // If the signer used to derive from in a previous +// // call is not the same as used current, invalidate +// // the cache. +// if sigCache.signer.Equal(signer) { +// return sigCache.from, nil +// } +// } - addr, err := signer.Sender(tx) - if err != nil { - return common.Address{}, err - } - tx.from.Store(sigCache{signer: signer, from: addr}) - return addr, nil -} +// addr, err := signer.Sender(tx) +// if err != nil { +// return common.Address{}, err +// } +// tx.Sender.Store(sigCache{signer: signer, from: addr}) +// return addr, nil +// } // Signer encapsulates transaction signature handling. Note that this interface is not a // stable API and may change at any time to accommodate new protocol rules. @@ -131,9 +131,9 @@ func (s EIP155Signer) Sender(tx *Transaction) (common.Address, error) { if tx.ChainID().Cmp(s.chainId) != 0 { return common.Address{}, ErrInvalidChainID } - V := new(big.Int).Sub(tx.data.V, s.chainIdMul) + V := new(big.Int).Sub(tx.V, s.chainIdMul) V.Sub(V, big8) - return recoverPlain(s.Hash(tx), tx.data.R, tx.data.S, V, true) + return recoverPlain(s.Hash(tx), tx.R, tx.S, V, true) } // SignatureValues returns signature values. This signature @@ -154,16 +154,16 @@ func (s EIP155Signer) SignatureValues(tx *Transaction, sig []byte) (R, S, V *big // It does not uniquely identify the transaction. func (s EIP155Signer) Hash(tx *Transaction) common.Hash { return rlpHash([]interface{}{ - tx.data.AccountNonce, - tx.data.Price, - tx.data.GasLimit, - tx.data.BlockLimit, - tx.data.Recipient, - tx.data.Amount, - tx.data.Payload, - tx.data.ChainID, - tx.data.GroupID, - tx.data.ExtraData, + tx.Data.Nonce, + tx.Data.GasPrice, + tx.Data.GasLimit, + tx.Data.BlockLimit, + tx.Data.To, + tx.Data.Value, + tx.Data.Input, + tx.Data.ChainID, + tx.Data.GroupID, + tx.ExtraData, s.chainId, uint(0), uint(0), }) } @@ -184,7 +184,7 @@ func (hs HomesteadSigner) SignatureValues(tx *Transaction, sig []byte) (r, s, v } func (hs HomesteadSigner) Sender(tx *Transaction) (common.Address, error) { - return recoverPlain(hs.Hash(tx), tx.data.R, tx.data.S, tx.data.V, true) + return recoverPlain(hs.Hash(tx), tx.R, tx.S, tx.V, true) } type FrontierSigner struct{} @@ -210,21 +210,21 @@ func (fs FrontierSigner) SignatureValues(tx *Transaction, sig []byte) (r, s, v * // It does not uniquely identify the transaction. func (fs FrontierSigner) Hash(tx *Transaction) common.Hash { return rlpHash([]interface{}{ - tx.data.AccountNonce, - tx.data.Price, - tx.data.GasLimit, - tx.data.BlockLimit, - tx.data.Recipient, - tx.data.Amount, - tx.data.Payload, - tx.data.ChainID, - tx.data.GroupID, - tx.data.ExtraData, + tx.Data.Nonce, + tx.Data.GasPrice, + tx.Data.GasLimit, + tx.Data.BlockLimit, + tx.Data.To, + tx.Data.Value, + tx.Data.Input, + tx.Data.ChainID, + tx.Data.GroupID, + tx.ExtraData, }) } func (fs FrontierSigner) Sender(tx *Transaction) (common.Address, error) { - return recoverPlain(fs.Hash(tx), tx.data.R, tx.data.S, tx.data.V, false) + return recoverPlain(fs.Hash(tx), tx.R, tx.S, tx.V, false) } func recoverPlain(sighash common.Hash, R, S, Vb *big.Int, homestead bool) (common.Address, error) {