Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

eth-pos-devnet-validator-1:could not validate blob data availability: can't verify opening proof #55

Closed
qymlyl opened this issue May 28, 2024 · 3 comments

Comments

@qymlyl
Copy link

qymlyl commented May 28, 2024

description

send blob transaction without generating block

consensus/config.yml

image

docker-compose.yml

image

problem

send blob transaction without generating block

eth-pos-devnet-geth-1

image

eth-pos-devnet-beacon-chain-1

image

eth-pos-devnet-validator-1

image

@qymlyl
Copy link
Author

qymlyl commented May 28, 2024

testcode

package blob_tx

import (
	"fmt"
	"log"
	testing2 "testing"
)

const (
	localnetRpcUrl = "http://192.168.3.173:8645" // mainnet rpc url
	to             = "0x12630d738344a01AbD32EE8AcaF85985c9c59fD6"
	data           = "0x014567890123456bbb"
	privKey        = "2e0834786285daccd064ca17f1654f67b4aef298acbb82cef9ec422fb4975622"
	from           = "0xE25583099BA105D9ec0A67f5Ae86D90e50036425"
)

func TestSendBlobTX(t *testing2.T) {

	fmt.Println("using ethclient...")

	blob, err := SendBlobTX(localnetRpcUrl, to, data, privKey)

	if err != nil {
		log.Fatalln(err)
	}

	fmt.Println("\nBlob transaction hash:", blob) // This was just added.
}

send_tx

package blob_tx

import (
	"context"
	"fmt"
	"regexp"
	"strings"

	"github.com/ethereum/go-ethereum/common"
	"github.com/ethereum/go-ethereum/common/hexutil"
	"github.com/ethereum/go-ethereum/core/types"
	"github.com/ethereum/go-ethereum/crypto"
	"github.com/ethereum/go-ethereum/crypto/kzg4844"
	"github.com/ethereum/go-ethereum/ethclient"
	"github.com/holiman/uint256"
)

// SendBlobTX sends a transaction with an EIP-4844 blob payload to the Ethereum network.

func SendBlobTX(rpcURL, toAddress, data, privKey string) (string, error) {
	// Connect to the Ethereum client
	client, err := ethclient.Dial(rpcURL)
	if err != nil {
		return "", fmt.Errorf("failed to dial RPC client: %s", err)
	}
	defer client.Close() // Ensure the connection is closed after completing the function

	// Retrieve the current chain ID
	chainID, err := client.ChainID(context.Background())
	if err != nil {
		return "", fmt.Errorf("failed to get chain ID: %s", err)
	}

	var Blob [131072]byte // Define a blob array to hold the large data payload, blobs are 128kb in length

	// If necessary, convert the input data to a byte slice in hex format
	var bytesData []byte
	if data != "" {
		// Check if the data is in hex format, with or without the '0x' prefix
		if IsHexWithOrWithout0xPrefix(data) {
			// Ensure the data has the '0x' prefix
			if !strings.HasPrefix(data, "0x") {
				data = "0x" + data
			}
			// Decode the hex-encoded data
			bytesData, err = hexutil.Decode(data)
			if err != nil {
				return "", fmt.Errorf("failed to decode data: %s", err)
			}
			// Copy the decoded data into the blob array
			copy(Blob[:], bytesData)
		} else {
			// If the data is not in hex format, copy it directly into the blob array
			copy(Blob[:], data)
		}
	}

	// Compute the commitment for the blob data using KZG4844 cryptographic algorithm
	BlobCommitment, err := kzg4844.BlobToCommitment(Blob)
	if err != nil {
		return "", fmt.Errorf("failed to compute blob commitment: %s", err)
	}

	// Compute the proof for the blob data, which will be used to verify the transaction
	BlobProof, err := kzg4844.ComputeBlobProof(Blob, BlobCommitment)
	if err != nil {
		return "", fmt.Errorf("failed to compute blob proof: %s", err)
	}

	// Prepare the sidecar data for the transaction, which includes the blob and its cryptographic proof
	sidecar := types.BlobTxSidecar{
		Blobs:       []kzg4844.Blob{Blob},
		Commitments: []kzg4844.Commitment{BlobCommitment},
		Proofs:      []kzg4844.Proof{BlobProof},
	}

	// Decode the sender's private key
	pKeyBytes, err := hexutil.Decode("0x" + privKey)
	if err != nil {
		return "", fmt.Errorf("failed to decode private key: %s", err)
	}

	// Convert the private key into the ECDSA format
	ecdsaPrivateKey, err := crypto.ToECDSA(pKeyBytes)
	if err != nil {
		return "", fmt.Errorf("failed to convert private key to ECDSA: %s", err)
	}

	// Compute the sender's address from the public key
	fromAddress := crypto.PubkeyToAddress(ecdsaPrivateKey.PublicKey)

	// Retrieve the nonce for the transaction
	nonce, err := client.PendingNonceAt(context.Background(), fromAddress)

	if err != nil {
		return "", fmt.Errorf("failed to get nonce: %s", err)
	}

	// Create the transaction with the blob data and cryptographic proofs
	tx := types.NewTx(&types.BlobTx{
		ChainID:    uint256.MustFromBig(chainID),
		Nonce:      nonce,
		GasTipCap:  uint256.NewInt(1e10),           // max priority fee per gas
		GasFeeCap:  uint256.NewInt(50e10),          // max fee per gas
		Gas:        250000,                         // gas limit for the transaction
		To:         common.HexToAddress(toAddress), // recipient's address
		Value:      uint256.NewInt(0),              // value transferred in the transaction
		Data:       nil,                            // No additional data is sent in this transaction
		BlobFeeCap: uint256.NewInt(3e10),           // fee cap for the blob data
		BlobHashes: sidecar.BlobHashes(),           // blob hashes in the transaction
		Sidecar:    &sidecar,                       // sidecar data in the transaction
	})

	fmt.Println("Type: ", tx.Type())
	//fmt.Println("BlobTxSidecar: ", tx.BlobTxSidecar())

	// Sign the transaction with the sender's private key
	signedTx, err := types.SignTx(tx, types.LatestSignerForChainID(chainID), ecdsaPrivateKey)

	if err != nil {
		return "", fmt.Errorf("failed to sign transaction: %s", err)
	}

	// Send the signed transaction to the Ethereum network
	if err = client.SendTransaction(context.Background(), signedTx); err != nil {
		return "", fmt.Errorf("failed to send transaction: %s", err)
	}

	// Return the transaction hash
	txHash := signedTx.Hash().Hex()

	return txHash, nil
}

// IsHexWithOrWithout0xPrefix checks if a string is hex with or without `0x` prefix using regular expression.
func IsHexWithOrWithout0xPrefix(data string) bool {
	pattern := `^(0x)?[0-9a-fA-F]+$`
	matched, _ := regexp.MatchString(pattern, data)
	return matched
}

@nisdas
Copy link
Contributor

nisdas commented May 28, 2024

You need to initialize with the correct trusted setup

@qymlyl
Copy link
Author

qymlyl commented May 31, 2024

You need to initialize with the correct trusted setup
Maybe the image version is old. The latest image can send blob type transactions

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants