diff --git a/v3/abi/bind/auth.go b/v3/abi/bind/auth.go index 9c8323dd..f3897999 100644 --- a/v3/abi/bind/auth.go +++ b/v3/abi/bind/auth.go @@ -94,7 +94,10 @@ func NewSMCryptoTransactor(sm2Key []byte) *TransactOpts { if address != keyAddr { return nil, errors.New("not authorized to sign this account") } - signature, err := smcrypto.Sign(tx.SM3HashNonSig().Bytes(), sm2Key) + if !tx.SMCrypto { + tx.SMCrypto = true + } + signature, err := smcrypto.Sign(tx.Hash().Bytes(), sm2Key) if err != nil { return nil, err } diff --git a/v3/examples/parallelok/manual/main.go b/v3/examples/parallelok/manual/main.go index 86649dc7..61a3bcf7 100644 --- a/v3/examples/parallelok/manual/main.go +++ b/v3/examples/parallelok/manual/main.go @@ -199,11 +199,11 @@ func main() { } err = client.AsyncSendEncodedTransaction(context.Background(), tx, true, func(receipt *types.Receipt, err error) { receiveBar.Add(1) - wg2.Done() if err != nil { fmt.Println("transfer error", err) return } + wg2.Done() if receipt.Status != 0 { fmt.Println("transfer error", receipt.GetErrorMessage()) return diff --git a/v3/examples/parallelok/wrapper/main.go b/v3/examples/parallelok/wrapper/main.go index 5e4b0b4d..2b6d83d2 100644 --- a/v3/examples/parallelok/wrapper/main.go +++ b/v3/examples/parallelok/wrapper/main.go @@ -112,6 +112,7 @@ func main() { if err != nil { fmt.Println("add user error", err) failedCount++ + continue } balance.Store(i, initValue) wg.Add(1) @@ -185,11 +186,11 @@ func main() { amount := int64(1) _, err = transfer.AsyncTransfer(func(receipt *types.Receipt, err error) { receiveBar.Add(1) - wg2.Done() if err != nil { - fmt.Println("transfer error", err) + fmt.Println("AsyncTransfer error", err) return } + wg2.Done() currentFrom, _ := balance.Load(from) currentTo, _ := balance.Load(to) if !balance.CompareAndSwap(from, currentFrom.(int64), currentFrom.(int64)-amount) { diff --git a/v3/go.mod b/v3/go.mod index f6d8216d..649a4fd0 100644 --- a/v3/go.mod +++ b/v3/go.mod @@ -11,6 +11,7 @@ replace ( require ( github.com/FISCO-BCOS/bcos-c-sdk v0.0.0-20240105080731-14b9b42a47a9 github.com/FISCO-BCOS/crypto v0.0.0-20200202032121-bd8ab0b5d4f1 + github.com/TarsCloud/TarsGo v1.4.5 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 @@ -55,7 +56,6 @@ require ( github.com/influxdata/influxdb-client-go/v2 v2.4.0 // indirect github.com/influxdata/line-protocol v0.0.0-20210311194329-9aa0e372d097 // indirect github.com/jackpal/go-nat-pmp v1.0.2 // indirect - github.com/kr/text v0.2.0 // indirect github.com/mattn/go-colorable v0.1.8 // indirect github.com/mattn/go-isatty v0.0.20 // indirect github.com/mattn/go-runewidth v0.0.9 // indirect @@ -84,7 +84,6 @@ require ( golang.org/x/sys v0.14.0 // indirect golang.org/x/term v0.14.0 // indirect golang.org/x/text v0.3.7 // indirect - gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce // indirect gopkg.in/yaml.v2 v2.4.0 // indirect ) diff --git a/v3/go.sum b/v3/go.sum index 47b7d609..ef782bd1 100644 --- a/v3/go.sum +++ b/v3/go.sum @@ -28,6 +28,8 @@ github.com/FISCO-BCOS/crypto v0.0.0-20200202032121-bd8ab0b5d4f1/go.mod h1:UrLdws github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/StackExchange/wmi v0.0.0-20190523213315-cbe66965904d h1:G0m3OIz70MZUWq3EgK3CesDbo8upS2Vm9/P3FtgI+Jk= github.com/StackExchange/wmi v0.0.0-20190523213315-cbe66965904d/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg= +github.com/TarsCloud/TarsGo v1.4.5 h1:AeOILCND6p35Swnu8MRHVLWqcjzJ+M6aKi6UIfsemNM= +github.com/TarsCloud/TarsGo v1.4.5/go.mod h1:fQITmq34rZnC0bz+KbQcHGdQUijzcmVtowXlic33jSk= github.com/VictoriaMetrics/fastcache v1.6.0 h1:C/3Oi3EiBCqufydp1neRZkqcwmEiuRT9c3fqvvgKm5o= github.com/VictoriaMetrics/fastcache v1.6.0/go.mod h1:0qHz5QP0GMX4pfmMA/zt5RgfNuXJrTP0zS7DqpHGGTw= github.com/ajstarks/svgo v0.0.0-20180226025133-644b8db467af/go.mod h1:K08gAheRH3/J6wwsYMMT4xOr94bZjxIelGM0+d/wbFw= @@ -240,8 +242,9 @@ github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxv github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515 h1:T+h1c/A9Gawja4Y9mFVWj2vyii2bbUNDw3kt9VxK2EY= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= -github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= +github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0= +github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= @@ -307,6 +310,7 @@ github.com/peterh/liner v1.1.1-0.20190123174540-a2c9a5303de7 h1:oYW+YCJ1pachXTQm github.com/peterh/liner v1.1.1-0.20190123174540-a2c9a5303de7/go.mod h1:CRroGNssyjTd/qIG2FyxByd2S8JEAZXBl4qUrZf8GS0= github.com/philhofer/fwd v1.0.0/go.mod h1:gk3iGcWd9+svBvR0sR+KPcfE+RNWozjowpeBVG3ZVNU= github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= +github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= @@ -314,6 +318,7 @@ github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE github.com/pkg/term v0.0.0-20180730021639-bffc007b7fd5/go.mod h1:eCbImbZ95eXtAUIbLAuAVnBnwf83mjf6QIVH8SHYwqQ= 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/prashantv/gostub v1.1.0/go.mod h1:A5zLQHz7ieHGG7is6LLXLz7I8+3LZzsrV0P1IAHhP5U= github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso= github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= @@ -336,6 +341,9 @@ github.com/rjeczalik/notify v0.9.1 h1:CLCKso/QK1snAlnhNR/CNvNiFU2saUtjV0bx3EwNeC github.com/rjeczalik/notify v0.9.1/go.mod h1:rKwnCoCGeuQnwBtTSPL9Dad03Vh2n40ePRrjvIXnJho= github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= +github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= +github.com/rogpeppe/go-internal v1.8.0 h1:FCbCCtXNOY3UtUuHUYaghJg4y7Fd14rXifAYUAtL9R8= +github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE= github.com/rs/cors v1.7.0 h1:+88SsELBHx5r+hZ8TCkggzSstaWNbDvThkVK8H6f9ik= github.com/rs/cors v1.7.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= @@ -370,14 +378,18 @@ github.com/status-im/keycard-go v0.0.0-20190316090335-8537d3370df4 h1:Gb2Tyox57N github.com/status-im/keycard-go v0.0.0-20190316090335-8537d3370df4/go.mod h1:RZLeN1LMWmRsyYjvAu+I6Dm9QmlDaIIt+Y+4Kd7Tp+Q= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= github.com/stretchr/testify v1.2.0/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.7.2 h1:4jaiDzPyXQvSd7D0EjG45355tLlV3VOECpq10pLC+8s= -github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= +github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 h1:epCh84lMvA70Z7CTTCmYQn2CKbY8j86K7/FAIr141uY= github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7/go.mod h1:q4W45IWZaF22tdD+VEXcAWRA037jwmWEB5VWYORlTpc= github.com/tinylib/msgp v1.0.2/go.mod h1:+d+yLhGm8mzTaHzB+wgMYrodPfmZrzkirds8fDWklFE= @@ -406,6 +418,7 @@ go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= +go.uber.org/automaxprocs v1.5.2/go.mod h1:eRbA25aqJrxAbsLO0xy5jVwPt7FQnRgjW+efnwa1WM0= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= go.uber.org/zap v1.9.1/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= diff --git a/v3/types/log.go b/v3/types/log.go index 8f541e10..49447e31 100644 --- a/v3/types/log.go +++ b/v3/types/log.go @@ -17,11 +17,8 @@ package types import ( - "io" - "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" - "github.com/ethereum/go-ethereum/rlp" ) //go:generate gencodec -type Log -field-override logMarshaling -out gen_log_json.go @@ -69,86 +66,6 @@ type logMarshaling struct { Index hexutil.Uint } -type rlpLog struct { - Address common.Address - Topics []common.Hash - Data []byte -} - -// rlpStorageLog is the storage encoding of a log. -type rlpStorageLog rlpLog - -// legacyRlpStorageLog is the previous storage encoding of a log including some redundant fields. -type legacyRlpStorageLog struct { - Address common.Address - Topics []common.Hash - Data []byte - BlockNumber uint64 - TxHash common.Hash - TxIndex uint - BlockHash common.Hash - Index uint -} - -// EncodeRLP implements rlp.Encoder. -func (l *Log) EncodeRLP(w io.Writer) error { - return rlp.Encode(w, rlpLog{Address: l.Address, Topics: l.Topics, Data: l.Data}) -} - -// DecodeRLP implements rlp.Decoder. -func (l *Log) DecodeRLP(s *rlp.Stream) error { - var dec rlpLog - err := s.Decode(&dec) - if err == nil { - l.Address, l.Topics, l.Data = dec.Address, dec.Topics, dec.Data - } - return err -} - -// LogForStorage is a wrapper around a Log that flattens and parses the entire content of -// a log including non-consensus fields. -type LogForStorage Log - -// EncodeRLP implements rlp.Encoder. -func (l *LogForStorage) EncodeRLP(w io.Writer) error { - return rlp.Encode(w, rlpStorageLog{ - Address: l.Address, - Topics: l.Topics, - Data: l.Data, - }) -} - -// DecodeRLP implements rlp.Decoder. -// -// Note some redundant fields(e.g. block number, tx hash etc) will be assembled later. -func (l *LogForStorage) DecodeRLP(s *rlp.Stream) error { - blob, err := s.Raw() - if err != nil { - return err - } - var dec rlpStorageLog - err = rlp.DecodeBytes(blob, &dec) - if err == nil { - *l = LogForStorage{ - Address: dec.Address, - Topics: dec.Topics, - Data: dec.Data, - } - } else { - // Try to decode log with previous definition. - var dec legacyRlpStorageLog - err = rlp.DecodeBytes(blob, &dec) - if err == nil { - *l = LogForStorage{ - Address: dec.Address, - Topics: dec.Topics, - Data: dec.Data, - } - } - } - return err -} - // NewLog is used for the receipt type NewLog struct { BlockNumber string `json:"blockNumber"` diff --git a/v3/types/transaction.go b/v3/types/transaction.go index 373e485a..708ce6b2 100644 --- a/v3/types/transaction.go +++ b/v3/types/transaction.go @@ -1,14 +1,14 @@ package types import ( - "bytes" + "encoding/binary" "errors" "fmt" "math/big" "github.com/FISCO-BCOS/go-sdk/v3/smcrypto/sm3" + "github.com/TarsCloud/TarsGo/tars/protocol/codec" "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/rlp" "golang.org/x/crypto/sha3" ) @@ -16,54 +16,347 @@ var ( ErrInvalidSig = errors.New("invalid raw transaction v, r, s values") ) +type TransactionData struct { + Version int32 `json:"version" tars:"version,tag:1,require:false"` + ChainID string `json:"chainID" tars:"chainID,tag:2,require:false"` + GroupID string `json:"groupID" tars:"groupID,tag:3,require:false"` + BlockLimit int64 `json:"blockLimit" tars:"blockLimit,tag:4,require:false"` + Nonce string `json:"nonce" tars:"nonce,tag:5,require:false"` + To *common.Address `json:"to" tars:"to,tag:6,require:false"` + Input []byte `json:"input" tars:"input,tag:7,require:false"` + Abi string `json:"abi" tars:"abi,tag:8,require:false"` + Value *big.Int `json:"value" tars:"value,tag:9,require:false"` + GasPrice *big.Int `json:"gasPrice" tars:"gasPrice,tag:10,require:false"` + GasLimit int64 `json:"gasLimit" tars:"gasLimit,tag:11,require:false"` + MaxFeePerGas *big.Int `json:"maxFeePerGas" tars:"maxFeePerGas,tag:12,require:false"` + MaxPriorityFeePerGas *big.Int `json:"maxPriorityFeePerGas" tars:"maxPriorityFeePerGas,tag:13,require:false"` +} + +func (st *TransactionData) ResetDefault() { +} + +func (st *TransactionData) Bytes() []byte { + buf := codec.NewBuffer() + st.WriteTo(buf) + return buf.ToBytes() +} + +func readBigIntFromHex(readBuf *codec.Reader, tag byte, require bool) (*big.Int, error) { + var hexStr string + err := readBuf.ReadString(&hexStr, tag, require) + if err != nil { + return nil, err + } + if len(hexStr) == 0 { + return nil, nil + } + return big.NewInt(0).SetBytes(common.FromHex(hexStr)), nil +} + +// ReadFrom reads from readBuf and put into struct. +func (st *TransactionData) ReadFrom(readBuf *codec.Reader) error { + var ( + err error + length int32 + have bool + ty byte + ) + st.ResetDefault() + + err = readBuf.ReadInt32(&st.Version, 1, false) + if err != nil { + return err + } + + err = readBuf.ReadString(&st.ChainID, 2, false) + if err != nil { + return err + } + + err = readBuf.ReadString(&st.GroupID, 3, false) + if err != nil { + return err + } + + err = readBuf.ReadInt64(&st.BlockLimit, 4, false) + if err != nil { + return err + } + + err = readBuf.ReadString(&st.Nonce, 5, false) + if err != nil { + return err + } + var to string + err = readBuf.ReadString(&to, 6, false) + if err != nil { + return err + } + if len(to) > 0 { + addr := common.HexToAddress(to) + st.To = &addr + } + + have, ty, err = readBuf.SkipToNoCheck(7, false) + if err != nil { + return err + } + if have { + if ty == codec.LIST { + err = readBuf.ReadInt32(&length, 0, true) + if err != nil { + return err + } + st.Input = make([]byte, length) + for i0, e0 := int32(0), length; i0 < e0; i0++ { + err = readBuf.ReadUint8(&st.Input[i0], 0, true) + if err != nil { + return err + } + } + } else if ty == codec.SimpleList { + _, err = readBuf.SkipTo(codec.BYTE, 0, true) + if err != nil { + return err + } + err = readBuf.ReadInt32(&length, 0, true) + if err != nil { + return err + } + err = readBuf.ReadSliceUint8(&st.Input, length, true) + if err != nil { + return err + } + } else { + err = fmt.Errorf("require vector, but not") + if err != nil { + return err + } + } + } + + err = readBuf.ReadString(&st.Abi, 8, false) + if err != nil { + return err + } + st.Value, err = readBigIntFromHex(readBuf, 9, false) + if err != nil { + return err + } + st.GasPrice, err = readBigIntFromHex(readBuf, 10, false) + if err != nil { + return err + } + + err = readBuf.ReadInt64(&st.GasLimit, 11, false) + if err != nil { + return err + } + + st.MaxFeePerGas, err = readBigIntFromHex(readBuf, 12, false) + if err != nil { + return err + } + + st.MaxPriorityFeePerGas, err = readBigIntFromHex(readBuf, 13, false) + if err != nil { + return err + } + + _ = err + _ = length + _ = have + _ = ty + return nil +} + +// ReadBlock reads struct from the given tag , require or optional. +func (st *TransactionData) ReadBlock(readBuf *codec.Reader, tag byte, require bool) error { + var ( + err error + have bool + ) + st.ResetDefault() + + have, err = readBuf.SkipTo(codec.StructBegin, tag, require) + if err != nil { + return err + } + if !have { + if require { + return fmt.Errorf("require TransactionData, but not exist. tag %d", tag) + } + return nil + } + + err = st.ReadFrom(readBuf) + if err != nil { + return err + } + + err = readBuf.SkipToStructEnd() + if err != nil { + return err + } + _ = have + return nil +} + +// WriteTo encode struct to buffer +func (st *TransactionData) WriteTo(buf *codec.Buffer) (err error) { + // if st.Version != 0 { + err = buf.WriteInt32(st.Version, 1) + if err != nil { + return err + } + // } + + if st.ChainID != "" { + err = buf.WriteString(st.ChainID, 2) + if err != nil { + return err + } + } + + if st.GroupID != "" { + err = buf.WriteString(st.GroupID, 3) + if err != nil { + return err + } + } + + if st.BlockLimit != 0 { + err = buf.WriteInt64(st.BlockLimit, 4) + if err != nil { + return err + } + } + + if st.Nonce != "" { + err = buf.WriteString(st.Nonce, 5) + if err != nil { + return err + } + } + + if st.To != nil { + err = buf.WriteString(fmt.Sprintf("%x", st.To), 6) + if err != nil { + return err + } + } + + if len(st.Input) > 0 { + err = buf.WriteHead(codec.SimpleList, 7) + if err != nil { + return err + } + err = buf.WriteHead(codec.BYTE, 0) + if err != nil { + return err + } + err = buf.WriteInt32(int32(len(st.Input)), 0) + if err != nil { + return err + } + err = buf.WriteSliceUint8(st.Input) + if err != nil { + return err + } + } + + if st.Abi != "" { + err = buf.WriteString(st.Abi, 8) + if err != nil { + return err + } + } + + if st.Value != nil { + err = buf.WriteString(fmt.Sprintf("%#x", st.Value), 9) + if err != nil { + return err + } + } + + if st.GasPrice != nil { + err = buf.WriteString(fmt.Sprintf("%#x", st.GasPrice), 10) + if err != nil { + return err + } + } + + if st.GasLimit != 0 { + err = buf.WriteInt64(st.GasLimit, 11) + if err != nil { + return err + } + } + + if st.MaxFeePerGas != nil { + err = buf.WriteString(fmt.Sprintf("%#x", st.MaxFeePerGas), 12) + if err != nil { + return err + } + } + + if st.MaxPriorityFeePerGas != nil { + err = buf.WriteString(fmt.Sprintf("%#x", st.MaxPriorityFeePerGas), 13) + if err != nil { + return err + } + } + + return err +} + +// WriteBlock encode struct +func (st *TransactionData) WriteBlock(buf *codec.Buffer, tag byte) error { + var err error + err = buf.WriteHead(codec.StructBegin, tag) + if err != nil { + return err + } + + err = st.WriteTo(buf) + if err != nil { + return err + } + + err = buf.WriteHead(codec.StructEnd, 0) + if err != nil { + return err + } + return nil +} + type Transaction struct { - 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"` + Data TransactionData + DataHash *common.Hash `json:"dataHash" tars:"dataHash,tag:2,require:false"` + Signature []byte `json:"signature" tars:"signature,tag:3,require:false"` + ImportTime int64 `json:"importTime" tars:"importTime,tag:4,require:false"` + Attribute int32 `json:"attribute" tars:"attribute,tag:5,require:false"` + Sender *common.Address `json:"sender" tars:"sender,tag:7,require:false"` + ExtraData string `json:"extraData" tars:"extraData,tag:8,require:false"` SMCrypto bool `json:"-"` - + // Data TarsTransactionData `json:"data" tars:"data,tag:1,require:false"` // Signature values V *big.Int `json:"v"` R *big.Int `json:"r"` S *big.Int `json:"s"` } -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(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(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) -} - // 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 := transactionData{ + d := TransactionData{ To: to, Input: data, Abi: abi, @@ -76,7 +369,7 @@ func newTransaction(to *common.Address, amount *big.Int, gasLimit int64, gasPric if len(data) > 0 { data = common.CopyBytes(data) } - d := transactionData{ + d := TransactionData{ Nonce: nonce, To: to, Input: data, @@ -88,20 +381,14 @@ func newTransaction(to *common.Address, amount *big.Int, gasLimit int64, gasPric GroupID: groupId, } if amount != nil { - d.Value.Set(amount) + d.Value = big.NewInt(0).Set(amount) } if gasPrice != nil { - d.GasPrice.Set(gasPrice) + d.GasPrice = big.NewInt(0).Set(gasPrice) } - 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.V) -} - // Protected returns whether the transaction is protected from replay protection. func (tx *Transaction) Protected() bool { return isProtectedV(tx.V) @@ -136,53 +423,96 @@ func (tx *Transaction) To() *common.Address { // Hash hashes the RLP encoding of tx. // It uniquely identifies the transaction. func (tx *Transaction) Hash() common.Hash { - if hash := tx.DataHash; hash != nil { - return *hash - } + // if hash := tx.DataHash; hash != nil { + // return *hash + // } + var v common.Hash if tx.SMCrypto { - return tx.sm3HashWithSig() + v = tx.sm3Hash() + } else { + v = tx.keccak256Hash() } - v := rlpHash(tx) tx.DataHash = &v - return v + return *tx.DataHash } // SM3HashNonSig hashes the RLP encoding of tx use sm3. // It uniquely identifies the transaction. -func (tx *Transaction) SM3HashNonSig() (h common.Hash) { - var src []byte - buf := bytes.NewBuffer(src) - rlp.Encode(buf, []interface{}{ - 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) - return h -} - -func (tx *Transaction) sm3HashWithSig() (h common.Hash) { - - var src []byte - buf := bytes.NewBuffer(src) - rlp.Encode(buf, tx) - v := sm3.Hash(buf.Bytes()) - copy(h[:], v) - tx.DataHash = &h +func (tx *Transaction) sm3Hash() (h common.Hash) { + var sm3 sm3.Context + sm3.Reset() + version := make([]byte, 4) + binary.BigEndian.PutUint32(version, uint32(tx.Data.Version)) + sm3.Append(version) + sm3.Append([]byte(tx.Data.ChainID)) + sm3.Append([]byte(tx.Data.GroupID)) + blockLimit := make([]byte, 8) + binary.BigEndian.PutUint64(blockLimit, uint64(tx.Data.BlockLimit)) + sm3.Append(blockLimit) + sm3.Append([]byte(tx.Data.Nonce)) + if tx.Data.To != nil { + sm3.Append([]byte(fmt.Sprintf("%x", tx.Data.To))) + } + sm3.Append(tx.Data.Input) + sm3.Append([]byte(tx.Data.Abi)) + if tx.Data.Version == 1 { + if tx.Data.Value != nil { + sm3.Append([]byte(fmt.Sprintf("%x", tx.Data.Value))) + } + if tx.Data.GasPrice != nil { + sm3.Append([]byte(fmt.Sprintf("%x", tx.Data.GasPrice))) + } + gasLimit := make([]byte, 8) + binary.BigEndian.PutUint64(gasLimit, uint64(tx.Data.GasLimit)) + sm3.Append(gasLimit) + if tx.Data.MaxFeePerGas != nil { + sm3.Append([]byte(fmt.Sprintf("%x", tx.Data.MaxFeePerGas))) + } + if tx.Data.MaxPriorityFeePerGas != nil { + sm3.Append([]byte(fmt.Sprintf("%x", tx.Data.MaxPriorityFeePerGas))) + } + } + hash := sm3.Final() + copy(h[:], hash) return h } -func rlpHash(x interface{}) (h common.Hash) { +func (tx *Transaction) keccak256Hash() (h common.Hash) { hw := sha3.NewLegacyKeccak256() - rlp.Encode(hw, x) - hw.Sum(h[:0]) + version := make([]byte, 4) + binary.BigEndian.PutUint32(version, uint32(tx.Data.Version)) + hw.Write(version) + hw.Write([]byte(tx.Data.ChainID)) + hw.Write([]byte(tx.Data.GroupID)) + blockLimit := make([]byte, 8) + binary.BigEndian.PutUint64(blockLimit, uint64(tx.Data.BlockLimit)) + hw.Write(blockLimit) + hw.Write([]byte(tx.Data.Nonce)) + if tx.Data.To != nil { + hw.Write([]byte(fmt.Sprintf("%x", tx.Data.To))) + } + hw.Write(tx.Data.Input) + hw.Write([]byte(tx.Data.Abi)) + if tx.Data.Version == 1 { + if tx.Data.Value != nil { + hw.Write([]byte(fmt.Sprintf("%x", tx.Data.Value))) + } + if tx.Data.GasPrice != nil { + hw.Write([]byte(fmt.Sprintf("%x", tx.Data.GasPrice))) + } + gasLimit := make([]byte, 8) + binary.BigEndian.PutUint64(gasLimit, uint64(tx.Data.GasLimit)) + hw.Write(gasLimit) + if tx.Data.MaxFeePerGas != nil { + hw.Write([]byte(fmt.Sprintf("%x", tx.Data.MaxFeePerGas))) + } + if tx.Data.MaxPriorityFeePerGas != nil { + hw.Write([]byte(fmt.Sprintf("%x", tx.Data.MaxPriorityFeePerGas))) + } + } + var v []byte + v = hw.Sum(v) + copy(h[:], v) return h } @@ -227,6 +557,313 @@ func (tx *Transaction) SignatureValues() (v, r, s *big.Int) { return tx.V, tx.R, tx.S } +func (st *Transaction) ResetDefault() { + st.Data.ResetDefault() +} + +func (st *Transaction) Bytes() []byte { + buf := codec.NewBuffer() + st.WriteTo(buf) + return buf.ToBytes() +} + +// ReadFrom reads from readBuf and put into struct. +func (st *Transaction) ReadFrom(readBuf *codec.Reader) error { + var ( + err error + length int32 + have bool + ty byte + ) + st.ResetDefault() + + err = st.Data.ReadBlock(readBuf, 1, false) + if err != nil { + return err + } + + have, ty, err = readBuf.SkipToNoCheck(2, false) + if err != nil { + return err + } + if have { + if ty == codec.LIST { + err = readBuf.ReadInt32(&length, 0, true) + if err != nil { + return err + } + st.DataHash = new(common.Hash) + for i0, e0 := int32(0), length; i0 < e0; i0++ { + err = readBuf.ReadUint8(&st.DataHash[i0], 0, true) + if err != nil { + return err + } + } + } else if ty == codec.SimpleList { + _, err = readBuf.SkipTo(codec.BYTE, 0, true) + if err != nil { + return err + } + err = readBuf.ReadInt32(&length, 0, true) + if err != nil { + return err + } + var data []byte + err = readBuf.ReadSliceUint8(&data, length, true) + if err != nil { + return err + } + dataHash := common.BytesToHash(data) + st.DataHash = &dataHash + } else { + err = fmt.Errorf("require vector, but not") + if err != nil { + return err + } + } + } + + have, ty, err = readBuf.SkipToNoCheck(3, false) + if err != nil { + return err + } + if have { + if ty == codec.LIST { + err = readBuf.ReadInt32(&length, 0, true) + if err != nil { + return err + } + st.Signature = make([]byte, length) + for i1, e1 := int32(0), length; i1 < e1; i1++ { + err = readBuf.ReadUint8(&st.Signature[i1], 0, true) + if err != nil { + return err + } + } + } else if ty == codec.SimpleList { + _, err = readBuf.SkipTo(codec.BYTE, 0, true) + if err != nil { + return err + } + err = readBuf.ReadInt32(&length, 0, true) + if err != nil { + return err + } + err = readBuf.ReadSliceUint8(&st.Signature, length, true) + if err != nil { + return err + } + } else { + err = fmt.Errorf("require vector, but not") + if err != nil { + return err + } + } + } + + err = readBuf.ReadInt64(&st.ImportTime, 4, false) + if err != nil { + return err + } + + err = readBuf.ReadInt32(&st.Attribute, 5, false) + if err != nil { + return err + } + + have, ty, err = readBuf.SkipToNoCheck(7, false) + if err != nil { + return err + } + if have { + if ty == codec.LIST { + err = readBuf.ReadInt32(&length, 0, true) + if err != nil { + return err + } + st.Sender = new(common.Address) + for i2, e2 := int32(0), length; i2 < e2; i2++ { + err = readBuf.ReadUint8(&st.Sender[i2], 0, true) + if err != nil { + return err + } + } + } else if ty == codec.SimpleList { + _, err = readBuf.SkipTo(codec.BYTE, 0, true) + if err != nil { + return err + } + err = readBuf.ReadInt32(&length, 0, true) + if err != nil { + return err + } + var sender []byte + err = readBuf.ReadSliceUint8(&sender, length, true) + if err != nil { + return err + } + senderAddr := common.BytesToAddress(sender) + st.Sender = &senderAddr + } else { + err = fmt.Errorf("require vector, but not") + if err != nil { + return err + } + } + } + + err = readBuf.ReadString(&st.ExtraData, 8, false) + if err != nil { + return err + } + + _ = err + _ = length + _ = have + _ = ty + return nil +} + +// ReadBlock reads struct from the given tag , require or optional. +func (st *Transaction) ReadBlock(readBuf *codec.Reader, tag byte, require bool) error { + var ( + err error + have bool + ) + st.ResetDefault() + + have, err = readBuf.SkipTo(codec.StructBegin, tag, require) + if err != nil { + return err + } + if !have { + if require { + return fmt.Errorf("require Transaction, but not exist. tag %d", tag) + } + return nil + } + + err = st.ReadFrom(readBuf) + if err != nil { + return err + } + + err = readBuf.SkipToStructEnd() + if err != nil { + return err + } + _ = have + return nil +} + +// WriteTo encode struct to buffer +func (st *Transaction) WriteTo(buf *codec.Buffer) (err error) { + err = st.Data.WriteBlock(buf, 1) + if err != nil { + return err + } + + if len(st.DataHash) > 0 { + err = buf.WriteHead(codec.SimpleList, 2) + if err != nil { + return err + } + err = buf.WriteHead(codec.BYTE, 0) + if err != nil { + return err + } + err = buf.WriteInt32(int32(len(st.DataHash)), 0) + if err != nil { + return err + } + err = buf.WriteSliceUint8(st.DataHash.Bytes()) + if err != nil { + return err + } + } + + if len(st.Signature) > 0 { + err = buf.WriteHead(codec.SimpleList, 3) + if err != nil { + return err + } + err = buf.WriteHead(codec.BYTE, 0) + if err != nil { + return err + } + err = buf.WriteInt32(int32(len(st.Signature)), 0) + if err != nil { + return err + } + err = buf.WriteSliceUint8(st.Signature) + if err != nil { + return err + } + } + + if st.ImportTime != 0 { + err = buf.WriteInt64(st.ImportTime, 4) + if err != nil { + return err + } + } + + if st.Attribute != 0 { + err = buf.WriteInt32(st.Attribute, 5) + if err != nil { + return err + } + } + + if len(st.Sender) > 0 { + err = buf.WriteHead(codec.SimpleList, 7) + if err != nil { + return err + } + err = buf.WriteHead(codec.BYTE, 0) + if err != nil { + return err + } + err = buf.WriteInt32(int32(len(st.Sender)), 0) + if err != nil { + return err + } + err = buf.WriteSliceUint8(st.Sender.Bytes()) + if err != nil { + return err + } + } + + if st.ExtraData != "" { + err = buf.WriteString(st.ExtraData, 8) + if err != nil { + return err + } + } + + return err +} + +// WriteBlock encode struct +func (st *Transaction) WriteBlock(buf *codec.Buffer, tag byte) error { + var err error + err = buf.WriteHead(codec.StructBegin, tag) + if err != nil { + return err + } + + err = st.WriteTo(buf) + if err != nil { + return err + } + + err = buf.WriteHead(codec.StructEnd, 0) + if err != nil { + return err + } + return nil +} + // Transactions is a Transaction slice type for basic sorting. type Transactions []*Transaction @@ -236,12 +873,6 @@ func (s Transactions) Len() int { return len(s) } // Swap swaps the i'th and the j'th element in s. func (s Transactions) Swap(i, j int) { s[i], s[j] = s[j], s[i] } -// GetRlp implements Rlpable and returns the i'th element of s in rlp. -func (s Transactions) GetRlp(i int) []byte { - enc, _ := rlp.EncodeToBytes(s[i]) - return enc -} - // TxDifference returns a new set which is the difference between a and b. func TxDifference(a, b Transactions) Transactions { keep := make(Transactions, 0, len(a)) diff --git a/v3/types/transaction_signing.go b/v3/types/transaction_signing.go index b50aab07..4ae03f2e 100644 --- a/v3/types/transaction_signing.go +++ b/v3/types/transaction_signing.go @@ -128,9 +128,9 @@ func (s EIP155Signer) Sender(tx *Transaction) (common.Address, error) { if !tx.Protected() { return HomesteadSigner{}.Sender(tx) } - if tx.ChainID().Cmp(s.chainId) != 0 { - return common.Address{}, ErrInvalidChainID - } + // if tx.ChainID().Cmp(s.chainId) != 0 { + // return common.Address{}, ErrInvalidChainID + // } V := new(big.Int).Sub(tx.V, s.chainIdMul) V.Sub(V, big8) return recoverPlain(s.Hash(tx), tx.R, tx.S, V, true) @@ -153,19 +153,7 @@ func (s EIP155Signer) SignatureValues(tx *Transaction, sig []byte) (R, S, V *big // Hash returns the hash to be signed by the sender. // It does not uniquely identify the transaction. func (s EIP155Signer) Hash(tx *Transaction) common.Hash { - return rlpHash([]interface{}{ - 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), - }) + return tx.Hash() } // HomesteadTransaction implements TransactionInterface using the @@ -209,18 +197,7 @@ func (fs FrontierSigner) SignatureValues(tx *Transaction, sig []byte) (r, s, v * // Hash returns the hash to be signed by the sender. // It does not uniquely identify the transaction. func (fs FrontierSigner) Hash(tx *Transaction) common.Hash { - return rlpHash([]interface{}{ - 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, - }) + return tx.Hash() } func (fs FrontierSigner) Sender(tx *Transaction) (common.Address, error) { @@ -253,16 +230,3 @@ func recoverPlain(sighash common.Hash, R, S, Vb *big.Int, homestead bool) (commo copy(addr[:], crypto.Keccak256(pub[1:])[12:]) return addr, nil } - -// deriveChainID derives the chain id from the given v parameter -func deriveChainID(v *big.Int) *big.Int { - if v.BitLen() <= 64 { - v := v.Uint64() - if v == 27 || v == 28 { - return new(big.Int) - } - return new(big.Int).SetUint64((v - 35) / 2) - } - v = new(big.Int).Sub(v, big.NewInt(35)) - return v.Div(v, big.NewInt(2)) -} diff --git a/v3/types/transaction_test.go b/v3/types/transaction_test.go new file mode 100644 index 00000000..abcb3390 --- /dev/null +++ b/v3/types/transaction_test.go @@ -0,0 +1,95 @@ +package types + +import ( + "bytes" + "testing" + + "github.com/TarsCloud/TarsGo/tars/protocol/codec" + "github.com/ethereum/go-ethereum/common" +) + +const ( + DEPLOY_HELLOWORLD_TX_DATA = `1c2606636861696e30360667726f75703041020a5628313638383630333033393337383835393933333531353931323138383539373634313130333138307d0001060e60806040526040805190810160405280600181526020017f31000000000000000000000000000000000000000000000000000000000000008152506001908051906020019061004f9291906100ae565b5034801561005c57600080fd5b506040805190810160405280600d81526020017f48656c6c6f2c20576f726c642100000000000000000000000000000000000000815250600090805190602001906100a89291906100ae565b50610153565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106100ef57805160ff191683800117855561011d565b8280016001018555821561011d579182015b8281111561011c578251825591602001919060010190610101565b5b50905061012a919061012e565b5090565b61015091905b8082111561014c576000816000905550600101610134565b5090565b90565b6104ac806101626000396000f300608060405260043610610057576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680634ed3885e1461005c57806354fd4d50146100c55780636d4ce63c14610155575b600080fd5b34801561006857600080fd5b506100c3600480360381019080803590602001908201803590602001908080601f01602080910402602001604051908101604052809392919081815260200183838082843782019150505050505091929192905050506101e5565b005b3480156100d157600080fd5b506100da61029b565b6040518080602001828103825283818151815260200191508051906020019080838360005b8381101561011a5780820151818401526020810190506100ff565b50505050905090810190601f1680156101475780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561016157600080fd5b5061016a610339565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156101aa57808201518184015260208101905061018f565b50505050905090810190601f1680156101d75780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b80600090805190602001906101fb9291906103db565b507f93a093529f9c8a0c300db4c55fcd27c068c4f5e0e8410bc288c7e76f3d71083e816040518080602001828103825283818151815260200191508051906020019080838360005b8381101561025e578082015181840152602081019050610243565b50505050905090810190601f16801561028b5780820380516001836020036101000a031916815260200191505b509250505060405180910390a150565b60018054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156103315780601f1061030657610100808354040283529160200191610331565b820191906000526020600020905b81548152906001019060200180831161031457829003601f168201915b505050505081565b606060008054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156103d15780601f106103a6576101008083540402835291602001916103d1565b820191906000526020600020905b8154815290600101906020018083116103b457829003601f168201915b5050505050905090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061041c57805160ff191683800117855561044a565b8280016001018555821561044a579182015b8281111561044957825182559160200191906001019061042e565b5b509050610457919061045b565b5090565b61047d91905b80821115610479576000816000905550600101610461565b5090565b905600a165627a7a72305820fd433a091cb8e1aba3f49e5efb35f937e4b22a85a46f35574834d120699d7ae5002987000002755b7b22636f6e7374616e74223a66616c73652c22696e70757473223a5b7b226e616d65223a2276222c2274797065223a22737472696e67227d5d2c226e616d65223a22736574222c226f757470757473223a5b5d2c2270617961626c65223a66616c73652c2273746174654d75746162696c697479223a226e6f6e70617961626c65222c2274797065223a2266756e6374696f6e227d2c7b22636f6e7374616e74223a747275652c22696e70757473223a5b5d2c226e616d65223a2276657273696f6e222c226f757470757473223a5b7b226e616d65223a22222c2274797065223a22737472696e67227d5d2c2270617961626c65223a66616c73652c2273746174654d75746162696c697479223a2276696577222c2274797065223a2266756e6374696f6e227d2c7b22636f6e7374616e74223a747275652c22696e70757473223a5b5d2c226e616d65223a22676574222c226f757470757473223a5b7b226e616d65223a22222c2274797065223a22737472696e67227d5d2c2270617961626c65223a66616c73652c2273746174654d75746162696c697479223a2276696577222c2274797065223a2266756e6374696f6e227d2c7b22696e70757473223a5b5d2c2270617961626c65223a66616c73652c2273746174654d75746162696c697479223a226e6f6e70617961626c65222c2274797065223a22636f6e7374727563746f72227d2c7b22616e6f6e796d6f7573223a66616c73652c22696e70757473223a5b7b22696e6465786564223a66616c73652c226e616d65223a22222c2274797065223a22737472696e67227d5d2c226e616d65223a2273657456616c7565222c2274797065223a226576656e74227d5d` + DEPLOY_HELLOWORLD_TX = `1a1c2606636861696e30360667726f75703041020a5628313638383630333033393337383835393933333531353931323138383539373634313130333138307d0001060e60806040526040805190810160405280600181526020017f31000000000000000000000000000000000000000000000000000000000000008152506001908051906020019061004f9291906100ae565b5034801561005c57600080fd5b506040805190810160405280600d81526020017f48656c6c6f2c20576f726c642100000000000000000000000000000000000000815250600090805190602001906100a89291906100ae565b50610153565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106100ef57805160ff191683800117855561011d565b8280016001018555821561011d579182015b8281111561011c578251825591602001919060010190610101565b5b50905061012a919061012e565b5090565b61015091905b8082111561014c576000816000905550600101610134565b5090565b90565b6104ac806101626000396000f300608060405260043610610057576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680634ed3885e1461005c57806354fd4d50146100c55780636d4ce63c14610155575b600080fd5b34801561006857600080fd5b506100c3600480360381019080803590602001908201803590602001908080601f01602080910402602001604051908101604052809392919081815260200183838082843782019150505050505091929192905050506101e5565b005b3480156100d157600080fd5b506100da61029b565b6040518080602001828103825283818151815260200191508051906020019080838360005b8381101561011a5780820151818401526020810190506100ff565b50505050905090810190601f1680156101475780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561016157600080fd5b5061016a610339565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156101aa57808201518184015260208101905061018f565b50505050905090810190601f1680156101d75780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b80600090805190602001906101fb9291906103db565b507f93a093529f9c8a0c300db4c55fcd27c068c4f5e0e8410bc288c7e76f3d71083e816040518080602001828103825283818151815260200191508051906020019080838360005b8381101561025e578082015181840152602081019050610243565b50505050905090810190601f16801561028b5780820380516001836020036101000a031916815260200191505b509250505060405180910390a150565b60018054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156103315780601f1061030657610100808354040283529160200191610331565b820191906000526020600020905b81548152906001019060200180831161031457829003601f168201915b505050505081565b606060008054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156103d15780601f106103a6576101008083540402835291602001916103d1565b820191906000526020600020905b8154815290600101906020018083116103b457829003601f168201915b5050505050905090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061041c57805160ff191683800117855561044a565b8280016001018555821561044a579182015b8281111561044957825182559160200191906001019061042e565b5b509050610457919061045b565b5090565b61047d91905b80821115610479576000816000905550600101610461565b5090565b905600a165627a7a72305820fd433a091cb8e1aba3f49e5efb35f937e4b22a85a46f35574834d120699d7ae5002987000002755b7b22636f6e7374616e74223a66616c73652c22696e70757473223a5b7b226e616d65223a2276222c2274797065223a22737472696e67227d5d2c226e616d65223a22736574222c226f757470757473223a5b5d2c2270617961626c65223a66616c73652c2273746174654d75746162696c697479223a226e6f6e70617961626c65222c2274797065223a2266756e6374696f6e227d2c7b22636f6e7374616e74223a747275652c22696e70757473223a5b5d2c226e616d65223a2276657273696f6e222c226f757470757473223a5b7b226e616d65223a22222c2274797065223a22737472696e67227d5d2c2270617961626c65223a66616c73652c2273746174654d75746162696c697479223a2276696577222c2274797065223a2266756e6374696f6e227d2c7b22636f6e7374616e74223a747275652c22696e70757473223a5b5d2c226e616d65223a22676574222c226f757470757473223a5b7b226e616d65223a22222c2274797065223a22737472696e67227d5d2c2270617961626c65223a66616c73652c2273746174654d75746162696c697479223a2276696577222c2274797065223a2266756e6374696f6e227d2c7b22696e70757473223a5b5d2c2270617961626c65223a66616c73652c2273746174654d75746162696c697479223a226e6f6e70617961626c65222c2274797065223a22636f6e7374727563746f72227d2c7b22616e6f6e796d6f7573223a66616c73652c22696e70757473223a5b7b22696e6465786564223a66616c73652c226e616d65223a22222c2274797065223a22737472696e67227d5d2c226e616d65223a2273657456616c7565222c2274797065223a226576656e74227d5d0b2d0000207e9f0440919e2bd719e29cc512b8ed364a7ce81091d460ea31272106424e93e03d000041b8227e0be95ea1195f8fd605b3d5c288ac4481c366749c9ab12d8e5eef7e57885bd474a427fdba3e6fd3d28171b3fa2e47c373e77c45514d8985abf5715cb5be00` + HELLOWORLD_SET_TX_DATA = `1c2606636861696e30360667726f75703041020a56273136313235353631323839383636383633323732353836393034303732333238373635373533336628613663646334666564393662626638633963303133636331393230306233633862613935633933657d0000644ed3885e0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000c68656c6c6f2c20776f726c640000000000000000000000000000000000000000` + HELLOWORLD_SET_TX = `1a1c2606636861696e30360667726f75703041020a56273136313235353631323839383636383633323732353836393034303732333238373635373533336628613663646334666564393662626638633963303133636331393230306233633862613935633933657d0000644ed3885e0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000c68656c6c6f2c20776f726c6400000000000000000000000000000000000000000b2d000020b1e82e9052f066250532968bf9ad3a05f19dba10291089a27cea931ddfc8e9b53d000041aa923c250f2e8b64f401766b9348b27234858ee7cceefedda8c72cefc94d4142723d0b2584e753629a69404b8bfb33748747ec6b5a286488f9bebce79b2ef27101` + DEPLOY_HELLOWORLD_TX_DATA_GM = `1c2606636861696e30360667726f7570304101f456273136353333333933373031333131333936353533313836343438303132323233393434303735327d0001060e60806040526040805190810160405280600181526020017f31000000000000000000000000000000000000000000000000000000000000008152506001908051906020019061004f9291906100ae565b5034801561005c57600080fd5b506040805190810160405280600d81526020017f48656c6c6f2c20576f726c642100000000000000000000000000000000000000815250600090805190602001906100a89291906100ae565b50610153565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106100ef57805160ff191683800117855561011d565b8280016001018555821561011d579182015b8281111561011c578251825591602001919060010190610101565b5b50905061012a919061012e565b5090565b61015091905b8082111561014c576000816000905550600101610134565b5090565b90565b6104ac806101626000396000f300608060405260043610610057576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680634ed3885e1461005c57806354fd4d50146100c55780636d4ce63c14610155575b600080fd5b34801561006857600080fd5b506100c3600480360381019080803590602001908201803590602001908080601f01602080910402602001604051908101604052809392919081815260200183838082843782019150505050505091929192905050506101e5565b005b3480156100d157600080fd5b506100da61029b565b6040518080602001828103825283818151815260200191508051906020019080838360005b8381101561011a5780820151818401526020810190506100ff565b50505050905090810190601f1680156101475780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561016157600080fd5b5061016a610339565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156101aa57808201518184015260208101905061018f565b50505050905090810190601f1680156101d75780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b80600090805190602001906101fb9291906103db565b507f93a093529f9c8a0c300db4c55fcd27c068c4f5e0e8410bc288c7e76f3d71083e816040518080602001828103825283818151815260200191508051906020019080838360005b8381101561025e578082015181840152602081019050610243565b50505050905090810190601f16801561028b5780820380516001836020036101000a031916815260200191505b509250505060405180910390a150565b60018054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156103315780601f1061030657610100808354040283529160200191610331565b820191906000526020600020905b81548152906001019060200180831161031457829003601f168201915b505050505081565b606060008054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156103d15780601f106103a6576101008083540402835291602001916103d1565b820191906000526020600020905b8154815290600101906020018083116103b457829003601f168201915b5050505050905090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061041c57805160ff191683800117855561044a565b8280016001018555821561044a579182015b8281111561044957825182559160200191906001019061042e565b5b509050610457919061045b565b5090565b61047d91905b80821115610479576000816000905550600101610461565b5090565b905600a165627a7a72305820fd433a091cb8e1aba3f49e5efb35f937e4b22a85a46f35574834d120699d7ae5002987000002755b7b22636f6e7374616e74223a66616c73652c22696e70757473223a5b7b226e616d65223a2276222c2274797065223a22737472696e67227d5d2c226e616d65223a22736574222c226f757470757473223a5b5d2c2270617961626c65223a66616c73652c2273746174654d75746162696c697479223a226e6f6e70617961626c65222c2274797065223a2266756e6374696f6e227d2c7b22636f6e7374616e74223a747275652c22696e70757473223a5b5d2c226e616d65223a2276657273696f6e222c226f757470757473223a5b7b226e616d65223a22222c2274797065223a22737472696e67227d5d2c2270617961626c65223a66616c73652c2273746174654d75746162696c697479223a2276696577222c2274797065223a2266756e6374696f6e227d2c7b22636f6e7374616e74223a747275652c22696e70757473223a5b5d2c226e616d65223a22676574222c226f757470757473223a5b7b226e616d65223a22222c2274797065223a22737472696e67227d5d2c2270617961626c65223a66616c73652c2273746174654d75746162696c697479223a2276696577222c2274797065223a2266756e6374696f6e227d2c7b22696e70757473223a5b5d2c2270617961626c65223a66616c73652c2273746174654d75746162696c697479223a226e6f6e70617961626c65222c2274797065223a22636f6e7374727563746f72227d2c7b22616e6f6e796d6f7573223a66616c73652c22696e70757473223a5b7b22696e6465786564223a66616c73652c226e616d65223a22222c2274797065223a22737472696e67227d5d2c226e616d65223a2273657456616c7565222c2274797065223a226576656e74227d5d` + DEPLOY_HELLOWORLD_TX_GM = `1a1c2606636861696e30360667726f7570304101f456273136353333333933373031333131333936353533313836343438303132323233393434303735327d0001060e60806040526040805190810160405280600181526020017f31000000000000000000000000000000000000000000000000000000000000008152506001908051906020019061004f9291906100ae565b5034801561005c57600080fd5b506040805190810160405280600d81526020017f48656c6c6f2c20576f726c642100000000000000000000000000000000000000815250600090805190602001906100a89291906100ae565b50610153565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106100ef57805160ff191683800117855561011d565b8280016001018555821561011d579182015b8281111561011c578251825591602001919060010190610101565b5b50905061012a919061012e565b5090565b61015091905b8082111561014c576000816000905550600101610134565b5090565b90565b6104ac806101626000396000f300608060405260043610610057576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680634ed3885e1461005c57806354fd4d50146100c55780636d4ce63c14610155575b600080fd5b34801561006857600080fd5b506100c3600480360381019080803590602001908201803590602001908080601f01602080910402602001604051908101604052809392919081815260200183838082843782019150505050505091929192905050506101e5565b005b3480156100d157600080fd5b506100da61029b565b6040518080602001828103825283818151815260200191508051906020019080838360005b8381101561011a5780820151818401526020810190506100ff565b50505050905090810190601f1680156101475780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561016157600080fd5b5061016a610339565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156101aa57808201518184015260208101905061018f565b50505050905090810190601f1680156101d75780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b80600090805190602001906101fb9291906103db565b507f93a093529f9c8a0c300db4c55fcd27c068c4f5e0e8410bc288c7e76f3d71083e816040518080602001828103825283818151815260200191508051906020019080838360005b8381101561025e578082015181840152602081019050610243565b50505050905090810190601f16801561028b5780820380516001836020036101000a031916815260200191505b509250505060405180910390a150565b60018054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156103315780601f1061030657610100808354040283529160200191610331565b820191906000526020600020905b81548152906001019060200180831161031457829003601f168201915b505050505081565b606060008054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156103d15780601f106103a6576101008083540402835291602001916103d1565b820191906000526020600020905b8154815290600101906020018083116103b457829003601f168201915b5050505050905090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061041c57805160ff191683800117855561044a565b8280016001018555821561044a579182015b8281111561044957825182559160200191906001019061042e565b5b509050610457919061045b565b5090565b61047d91905b80821115610479576000816000905550600101610461565b5090565b905600a165627a7a72305820fd433a091cb8e1aba3f49e5efb35f937e4b22a85a46f35574834d120699d7ae5002987000002755b7b22636f6e7374616e74223a66616c73652c22696e70757473223a5b7b226e616d65223a2276222c2274797065223a22737472696e67227d5d2c226e616d65223a22736574222c226f757470757473223a5b5d2c2270617961626c65223a66616c73652c2273746174654d75746162696c697479223a226e6f6e70617961626c65222c2274797065223a2266756e6374696f6e227d2c7b22636f6e7374616e74223a747275652c22696e70757473223a5b5d2c226e616d65223a2276657273696f6e222c226f757470757473223a5b7b226e616d65223a22222c2274797065223a22737472696e67227d5d2c2270617961626c65223a66616c73652c2273746174654d75746162696c697479223a2276696577222c2274797065223a2266756e6374696f6e227d2c7b22636f6e7374616e74223a747275652c22696e70757473223a5b5d2c226e616d65223a22676574222c226f757470757473223a5b7b226e616d65223a22222c2274797065223a22737472696e67227d5d2c2270617961626c65223a66616c73652c2273746174654d75746162696c697479223a2276696577222c2274797065223a2266756e6374696f6e227d2c7b22696e70757473223a5b5d2c2270617961626c65223a66616c73652c2273746174654d75746162696c697479223a226e6f6e70617961626c65222c2274797065223a22636f6e7374727563746f72227d2c7b22616e6f6e796d6f7573223a66616c73652c22696e70757473223a5b7b22696e6465786564223a66616c73652c226e616d65223a22222c2274797065223a22737472696e67227d5d2c226e616d65223a2273657456616c7565222c2274797065223a226576656e74227d5d0b2d00002099f8ac271b22847c54a93e1cecf82c9b017430aafb0364c7d3fe76093ba051f83d000100805d7ea32ba1a14674da4ebeb87c88310b624b3ff53174c07d401cc125eacc58b70f66ee126e73d450958ecd483468c815e1f739094516a5d436a95af0a217d26e4c5a43dcbecdb28436cf138f5b74f8f4809415be473fa31e923e27a0e0eaebabe002537bbf5f787e87df7fa9acf7b13391ccf85618009ccb7413376641b19133` + HELLOWORLD_SET_TX_DATA_GM = `1c2606636861696e30360667726f7570304101f456273134323433393934373830323139353931303230323835343436343433333339333430333931356628633035323364626464393462613237653134623033333664373939343839333430636132346364667d0000644ed3885e0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000c68656c6c6f2c20776f726c640000000000000000000000000000000000000000` + HELLOWORLD_SET_TX_GM = `1a1c2606636861696e30360667726f7570304101f456273134323433393934373830323139353931303230323835343436343433333339333430333931356628633035323364626464393462613237653134623033333664373939343839333430636132346364667d0000644ed3885e0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000c68656c6c6f2c20776f726c6400000000000000000000000000000000000000000b2d000020db9d06a9258d4e8dbbe490a4f4c3f0bfa4fe8aa783ad77c2720c749410ee9bca3d0001008045e0d42a74157f03aaf9e7d2631df0c21e74ce72dbee2c3c047ac12e0435d24f8563b5b3b7b0a62bd0f95b297530a4e8d789bfb29762f5c47e789e6ffe366fa74c5a43dcbecdb28436cf138f5b74f8f4809415be473fa31e923e27a0e0eaebabe002537bbf5f787e87df7fa9acf7b13391ccf85618009ccb7413376641b19133` +) + +func checkTransaction(dataHex, txHex string, isSmCrypto bool, t *testing.T) { + deployTxData := common.FromHex(dataHex) + readBuf := codec.NewReader(deployTxData) + txData := TransactionData{} + txData.ReadFrom(readBuf) + + deployTx := common.FromHex(txHex) + txReadBuf := codec.NewReader(deployTx) + tx := &Transaction{SMCrypto: isSmCrypto} + tx.ReadFrom(txReadBuf) + if tx.Data.Version != txData.Version { + t.Errorf("tx.Data.Version should be %d, but got %d", tx.Data.Version, txData.Version) + } + if tx.Data.ChainID != txData.ChainID { + t.Errorf("tx.Data.ChainID should be %s, but got %s", tx.Data.ChainID, txData.ChainID) + } + if tx.Data.GroupID != txData.GroupID { + t.Errorf("tx.Data.GroupID should be %s, but got %s", tx.Data.GroupID, txData.GroupID) + } + if tx.Data.BlockLimit != txData.BlockLimit { + t.Errorf("tx.Data.BlockLimit should be %d, but got %d", tx.Data.BlockLimit, txData.BlockLimit) + } + if tx.Data.Nonce != txData.Nonce { + t.Errorf("tx.Data.Nonce should be %s, but got %s", tx.Data.Nonce, txData.Nonce) + } + if tx.Data.To != nil && txData.To != nil { + if *tx.Data.To != *txData.To { + t.Errorf("tx.Data.To should be %s, but got %s", tx.Data.To.String(), txData.To.String()) + } + } else if tx.Data.To == nil && txData.To == nil { + + } else { + t.Errorf("tx.Data.To should be %s, but got %s", tx.Data.To.String(), txData.To.String()) + } + if !bytes.Equal(tx.Data.Input, txData.Input) { + t.Errorf("tx.Data.Input should be %s, but got %s", common.Bytes2Hex(tx.Data.Input), common.Bytes2Hex(txData.Input)) + } + if tx.Data.Abi != txData.Abi { + t.Errorf("tx.Data.Abi should be %s, but got %s", tx.Data.Abi, txData.Abi) + } + if tx.Data.Value != nil { + t.Errorf("tx.Data.Value should be nil, but got %s", tx.Data.Value) + } + // if tx.Data.Value != txData.Value { + // t.Errorf("tx.Data.Value should be %s, but got %s", tx.Data.Value, txData.Value) + // } + // if tx.Data.GasPrice != txData.GasPrice { + // t.Errorf("tx.Data.GasPrice should be %s, but got %s", tx.Data.GasPrice, txData.GasPrice) + // } + if tx.Data.GasLimit != txData.GasLimit { + t.Errorf("tx.Data.Gas should be %v, but got %v", tx.Data.GasLimit, txData.GasLimit) + } + // if tx.Data.MaxFeePerGas != txData.MaxFeePerGas { + // t.Errorf("tx.Data.MaxFeePerGas should be %s, but got %s", tx.Data.MaxFeePerGas, txData.MaxFeePerGas) + // } + // if tx.Data.MaxPriorityFeePerGas != txData.MaxPriorityFeePerGas { + // t.Errorf("tx.Data.MaxPriorityFeePerGas should be %s, but got %s", tx.Data.MaxPriorityFeePerGas, txData.MaxPriorityFeePerGas) + // } + rightHash := tx.DataHash + newHash := tx.Hash() + if !bytes.Equal(rightHash.Bytes(), newHash.Bytes()) { + t.Errorf("tx.DataHash should be %s, but got %s", rightHash.String(), newHash.String()) + } + if !bytes.Equal(tx.Data.Bytes(), deployTxData) { + t.Errorf("tx.Data should be %#x, but got %#x", deployTxData, tx.Data.Bytes()) + } +} + +func TestUnmarshalTransactionDataDeploy(t *testing.T) { + checkTransaction(DEPLOY_HELLOWORLD_TX_DATA, DEPLOY_HELLOWORLD_TX, false, t) + checkTransaction(HELLOWORLD_SET_TX_DATA, HELLOWORLD_SET_TX, false, t) + checkTransaction(DEPLOY_HELLOWORLD_TX_DATA_GM, DEPLOY_HELLOWORLD_TX_GM, true, t) + checkTransaction(HELLOWORLD_SET_TX_DATA_GM, HELLOWORLD_SET_TX_GM, true, t) +}