Skip to content
26 changes: 18 additions & 8 deletions cmd/send-blob/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ const (
)

func main() {
rpcURL := pflag.String("rpc", "https://ethereum-sepolia-rpc.publicnode.com", "Execution-layer JSON-RPC endpoint (required)")
rpcURLs := pflag.StringSlice("rpc", []string{"https://ethereum-sepolia-rpc.publicnode.com"}, "Execution-layer JSON-RPC endpoint (required)")
privKey := pflag.String("privkey", "", "Hex-encoded Ethereum private key (required)")
toStr := pflag.String("to", "", "Optional destination address (defaults to sender)")
numBlobs := pflag.Int("n", 1, "Number of random blobs to include")
Expand All @@ -34,7 +34,7 @@ func main() {

pflag.Parse()

if *rpcURL == "" || *privKey == "" || *capi == "" {
if len(*rpcURLs) == 0 || *privKey == "" || *capi == "" {
pflag.Usage()
return
}
Expand All @@ -45,10 +45,14 @@ func main() {
log.Infow("starting sendblob")

// 1) Init Contracts
contracts, err := web3.New([]string{*rpcURL}, *capi, 1.0)
contracts, err := web3.New(*rpcURLs, *capi, 1.0)
if err != nil {
log.Fatalf("init web3: %v", err)
}
if err := contracts.LoadContracts(nil); err != nil {
log.Fatalf("failed to load contracts: %w", err)
}

if err := contracts.SetAccountPrivateKey(*privKey); err != nil {
log.Fatalf("set privkey: %v", err)
}
Expand Down Expand Up @@ -94,14 +98,20 @@ func main() {
ctx, cancel := context.WithTimeout(context.Background(), timeout)
defer cancel()

// Prepare the ABI for packing the data
processABI, err := contracts.ProcessRegistryABI()
processID := types.NewProcessID(from, types.ProcessIDVersion(uint32(contracts.ChainID), to), 1)

data, err := contracts.ProcessRegistryABI().Pack("submitStateTransition", processID, []byte{0x1}, []byte{0x1})
if err != nil {
log.Fatal("failed to get process registry ABI: %w", err)
log.Fatalf("failed to pack data: %w", err)
}

// Simulate tx to the contract to check if it will fail and get the root
// cause of the failure if it does
if err := contracts.SimulateProcessTransition(ctx, processID, []byte{0x1}, []byte{0x1}, sidecar); err != nil {
log.Debugw("failed to simulate state transition", "error", err, "processID", processID.String())
}

tx, err := contracts.NewEIP4844Transaction(ctx, to, processABI, "submitStateTransition",
[]any{[32]byte{0x1}, []byte{0x1}, []byte{0x1}}, sidecar)
tx, err := contracts.NewEIP4844Transaction(ctx, to, data, sidecar)
if err != nil {
log.Fatalf("failed to build blob tx: %v", err)
}
Expand Down
22 changes: 2 additions & 20 deletions sequencer/onchain.go
Original file line number Diff line number Diff line change
Expand Up @@ -171,16 +171,7 @@ func (s *Sequencer) pushTransitionToContract(

// Simulate tx to the contract to check if it will fail and get the root
// cause of the failure if it does
if err := s.contracts.SimulateContractCall(
s.ctx,
s.contracts.ContractsAddresses.ProcessRegistry,
s.contracts.ContractABIs.ProcessRegistry,
"submitStateTransition",
blobSidecar,
processID,
abiProof,
abiInputs,
); err != nil {
if err := s.contracts.SimulateProcessTransition(s.ctx, processID, abiProof, abiInputs, blobSidecar); err != nil {
log.Debugw("failed to simulate state transition",
"error", err,
"processID", processID.String())
Expand Down Expand Up @@ -281,16 +272,7 @@ func (s *Sequencer) processResultsOnChain() {
"strInputs", res.Inputs.String())
// Simulate tx to the contract to check if it will fail and get the root
// cause of the failure if it does
if err := s.contracts.SimulateContractCall(
s.ctx,
s.contracts.ContractsAddresses.ProcessRegistry,
s.contracts.ContractABIs.ProcessRegistry,
"setProcessResults",
nil, // No blob sidecar for regular contract calls
res.ProcessID,
abiProof,
abiInputs,
); err != nil {
if err := s.contracts.SimulateProcessResults(s.ctx, res.ProcessID, abiProof, abiInputs); err != nil {
log.Debugw("failed to simulate verified results upload",
"error", err,
"processID", res.ProcessID.String())
Expand Down
22 changes: 0 additions & 22 deletions tests/helpers_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -435,28 +435,6 @@ func setupWeb3(ctx context.Context) (*web3.Contracts, func(), error) {
cleanupFuncs = append(cleanupFuncs, func() {
txm.Stop()
})
// Set contracts ABIs
contracts.ContractABIs = &web3.ContractABIs{}
contracts.ContractABIs.ProcessRegistry, err = contracts.ProcessRegistryABI()
if err != nil {
cleanup() // Clean up what we've done so far
return nil, nil, fmt.Errorf("failed to get process registry ABI: %w", err)
}
contracts.ContractABIs.OrganizationRegistry, err = contracts.OrganizationRegistryABI()
if err != nil {
cleanup() // Clean up what we've done so far
return nil, nil, fmt.Errorf("failed to get organization registry ABI: %w", err)
}
contracts.ContractABIs.StateTransitionZKVerifier, err = contracts.StateTransitionVerifierABI()
if err != nil {
cleanup() // Clean up what we've done so far
return nil, nil, fmt.Errorf("failed to get state transition verifier ABI: %w", err)
}
contracts.ContractABIs.ResultsZKVerifier, err = contracts.ResultsVerifierABI()
if err != nil {
cleanup() // Clean up what we've done so far
return nil, nil, fmt.Errorf("failed to get results verifier ABI: %w", err)
}
// Return the contracts object and cleanup function
return contracts, cleanup, nil
}
Expand Down
29 changes: 7 additions & 22 deletions web3/blobs.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import (
"strings"

"github.com/ethereum/go-ethereum"
"github.com/ethereum/go-ethereum/accounts/abi"
"github.com/ethereum/go-ethereum/common"
gethtypes "github.com/ethereum/go-ethereum/core/types"
"github.com/holiman/uint256"
Expand Down Expand Up @@ -53,17 +52,15 @@ func applyGasMultiplier(baseFee *big.Int, multiplier float64) *big.Int {
func (c *Contracts) NewEIP4844Transaction(
ctx context.Context,
to common.Address,
contractABI *abi.ABI,
method string,
args []any,
data []byte,
blobsSidecar *types.BlobTxSidecar,
) (*gethtypes.Transaction, error) {
// Nonce
nonce, err := c.cli.PendingNonceAt(ctx, c.AccountAddress())
if err != nil {
return nil, err
}
return c.NewEIP4844TransactionWithNonce(ctx, to, contractABI, method, args, blobsSidecar, nonce)
return c.NewEIP4844TransactionWithNonce(ctx, to, data, nonce, blobsSidecar)
}

// NewEIP4844TransactionWithNonce method creates and signs a new EIP-4844. It
Expand All @@ -72,37 +69,22 @@ func (c *Contracts) NewEIP4844Transaction(
//
// Requirements:
// - `to` MUST be non-nil per EIP-4844.
// - `contractABI` MUST be non-nil.
// - `method` MUST be a valid method in the ABI.
// - `c.signer` MUST be non-nil (private key set).
func (c *Contracts) NewEIP4844TransactionWithNonce(
ctx context.Context,
to common.Address,
contractABI *abi.ABI,
method string,
args []any,
blobsSidecar *types.BlobTxSidecar,
data []byte,
nonce uint64,
blobsSidecar *types.BlobTxSidecar,
) (*gethtypes.Transaction, error) {
if contractABI == nil {
return nil, fmt.Errorf("nil contract ABI")
}
if (to == common.Address{}) {
return nil, fmt.Errorf("empty to address")
}
if method == "" {
return nil, fmt.Errorf("empty method")
}
if c.signer == nil {
return nil, fmt.Errorf("no signer defined")
}

// ABI-encode call data
data, err := contractABI.Pack(method, args...)
if err != nil {
return nil, fmt.Errorf("failed to encode ABI: %w", err)
}

// Estimate execution gas, include blob hashes so any contract logic that
// references them (e.g. checks) isn't under-estimated.
gas, err := c.txManager.EstimateGas(ctx, ethereum.CallMsg{
Expand All @@ -112,6 +94,9 @@ func (c *Contracts) NewEIP4844TransactionWithNonce(
BlobHashes: blobsSidecar.BlobHashes(),
}, txmanager.DefaultGasEstimateOpts, txmanager.DefaultCancelGasFallback)
if err != nil {
if reason, ok := c.DecodeError(err); ok {
return nil, fmt.Errorf("failed to estimate gas: %w (decoded: %s)", err, reason)
}
return nil, fmt.Errorf("failed to estimate gas: %w", err)
}

Expand Down
Loading