@@ -6,12 +6,14 @@ import (
66 "fmt"
77 "math/big"
88
9+ "github.com/holiman/uint256"
910 "github.com/onflow/flow-evm-gateway/models"
1011 errs "github.com/onflow/flow-evm-gateway/models/errors"
1112
1213 "github.com/onflow/go-ethereum/common"
1314 "github.com/onflow/go-ethereum/common/hexutil"
1415 "github.com/onflow/go-ethereum/core/types"
16+ "github.com/onflow/go-ethereum/crypto/kzg4844"
1517)
1618
1719// TransactionArgs represents the arguments to construct a new transaction
@@ -35,6 +37,18 @@ type TransactionArgs struct {
3537 // Introduced by AccessListTxType transaction.
3638 AccessList * types.AccessList `json:"accessList,omitempty"`
3739 ChainID * hexutil.Big `json:"chainId,omitempty"`
40+
41+ // For BlobTxType
42+ BlobFeeCap * hexutil.Big `json:"maxFeePerBlobGas"`
43+ BlobHashes []common.Hash `json:"blobVersionedHashes,omitempty"`
44+
45+ // For BlobTxType transactions with blob sidecar
46+ Blobs []kzg4844.Blob `json:"blobs"`
47+ Commitments []kzg4844.Commitment `json:"commitments"`
48+ Proofs []kzg4844.Proof `json:"proofs"`
49+
50+ // For SetCodeTxType
51+ AuthorizationList []types.SetCodeAuthorization `json:"authorizationList"`
3852}
3953
4054func (txArgs TransactionArgs ) Validate () error {
@@ -86,6 +100,141 @@ func (txArgs TransactionArgs) Validate() error {
86100 return nil
87101}
88102
103+ // ToTransaction converts the arguments to a transaction.
104+ func (txArgs TransactionArgs ) ToTransaction (
105+ defaultType int ,
106+ defaultGas uint64 ,
107+ ) * types.Transaction {
108+ nonce := uint64 (0 )
109+ if txArgs .Nonce != nil {
110+ nonce = uint64 (* txArgs .Nonce )
111+ }
112+
113+ if txArgs .Gas == nil {
114+ gas := hexutil .Uint64 (defaultGas )
115+ txArgs .Gas = & gas
116+ }
117+
118+ usedType := types .LegacyTxType
119+ switch {
120+ case txArgs .AuthorizationList != nil || defaultType == types .SetCodeTxType :
121+ usedType = types .SetCodeTxType
122+ case txArgs .BlobHashes != nil || defaultType == types .BlobTxType :
123+ usedType = types .BlobTxType
124+ case txArgs .MaxFeePerGas != nil || defaultType == types .DynamicFeeTxType :
125+ usedType = types .DynamicFeeTxType
126+ case txArgs .AccessList != nil || defaultType == types .AccessListTxType :
127+ usedType = types .AccessListTxType
128+ }
129+ // Make it possible to default to newer tx, but use legacy if gasprice is provided
130+ if txArgs .GasPrice != nil {
131+ usedType = types .LegacyTxType
132+ }
133+ var data types.TxData
134+ switch usedType {
135+ case types .SetCodeTxType :
136+ al := types.AccessList {}
137+ if txArgs .AccessList != nil {
138+ al = * txArgs .AccessList
139+ }
140+ authList := []types.SetCodeAuthorization {}
141+ if txArgs .AuthorizationList != nil {
142+ authList = txArgs .AuthorizationList
143+ }
144+ data = & types.SetCodeTx {
145+ To : * txArgs .To ,
146+ ChainID : uint256 .MustFromBig (txArgs .ChainID .ToInt ()),
147+ Nonce : nonce ,
148+ Gas : uint64 (* txArgs .Gas ),
149+ GasFeeCap : uint256 .MustFromBig ((* big .Int )(txArgs .MaxFeePerGas )),
150+ GasTipCap : uint256 .MustFromBig ((* big .Int )(txArgs .MaxPriorityFeePerGas )),
151+ Value : uint256 .MustFromBig ((* big .Int )(txArgs .Value )),
152+ Data : txArgs .data (),
153+ AccessList : al ,
154+ AuthList : authList ,
155+ }
156+
157+ case types .BlobTxType :
158+ al := types.AccessList {}
159+ if txArgs .AccessList != nil {
160+ al = * txArgs .AccessList
161+ }
162+ data = & types.BlobTx {
163+ To : * txArgs .To ,
164+ ChainID : uint256 .MustFromBig ((* big .Int )(txArgs .ChainID )),
165+ Nonce : nonce ,
166+ Gas : uint64 (* txArgs .Gas ),
167+ GasFeeCap : uint256 .MustFromBig ((* big .Int )(txArgs .MaxFeePerGas )),
168+ GasTipCap : uint256 .MustFromBig ((* big .Int )(txArgs .MaxPriorityFeePerGas )),
169+ Value : uint256 .MustFromBig ((* big .Int )(txArgs .Value )),
170+ Data : txArgs .data (),
171+ AccessList : al ,
172+ BlobHashes : txArgs .BlobHashes ,
173+ BlobFeeCap : uint256 .MustFromBig ((* big .Int )(txArgs .BlobFeeCap )),
174+ }
175+ if txArgs .Blobs != nil {
176+ data .(* types.BlobTx ).Sidecar = & types.BlobTxSidecar {
177+ Blobs : txArgs .Blobs ,
178+ Commitments : txArgs .Commitments ,
179+ Proofs : txArgs .Proofs ,
180+ }
181+ }
182+
183+ case types .DynamicFeeTxType :
184+ al := types.AccessList {}
185+ if txArgs .AccessList != nil {
186+ al = * txArgs .AccessList
187+ }
188+ data = & types.DynamicFeeTx {
189+ To : txArgs .To ,
190+ ChainID : (* big .Int )(txArgs .ChainID ),
191+ Nonce : nonce ,
192+ Gas : uint64 (* txArgs .Gas ),
193+ GasFeeCap : (* big .Int )(txArgs .MaxFeePerGas ),
194+ GasTipCap : (* big .Int )(txArgs .MaxPriorityFeePerGas ),
195+ Value : (* big .Int )(txArgs .Value ),
196+ Data : txArgs .data (),
197+ AccessList : al ,
198+ }
199+
200+ case types .AccessListTxType :
201+ data = & types.AccessListTx {
202+ To : txArgs .To ,
203+ ChainID : (* big .Int )(txArgs .ChainID ),
204+ Nonce : nonce ,
205+ Gas : uint64 (* txArgs .Gas ),
206+ GasPrice : (* big .Int )(txArgs .GasPrice ),
207+ Value : (* big .Int )(txArgs .Value ),
208+ Data : txArgs .data (),
209+ AccessList : * txArgs .AccessList ,
210+ }
211+
212+ default :
213+ data = & types.LegacyTx {
214+ To : txArgs .To ,
215+ Nonce : nonce ,
216+ Gas : uint64 (* txArgs .Gas ),
217+ GasPrice : (* big .Int )(txArgs .GasPrice ),
218+ Value : (* big .Int )(txArgs .Value ),
219+ Data : txArgs .data (),
220+ }
221+ }
222+
223+ return types .NewTx (data )
224+ }
225+
226+ // data retrieves the transaction calldata. Input field is preferred.
227+ func (txArgs * TransactionArgs ) data () []byte {
228+ if txArgs .Input != nil {
229+ return * txArgs .Input
230+ }
231+ if txArgs .Data != nil {
232+ return * txArgs .Data
233+ }
234+
235+ return nil
236+ }
237+
89238// AccessListResult returns an optional accesslist
90239// It's the result of the `debug_createAccessList` RPC call.
91240// It contains an error if the transaction itself failed.
0 commit comments